merged branch bschussek/issue5383 (PR #6528)
This PR was merged into the master branch. Discussion ---------- [2.3] [Form] Support buttons in forms Bug fix: no Feature addition: yes Backwards compatibility break: yes Symfony2 tests pass: yes Fixes the following tickets: #5383 Todo: - License of the code: MIT Documentation PR: symfony/symfony-docs#2489 The general idea of this PR is to be able to add buttons to forms like so: ```php $builder->add('clickme', 'submit'); ``` You can then check in the controller whether the button was clicked: ```php if ($form->get('clickme')->isClicked()) { // do stuff } ``` Button-specific validation groups are also supported: ```php $builder->add('clickme', 'submit', array( 'validation_groups' => 'OnlyClickMe', )); ``` The validation group will then override the one defined in the form if that button is clicked. This PR also introduces the disabling of form validation by passing the value `false` in the option `validation_groups`: ```php $builder->add('clickme', 'submit', array( 'validation_groups' => false, )); ``` The same can be achieved (already before this PR) by passing an empty array: ```php $builder->add('clickme', 'submit', array( 'validation_groups' => array(), )); ``` See the linked documentation for more information. Commits -------faf8d7a
[Form] Added upgrade information about setting "validation_groups" => falsed504732
[Form] Added leading backslashes to @exceptionMessage doc blocksc8afa88
[Form] Removed deprecated code scheduled for removal in 2.336ca056
[Form] Simplified Twig codece29c70
[Form] Fixed incorrect doc comment0bc7129
[Form] Fixed invalid use of FormException600007b
[Form] The option "validation_groups" can now be set to false to disable validation. This is identical to setting it to an empty array.277d6df
[Form] Fixed concatenation operator CS (see7c47e34928
)7b07925
[Form] Changed isset() to array_key_exists() to be consistent with ParameterBag7b438a8
[Form] Made submit buttons able to convey validation groupscc2118d
[Form] Implemented support for buttons
This commit is contained in:
commit
5a158ea08b
37
UPGRADE-2.3.md
Normal file
37
UPGRADE-2.3.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
UPGRADE FROM 2.2 to 2.3
|
||||||
|
=======================
|
||||||
|
|
||||||
|
### Form
|
||||||
|
|
||||||
|
* Although this was not officially supported nor documented, it was possible to
|
||||||
|
set the option "validation_groups" to false, resulting in the group "Default"
|
||||||
|
being validated. Now, if you set "validation_groups" to false, the validation
|
||||||
|
of a form will be skipped (except for a few integrity checks on the form).
|
||||||
|
|
||||||
|
If you want to validate a form in group "Default", you should either
|
||||||
|
explicitly set "validation_groups" to "Default" or alternatively set it to
|
||||||
|
null.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
```
|
||||||
|
// equivalent notations for validating in group "Default"
|
||||||
|
"validation_groups" => null
|
||||||
|
"validation_groups" => "Default"
|
||||||
|
"validation_groups" => false
|
||||||
|
|
||||||
|
// notation for skipping validation
|
||||||
|
"validation_groups" => array()
|
||||||
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
```
|
||||||
|
// equivalent notations for validating in group "Default"
|
||||||
|
"validation_groups" => null
|
||||||
|
"validation_groups" => "Default"
|
||||||
|
|
||||||
|
// equivalent notations for skipping validation
|
||||||
|
"validation_groups" => false
|
||||||
|
"validation_groups" => array()
|
||||||
|
```
|
@ -218,6 +218,29 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endblock email_widget %}
|
{% endblock email_widget %}
|
||||||
|
|
||||||
|
{% block button_widget %}
|
||||||
|
{% spaceless %}
|
||||||
|
{% if label is empty %}
|
||||||
|
{% set label = name|humanize %}
|
||||||
|
{% endif %}
|
||||||
|
<button type="{{ type|default('button') }}" {{ block('button_attributes') }}>{{ label|trans({}, translation_domain) }}</button>
|
||||||
|
{% endspaceless %}
|
||||||
|
{% endblock button_widget %}
|
||||||
|
|
||||||
|
{% block submit_widget %}
|
||||||
|
{% spaceless %}
|
||||||
|
{% set type = type|default('submit') %}
|
||||||
|
{{ block('button_widget') }}
|
||||||
|
{% endspaceless %}
|
||||||
|
{% endblock submit_widget %}
|
||||||
|
|
||||||
|
{% block reset_widget %}
|
||||||
|
{% spaceless %}
|
||||||
|
{% set type = type|default('reset') %}
|
||||||
|
{{ block('button_widget') }}
|
||||||
|
{% endspaceless %}
|
||||||
|
{% endblock reset_widget %}
|
||||||
|
|
||||||
{# Labels #}
|
{# Labels #}
|
||||||
|
|
||||||
{% block form_label %}
|
{% block form_label %}
|
||||||
@ -237,6 +260,8 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endblock form_label %}
|
{% endblock form_label %}
|
||||||
|
|
||||||
|
{% block button_label %}{% endblock %}
|
||||||
|
|
||||||
{# Rows #}
|
{# Rows #}
|
||||||
|
|
||||||
{% block repeated_row %}
|
{% block repeated_row %}
|
||||||
@ -259,6 +284,14 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endblock form_row %}
|
{% endblock form_row %}
|
||||||
|
|
||||||
|
{% block button_row %}
|
||||||
|
{% spaceless %}
|
||||||
|
<div>
|
||||||
|
{{ form_widget(form) }}
|
||||||
|
</div>
|
||||||
|
{% endspaceless %}
|
||||||
|
{% endblock button_row %}
|
||||||
|
|
||||||
{% block hidden_row %}
|
{% block hidden_row %}
|
||||||
{{ form_widget(form) }}
|
{{ form_widget(form) }}
|
||||||
{% endblock hidden_row %}
|
{% endblock hidden_row %}
|
||||||
@ -317,14 +350,9 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endblock widget_container_attributes %}
|
{% endblock widget_container_attributes %}
|
||||||
|
|
||||||
{# Deprecated in Symfony 2.1, to be removed in 2.3 #}
|
{% block button_attributes %}
|
||||||
|
{% spaceless %}
|
||||||
{% block generic_label %}{{ block('form_label') }}{% endblock %}
|
id="{{ id }}" name="{{ full_name }}"{% if disabled %} disabled="disabled"{% endif %}
|
||||||
{% block widget_choice_options %}{{ block('choice_widget_options') }}{% endblock %}
|
{% for attrname, attrvalue in attr %}{{ attrname }}="{{ attrvalue }}" {% endfor %}
|
||||||
{% block field_widget %}{{ block('form_widget_simple') }}{% endblock %}
|
{% endspaceless %}
|
||||||
{% block field_label %}{{ block('form_label') }}{% endblock %}
|
{% endblock button_attributes %}
|
||||||
{% block field_row %}{{ block('form_row') }}{% endblock %}
|
|
||||||
{% block field_enctype %}{{ block('form_enctype') }}{% endblock %}
|
|
||||||
{% block field_errors %}{{ block('form_errors') }}{% endblock %}
|
|
||||||
{% block field_rest %}{{ block('form_rest') }}{% endblock %}
|
|
||||||
{% block field_rows %}{{ block('form_rows') }}{% endblock %}
|
|
||||||
|
@ -14,6 +14,17 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endblock form_row %}
|
{% endblock form_row %}
|
||||||
|
|
||||||
|
{% block button_row %}
|
||||||
|
{% spaceless %}
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td colspan="2">
|
||||||
|
{{ form_widget(form) }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endspaceless %}
|
||||||
|
{% endblock button_row %}
|
||||||
|
|
||||||
{% block hidden_row %}
|
{% block hidden_row %}
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<tr style="display: none">
|
<tr style="display: none">
|
||||||
|
@ -140,6 +140,15 @@
|
|||||||
<service id="form.type.url" class="Symfony\Component\Form\Extension\Core\Type\UrlType">
|
<service id="form.type.url" class="Symfony\Component\Form\Extension\Core\Type\UrlType">
|
||||||
<tag name="form.type" alias="url" />
|
<tag name="form.type" alias="url" />
|
||||||
</service>
|
</service>
|
||||||
|
<service id="form.type.button" class="Symfony\Component\Form\Extension\Core\Type\ButtonType">
|
||||||
|
<tag name="form.type" alias="button" />
|
||||||
|
</service>
|
||||||
|
<service id="form.type.submit" class="Symfony\Component\Form\Extension\Core\Type\SubmitType">
|
||||||
|
<tag name="form.type" alias="submit" />
|
||||||
|
</service>
|
||||||
|
<service id="form.type.reset" class="Symfony\Component\Form\Extension\Core\Type\ResetType">
|
||||||
|
<tag name="form.type" alias="reset" />
|
||||||
|
</service>
|
||||||
|
|
||||||
<!-- FormTypeHttpFoundationExtension -->
|
<!-- FormTypeHttpFoundationExtension -->
|
||||||
<service id="form.type_extension.form.http_foundation" class="Symfony\Component\Form\Extension\HttpFoundation\Type\FormTypeHttpFoundationExtension">
|
<service id="form.type_extension.form.http_foundation" class="Symfony\Component\Form\Extension\HttpFoundation\Type\FormTypeHttpFoundationExtension">
|
||||||
@ -154,5 +163,8 @@
|
|||||||
<service id="form.type_extension.repeated.validator" class="Symfony\Component\Form\Extension\Validator\Type\RepeatedTypeValidatorExtension">
|
<service id="form.type_extension.repeated.validator" class="Symfony\Component\Form\Extension\Validator\Type\RepeatedTypeValidatorExtension">
|
||||||
<tag name="form.type_extension" alias="repeated" />
|
<tag name="form.type_extension" alias="repeated" />
|
||||||
</service>
|
</service>
|
||||||
|
<service id="form.type_extension.submit.validator" class="Symfony\Component\Form\Extension\Validator\Type\SubmitTypeValidatorExtension">
|
||||||
|
<tag name="form.type_extension" alias="submit" />
|
||||||
|
</service>
|
||||||
</services>
|
</services>
|
||||||
</container>
|
</container>
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
id="<?php echo $view->escape($id) ?>"
|
||||||
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
|
<?php if ($disabled): ?>disabled="disabled" <?php endif ?>
|
||||||
|
<?php foreach ($attr as $k => $v): ?>
|
||||||
|
<?php printf('%s="%s" ', $view->escape($k), $view->escape($v)) ?>
|
||||||
|
<?php endforeach; ?>
|
@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
<?php echo $view['form']->widget($form) ?>
|
||||||
|
</div>
|
@ -0,0 +1,4 @@
|
|||||||
|
<?php if (!$label) { $label = $view['form']->humanize($name); } ?>
|
||||||
|
<button type="<?php echo isset($type) ? $view->escape($type) : 'button' ?>" <?php echo $view['form']->block($form, 'button_attributes') ?>>
|
||||||
|
<?php $view->escape($view['translator']->trans($label, array(), $translation_domain)) ?>
|
||||||
|
</button>
|
@ -1 +0,0 @@
|
|||||||
<?php echo $view['form']->block($form, 'form_enctype') ?>
|
|
@ -1 +0,0 @@
|
|||||||
<?php echo $view['form']->block($form, 'form_errors') ?>
|
|
@ -1 +0,0 @@
|
|||||||
<?php echo $view['form']->block($form, 'form_label') ?>
|
|
@ -1 +0,0 @@
|
|||||||
<?php echo $view['form']->block($form, 'form_rest') ?>
|
|
@ -1 +0,0 @@
|
|||||||
<?php echo $view['form']->block($form, 'form_row') ?>
|
|
@ -1 +0,0 @@
|
|||||||
<?php echo $view['form']->block($form, 'form_rows') ?>
|
|
@ -1 +0,0 @@
|
|||||||
<?php echo $view['form']->block($form, 'form_widget_simple') ?>
|
|
@ -0,0 +1 @@
|
|||||||
|
<?php echo $view['form']->block($form, 'button_widget', array('type' => isset($type) ? $type : 'reset')) ?>
|
@ -0,0 +1 @@
|
|||||||
|
<?php echo $view['form']->block($form, 'button_widget', array('type' => isset($type) ? $type : 'submit')) ?>
|
@ -0,0 +1,6 @@
|
|||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<?php echo $view['form']->widget($form) ?>
|
||||||
|
</td>
|
||||||
|
</tr>
|
@ -25,7 +25,7 @@ class ArrayNodeTest extends \PHPUnit_Framework_TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
|
||||||
* @expectedExceptionMessage Unrecognized options "foo" under "root"
|
* @expectedExceptionMessage Unrecognized options "foo" under "root"
|
||||||
*/
|
*/
|
||||||
public function testExceptionThrownOnUnrecognizedChild()
|
public function testExceptionThrownOnUnrecognizedChild()
|
||||||
|
412
src/Symfony/Component/Form/Button.php
Normal file
412
src/Symfony/Component/Form/Button.php
Normal file
@ -0,0 +1,412 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\Exception\AlreadyBoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A form button.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class Button implements \IteratorAggregate, FormInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var FormInterface
|
||||||
|
*/
|
||||||
|
private $parent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FormConfigInterface
|
||||||
|
*/
|
||||||
|
private $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Boolean
|
||||||
|
*/
|
||||||
|
private $bound = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new button from a form configuration.
|
||||||
|
*
|
||||||
|
* @param FormConfigInterface $config The button's configuration.
|
||||||
|
*/
|
||||||
|
public function __construct(FormConfigInterface $config)
|
||||||
|
{
|
||||||
|
$this->config = $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function offsetExists($offset)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function offsetGet($offset)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
* @param mixed $value
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function offsetSet($offset, $value)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param mixed $offset
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function offsetUnset($offset)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setParent(FormInterface $parent = null)
|
||||||
|
{
|
||||||
|
$this->parent = $parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return $this->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param int|string|FormInterface $child
|
||||||
|
* @param null $type
|
||||||
|
* @param array $options
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function add($child, $type = null, array $options = array())
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function get($name)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function has($name)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function remove($name)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getErrors()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param string $modelData
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setData($modelData)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have data.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getNormData()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getViewData()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return array Always returns an empty array.
|
||||||
|
*/
|
||||||
|
public function getExtraData()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the button's configuration.
|
||||||
|
*
|
||||||
|
* @return FormConfigInterface The configuration.
|
||||||
|
*/
|
||||||
|
public function getConfig()
|
||||||
|
{
|
||||||
|
return $this->config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the button is submitted.
|
||||||
|
*
|
||||||
|
* @return Boolean true if the button was submitted.
|
||||||
|
*/
|
||||||
|
public function isBound()
|
||||||
|
{
|
||||||
|
return $this->bound;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name by which the button is identified in forms.
|
||||||
|
*
|
||||||
|
* @return string The name of the button.
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->config->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getPropertyPath()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @param FormError $error
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function addError(FormError $error)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have errors.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns true.
|
||||||
|
*/
|
||||||
|
public function isValid()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function isRequired()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isDisabled()
|
||||||
|
{
|
||||||
|
return $this->config->getDisabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns true.
|
||||||
|
*/
|
||||||
|
public function isEmpty()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns true.
|
||||||
|
*/
|
||||||
|
public function isSynchronized()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds data to the button.
|
||||||
|
*
|
||||||
|
* @param null|string $submittedData The data
|
||||||
|
*
|
||||||
|
* @return Button The button instance
|
||||||
|
*
|
||||||
|
* @throws Exception\AlreadyBoundException If the form has already been bound.
|
||||||
|
*/
|
||||||
|
public function bind($submittedData)
|
||||||
|
{
|
||||||
|
if ($this->bound) {
|
||||||
|
throw new AlreadyBoundException('A form can only be bound once');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->bound = true;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getRoot()
|
||||||
|
{
|
||||||
|
return $this->parent ? $this->parent->getRoot() : $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isRoot()
|
||||||
|
{
|
||||||
|
return null === $this->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function createView(FormView $parent = null)
|
||||||
|
{
|
||||||
|
if (null === $parent && $this->parent) {
|
||||||
|
$parent = $this->parent->createView();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->config->getType()->createView($this, $parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return integer Always returns 0.
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return \EmptyIterator Always returns an empty iterator.
|
||||||
|
*/
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return new \EmptyIterator();
|
||||||
|
}
|
||||||
|
}
|
750
src/Symfony/Component/Form/ButtonBuilder.php
Normal file
750
src/Symfony/Component/Form/ButtonBuilder.php
Normal file
@ -0,0 +1,750 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form;
|
||||||
|
|
||||||
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
|
use Symfony\Component\Form\Exception\FormException;
|
||||||
|
use Symfony\Component\Form\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder for {@link Button} instances.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class ButtonBuilder implements \IteratorAggregate, FormBuilderInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Boolean
|
||||||
|
*/
|
||||||
|
protected $locked = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Boolean
|
||||||
|
*/
|
||||||
|
private $disabled;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ResolvedFormTypeInterface
|
||||||
|
*/
|
||||||
|
private $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $attributes = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new button builder.
|
||||||
|
*
|
||||||
|
* @param string $name The name of the button.
|
||||||
|
* @param array $options The button's options.
|
||||||
|
*
|
||||||
|
* @throws FormException If the name is empty.
|
||||||
|
*/
|
||||||
|
public function __construct($name, array $options)
|
||||||
|
{
|
||||||
|
if (empty($name) && 0 != $name) {
|
||||||
|
throw new InvalidArgumentException('Buttons cannot have empty names.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->name = (string) $name;
|
||||||
|
$this->options = $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param string|integer|FormBuilderInterface $child
|
||||||
|
* @param string|FormTypeInterface $type
|
||||||
|
* @param array $options
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function add($child, $type = null, array $options = array())
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
* @param string|FormTypeInterface $type
|
||||||
|
* @param array $options
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function create($name, $type = null, array $options = array())
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function get($name)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function remove($name)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot have children.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function has($name)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the children.
|
||||||
|
*
|
||||||
|
* @return array Always returns an empty array.
|
||||||
|
*/
|
||||||
|
public function all()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the button.
|
||||||
|
*
|
||||||
|
* @return Button The button
|
||||||
|
*/
|
||||||
|
public function getForm()
|
||||||
|
{
|
||||||
|
return new Button($this->getFormConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param string $eventName
|
||||||
|
* @param callable $listener
|
||||||
|
* @param integer $priority
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function addEventListener($eventName, $listener, $priority = 0)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support event listeners.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param EventSubscriberInterface $subscriber
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function addEventSubscriber(EventSubscriberInterface $subscriber)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support event subscribers.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param DataTransformerInterface $viewTransformer
|
||||||
|
* @param Boolean $forcePrepend
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function addViewTransformer(DataTransformerInterface $viewTransformer, $forcePrepend = false)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support data transformers.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function resetViewTransformers()
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support data transformers.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param DataTransformerInterface $modelTransformer
|
||||||
|
* @param Boolean $forceAppend
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function addModelTransformer(DataTransformerInterface $modelTransformer, $forceAppend = false)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support data transformers.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function resetModelTransformers()
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support data transformers.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setAttribute($name, $value)
|
||||||
|
{
|
||||||
|
$this->attributes[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setAttributes(array $attributes)
|
||||||
|
{
|
||||||
|
$this->attributes = $attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param DataMapperInterface $dataMapper
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setDataMapper(DataMapperInterface $dataMapper = null)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support data mappers.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether the button is disabled.
|
||||||
|
*
|
||||||
|
* @param Boolean $disabled Whether the button is disabled
|
||||||
|
*
|
||||||
|
* @return ButtonBuilder The button builder.
|
||||||
|
*/
|
||||||
|
public function setDisabled($disabled)
|
||||||
|
{
|
||||||
|
$this->disabled = $disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param mixed $emptyData
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setEmptyData($emptyData)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support empty data.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param Boolean $errorBubbling
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setErrorBubbling($errorBubbling)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support error bubbling.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param Boolean $required
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setRequired($required)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot be required.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param null $propertyPath
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setPropertyPath($propertyPath)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support property paths.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param Boolean $mapped
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setMapped($mapped)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support data mapping.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param Boolean $byReference
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setByReference($byReference)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support data mapping.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param Boolean $virtual
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setVirtual($virtual)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot be virtual.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param Boolean $compound
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setCompound($compound)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons cannot be compound.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of the button.
|
||||||
|
*
|
||||||
|
* @param ResolvedFormTypeInterface $type The type of the button.
|
||||||
|
*
|
||||||
|
* @return ButtonBuilder The button builder.
|
||||||
|
*/
|
||||||
|
public function setType(ResolvedFormTypeInterface $type)
|
||||||
|
{
|
||||||
|
$this->type = $type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setData($data)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support data.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param Boolean $locked
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setDataLocked($locked)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support data locking.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* This method should not be invoked.
|
||||||
|
*
|
||||||
|
* @param FormFactoryInterface $formFactory
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @throws \BadMethodCallException
|
||||||
|
*/
|
||||||
|
public function setFormFactory(FormFactoryInterface $formFactory)
|
||||||
|
{
|
||||||
|
throw new \BadMethodCallException('Buttons do not support form factories.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds and returns the button configuration.
|
||||||
|
*
|
||||||
|
* @return FormConfigInterface
|
||||||
|
*/
|
||||||
|
public function getFormConfig()
|
||||||
|
{
|
||||||
|
// This method should be idempotent, so clone the builder
|
||||||
|
$config = clone $this;
|
||||||
|
$config->locked = true;
|
||||||
|
|
||||||
|
return $config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getEventDispatcher()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getPropertyPath()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function getMapped()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function getByReference()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function getVirtual()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function getCompound()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the form type used to construct the button.
|
||||||
|
*
|
||||||
|
* @return ResolvedFormTypeInterface The button's type.
|
||||||
|
*/
|
||||||
|
public function getType()
|
||||||
|
{
|
||||||
|
return $this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return array Always returns an empty array.
|
||||||
|
*/
|
||||||
|
public function getViewTransformers()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return array Always returns an empty array.
|
||||||
|
*/
|
||||||
|
public function getModelTransformers()
|
||||||
|
{
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getDataMapper()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function getRequired()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the button is disabled.
|
||||||
|
*
|
||||||
|
* @return Boolean Whether the button is disabled.
|
||||||
|
*/
|
||||||
|
public function getDisabled()
|
||||||
|
{
|
||||||
|
return $this->disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function getErrorBubbling()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getEmptyData()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns additional attributes of the button.
|
||||||
|
*
|
||||||
|
* @return array An array of key-value combinations.
|
||||||
|
*/
|
||||||
|
public function getAttributes()
|
||||||
|
{
|
||||||
|
return $this->attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the attribute with the given name exists.
|
||||||
|
*
|
||||||
|
* @param string $name The attribute name.
|
||||||
|
*
|
||||||
|
* @return Boolean Whether the attribute exists.
|
||||||
|
*/
|
||||||
|
public function hasAttribute($name)
|
||||||
|
{
|
||||||
|
return array_key_exists($name, $this->attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of the given attribute.
|
||||||
|
*
|
||||||
|
* @param string $name The attribute name.
|
||||||
|
* @param mixed $default The value returned if the attribute does not exist.
|
||||||
|
*
|
||||||
|
* @return mixed The attribute value.
|
||||||
|
*/
|
||||||
|
public function getAttribute($name, $default = null)
|
||||||
|
{
|
||||||
|
return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getData()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getDataClass()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return Boolean Always returns false.
|
||||||
|
*/
|
||||||
|
public function getDataLocked()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return null Always returns null.
|
||||||
|
*/
|
||||||
|
public function getFormFactory()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all options passed during the construction of the button.
|
||||||
|
*
|
||||||
|
* @return array The passed options.
|
||||||
|
*/
|
||||||
|
public function getOptions()
|
||||||
|
{
|
||||||
|
return $this->options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether a specific option exists.
|
||||||
|
*
|
||||||
|
* @param string $name The option name,
|
||||||
|
*
|
||||||
|
* @return Boolean Whether the option exists.
|
||||||
|
*/
|
||||||
|
public function hasOption($name)
|
||||||
|
{
|
||||||
|
return array_key_exists($name, $this->options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of a specific option.
|
||||||
|
*
|
||||||
|
* @param string $name The option name.
|
||||||
|
* @param mixed $default The value returned if the option does not exist.
|
||||||
|
*
|
||||||
|
* @return mixed The option value.
|
||||||
|
*/
|
||||||
|
public function getOption($name, $default = null)
|
||||||
|
{
|
||||||
|
return array_key_exists($name, $this->options) ? $this->options[$name] : $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return integer Always returns 0.
|
||||||
|
*/
|
||||||
|
public function count()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsupported method.
|
||||||
|
*
|
||||||
|
* @return \EmptyIterator Always returns an empty iterator.
|
||||||
|
*/
|
||||||
|
public function getIterator()
|
||||||
|
{
|
||||||
|
return new \EmptyIterator();
|
||||||
|
}
|
||||||
|
}
|
21
src/Symfony/Component/Form/ButtonTypeInterface.php
Normal file
21
src/Symfony/Component/Form/ButtonTypeInterface.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type that should be converted into a {@link Button} instance.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
interface ButtonTypeInterface extends FormTypeInterface
|
||||||
|
{
|
||||||
|
}
|
@ -28,6 +28,8 @@ CHANGELOG
|
|||||||
* added an optional PropertyAccessorInterface parameter to FormType,
|
* added an optional PropertyAccessorInterface parameter to FormType,
|
||||||
ObjectChoiceList and PropertyPathMapper
|
ObjectChoiceList and PropertyPathMapper
|
||||||
* [BC BREAK] PropertyPathMapper and FormType now have a constructor
|
* [BC BREAK] PropertyPathMapper and FormType now have a constructor
|
||||||
|
* [BC BREAK] setting the option "validation_groups" to ``false`` now disables validation
|
||||||
|
instead of assuming group "Default"
|
||||||
|
|
||||||
2.1.0
|
2.1.0
|
||||||
-----
|
-----
|
||||||
|
27
src/Symfony/Component/Form/ClickableInterface.php
Normal file
27
src/Symfony/Component/Form/ClickableInterface.php
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A clickable form element.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
interface ClickableInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns whether this element was clicked.
|
||||||
|
*
|
||||||
|
* @return Boolean Whether this element was clicked.
|
||||||
|
*/
|
||||||
|
public function isClicked();
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base InvalidArgumentException for the Form component.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||||
|
{
|
||||||
|
}
|
@ -50,6 +50,9 @@ class CoreExtension extends AbstractExtension
|
|||||||
new Type\TimezoneType(),
|
new Type\TimezoneType(),
|
||||||
new Type\UrlType(),
|
new Type\UrlType(),
|
||||||
new Type\FileType(),
|
new Type\FileType(),
|
||||||
|
new Type\ButtonType(),
|
||||||
|
new Type\SubmitType(),
|
||||||
|
new Type\ResetType(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
121
src/Symfony/Component/Form/Extension/Core/Type/BaseType.php
Normal file
121
src/Symfony/Component/Form/Extension/Core/Type/BaseType.php
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Core\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates common logic of {@link FormType} and {@link ButtonType}.
|
||||||
|
*
|
||||||
|
* This type does not appear in the form's type inheritance chain and as such
|
||||||
|
* cannot be extended (via {@link FormTypeExtension}s) nor themed.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
abstract class BaseType extends AbstractType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder->setDisabled($options['disabled']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
|
{
|
||||||
|
$name = $form->getName();
|
||||||
|
$blockName = $options['block_name'] ?: $form->getName();
|
||||||
|
$translationDomain = $options['translation_domain'];
|
||||||
|
|
||||||
|
if ($view->parent) {
|
||||||
|
if ('' !== ($parentFullName = $view->parent->vars['full_name'])) {
|
||||||
|
$id = sprintf('%s_%s', $view->parent->vars['id'], $name);
|
||||||
|
$fullName = sprintf('%s[%s]', $parentFullName, $name);
|
||||||
|
$uniqueBlockPrefix = sprintf('%s_%s', $view->parent->vars['unique_block_prefix'], $blockName);
|
||||||
|
} else {
|
||||||
|
$id = $name;
|
||||||
|
$fullName = $name;
|
||||||
|
$uniqueBlockPrefix = '_'.$blockName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$translationDomain) {
|
||||||
|
$translationDomain = $view->parent->vars['translation_domain'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$id = $name;
|
||||||
|
$fullName = $name;
|
||||||
|
$uniqueBlockPrefix = '_'.$blockName;
|
||||||
|
|
||||||
|
// Strip leading underscores and digits. These are allowed in
|
||||||
|
// form names, but not in HTML4 ID attributes.
|
||||||
|
// http://www.w3.org/TR/html401/struct/global.html#adef-id
|
||||||
|
$id = ltrim($id, '_0123456789');
|
||||||
|
}
|
||||||
|
|
||||||
|
$blockPrefixes = array();
|
||||||
|
for ($type = $form->getConfig()->getType(); null !== $type; $type = $type->getParent()) {
|
||||||
|
array_unshift($blockPrefixes, $type->getName());
|
||||||
|
}
|
||||||
|
$blockPrefixes[] = $uniqueBlockPrefix;
|
||||||
|
|
||||||
|
if (!$translationDomain) {
|
||||||
|
$translationDomain = 'messages';
|
||||||
|
}
|
||||||
|
|
||||||
|
$view->vars = array_replace($view->vars, array(
|
||||||
|
'form' => $view,
|
||||||
|
'id' => $id,
|
||||||
|
'name' => $name,
|
||||||
|
'full_name' => $fullName,
|
||||||
|
'disabled' => $form->isDisabled(),
|
||||||
|
'label' => $options['label'],
|
||||||
|
'multipart' => false,
|
||||||
|
'attr' => $options['attr'],
|
||||||
|
'block_prefixes' => $blockPrefixes,
|
||||||
|
'unique_block_prefix' => $uniqueBlockPrefix,
|
||||||
|
'translation_domain' => $translationDomain,
|
||||||
|
// Using the block name here speeds up performance in collection
|
||||||
|
// forms, where each entry has the same full block name.
|
||||||
|
// Including the type is important too, because if rows of a
|
||||||
|
// collection form have different types (dynamically), they should
|
||||||
|
// be rendered differently.
|
||||||
|
// https://github.com/symfony/symfony/issues/5038
|
||||||
|
'cache_key' => $uniqueBlockPrefix.'_'.$form->getConfig()->getType()->getName(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults(array(
|
||||||
|
'block_name' => null,
|
||||||
|
'disabled' => false,
|
||||||
|
'label' => null,
|
||||||
|
'attr' => array(),
|
||||||
|
'translation_domain' => null,
|
||||||
|
));
|
||||||
|
|
||||||
|
$resolver->setAllowedTypes(array(
|
||||||
|
'attr' => 'array',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Core\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\ButtonTypeInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A form button.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class ButtonType extends BaseType implements ButtonTypeInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'button';
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Form\Extension\Core\Type;
|
namespace Symfony\Component\Form\Extension\Core\Type;
|
||||||
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\Form\FormView;
|
use Symfony\Component\Form\FormView;
|
||||||
@ -23,7 +22,7 @@ use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
|||||||
use Symfony\Component\PropertyAccess\PropertyAccess;
|
use Symfony\Component\PropertyAccess\PropertyAccess;
|
||||||
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
|
||||||
|
|
||||||
class FormType extends AbstractType
|
class FormType extends BaseType
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var PropertyAccessorInterface
|
* @var PropertyAccessorInterface
|
||||||
@ -40,9 +39,10 @@ class FormType extends AbstractType
|
|||||||
*/
|
*/
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
{
|
{
|
||||||
|
parent::buildForm($builder, $options);
|
||||||
|
|
||||||
$builder
|
$builder
|
||||||
->setRequired($options['required'])
|
->setRequired($options['required'])
|
||||||
->setDisabled($options['disabled'])
|
|
||||||
->setErrorBubbling($options['error_bubbling'])
|
->setErrorBubbling($options['error_bubbling'])
|
||||||
->setEmptyData($options['empty_data'])
|
->setEmptyData($options['empty_data'])
|
||||||
->setPropertyPath($options['property_path'])
|
->setPropertyPath($options['property_path'])
|
||||||
@ -65,85 +65,34 @@ class FormType extends AbstractType
|
|||||||
*/
|
*/
|
||||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
{
|
{
|
||||||
|
parent::buildView($view, $form, $options);
|
||||||
|
|
||||||
$name = $form->getName();
|
$name = $form->getName();
|
||||||
$blockName = $options['block_name'] ?: $form->getName();
|
|
||||||
$readOnly = $options['read_only'];
|
$readOnly = $options['read_only'];
|
||||||
$translationDomain = $options['translation_domain'];
|
|
||||||
|
|
||||||
if ($view->parent) {
|
if ($view->parent) {
|
||||||
if ('' === $name) {
|
if ('' === $name) {
|
||||||
throw new Exception('Form node with empty name can be used only as root form node.');
|
throw new Exception('Form node with empty name can be used only as root form node.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('' !== ($parentFullName = $view->parent->vars['full_name'])) {
|
|
||||||
$id = sprintf('%s_%s', $view->parent->vars['id'], $name);
|
|
||||||
$fullName = sprintf('%s[%s]', $parentFullName, $name);
|
|
||||||
$uniqueBlockPrefix = sprintf('%s_%s', $view->parent->vars['unique_block_prefix'], $blockName);
|
|
||||||
} else {
|
|
||||||
$id = $name;
|
|
||||||
$fullName = $name;
|
|
||||||
$uniqueBlockPrefix = '_'.$blockName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complex fields are read-only if they themselves or their parents are.
|
// Complex fields are read-only if they themselves or their parents are.
|
||||||
if (!$readOnly) {
|
if (!$readOnly) {
|
||||||
$readOnly = $view->parent->vars['read_only'];
|
$readOnly = $view->parent->vars['read_only'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$translationDomain) {
|
|
||||||
$translationDomain = $view->parent->vars['translation_domain'];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$id = $name;
|
|
||||||
$fullName = $name;
|
|
||||||
$uniqueBlockPrefix = '_'.$blockName;
|
|
||||||
|
|
||||||
// Strip leading underscores and digits. These are allowed in
|
|
||||||
// form names, but not in HTML4 ID attributes.
|
|
||||||
// http://www.w3.org/TR/html401/struct/global.html#adef-id
|
|
||||||
$id = ltrim($id, '_0123456789');
|
|
||||||
}
|
|
||||||
|
|
||||||
$blockPrefixes = array();
|
|
||||||
for ($type = $form->getConfig()->getType(); null !== $type; $type = $type->getParent()) {
|
|
||||||
array_unshift($blockPrefixes, $type->getName());
|
|
||||||
}
|
|
||||||
$blockPrefixes[] = $uniqueBlockPrefix;
|
|
||||||
|
|
||||||
if (!$translationDomain) {
|
|
||||||
$translationDomain = 'messages';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$view->vars = array_replace($view->vars, array(
|
$view->vars = array_replace($view->vars, array(
|
||||||
'form' => $view,
|
'read_only' => $readOnly,
|
||||||
'id' => $id,
|
'errors' => $form->getErrors(),
|
||||||
'name' => $name,
|
'valid' => $form->isBound() ? $form->isValid() : true,
|
||||||
'full_name' => $fullName,
|
'value' => $form->getViewData(),
|
||||||
'read_only' => $readOnly,
|
'data' => $form->getNormData(),
|
||||||
'errors' => $form->getErrors(),
|
'required' => $form->isRequired(),
|
||||||
'valid' => $form->isBound() ? $form->isValid() : true,
|
'max_length' => $options['max_length'],
|
||||||
'value' => $form->getViewData(),
|
'pattern' => $options['pattern'],
|
||||||
'data' => $form->getNormData(),
|
'size' => null,
|
||||||
'disabled' => $form->isDisabled(),
|
'label_attr' => $options['label_attr'],
|
||||||
'required' => $form->isRequired(),
|
'compound' => $form->getConfig()->getCompound(),
|
||||||
'max_length' => $options['max_length'],
|
|
||||||
'pattern' => $options['pattern'],
|
|
||||||
'size' => null,
|
|
||||||
'label' => $options['label'],
|
|
||||||
'multipart' => false,
|
|
||||||
'attr' => $options['attr'],
|
|
||||||
'label_attr' => $options['label_attr'],
|
|
||||||
'compound' => $form->getConfig()->getCompound(),
|
|
||||||
'block_prefixes' => $blockPrefixes,
|
|
||||||
'unique_block_prefix' => $uniqueBlockPrefix,
|
|
||||||
'translation_domain' => $translationDomain,
|
|
||||||
// Using the block name here speeds up performance in collection
|
|
||||||
// forms, where each entry has the same full block name.
|
|
||||||
// Including the type is important too, because if rows of a
|
|
||||||
// collection form have different types (dynamically), they should
|
|
||||||
// be rendered differently.
|
|
||||||
// https://github.com/symfony/symfony/issues/5038
|
|
||||||
'cache_key' => $uniqueBlockPrefix.'_'.$form->getConfig()->getType()->getName(),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,6 +118,8 @@ class FormType extends AbstractType
|
|||||||
*/
|
*/
|
||||||
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||||
{
|
{
|
||||||
|
parent::setDefaultOptions($resolver);
|
||||||
|
|
||||||
// Derive "data_class" option from passed "data" object
|
// Derive "data_class" option from passed "data" object
|
||||||
$dataClass = function (Options $options) {
|
$dataClass = function (Options $options) {
|
||||||
return isset($options['data']) && is_object($options['data']) ? get_class($options['data']) : null;
|
return isset($options['data']) && is_object($options['data']) ? get_class($options['data']) : null;
|
||||||
@ -202,29 +153,23 @@ class FormType extends AbstractType
|
|||||||
));
|
));
|
||||||
|
|
||||||
$resolver->setDefaults(array(
|
$resolver->setDefaults(array(
|
||||||
'block_name' => null,
|
|
||||||
'data_class' => $dataClass,
|
'data_class' => $dataClass,
|
||||||
'empty_data' => $emptyData,
|
'empty_data' => $emptyData,
|
||||||
'trim' => true,
|
'trim' => true,
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'read_only' => false,
|
'read_only' => false,
|
||||||
'disabled' => false,
|
|
||||||
'max_length' => null,
|
'max_length' => null,
|
||||||
'pattern' => null,
|
'pattern' => null,
|
||||||
'property_path' => null,
|
'property_path' => null,
|
||||||
'mapped' => true,
|
'mapped' => true,
|
||||||
'by_reference' => true,
|
'by_reference' => true,
|
||||||
'error_bubbling' => $errorBubbling,
|
'error_bubbling' => $errorBubbling,
|
||||||
'label' => null,
|
|
||||||
'attr' => array(),
|
|
||||||
'label_attr' => array(),
|
'label_attr' => array(),
|
||||||
'virtual' => false,
|
'virtual' => false,
|
||||||
'compound' => true,
|
'compound' => true,
|
||||||
'translation_domain' => null,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
$resolver->setAllowedTypes(array(
|
$resolver->setAllowedTypes(array(
|
||||||
'attr' => 'array',
|
|
||||||
'label_attr' => 'array',
|
'label_attr' => 'array',
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
39
src/Symfony/Component/Form/Extension/Core/Type/ResetType.php
Normal file
39
src/Symfony/Component/Form/Extension/Core/Type/ResetType.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Core\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\ButtonTypeInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A reset button.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class ResetType extends AbstractType implements ButtonTypeInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return 'button';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'reset';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Core\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
|
use Symfony\Component\Form\SubmitButtonTypeInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A submit button.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class SubmitType extends AbstractType implements SubmitButtonTypeInterface
|
||||||
|
{
|
||||||
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
|
{
|
||||||
|
$view->vars['clicked'] = $form->isClicked();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return 'button';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'submit';
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Form\Extension\Validator\Constraints;
|
namespace Symfony\Component\Form\Extension\Validator\Constraints;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\ClickableInterface;
|
||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
|
use Symfony\Component\Form\Extension\Validator\Util\ServerParams;
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
@ -171,15 +172,21 @@ class FormValidator extends ConstraintValidator
|
|||||||
*/
|
*/
|
||||||
private static function getValidationGroups(FormInterface $form)
|
private static function getValidationGroups(FormInterface $form)
|
||||||
{
|
{
|
||||||
|
$button = self::findClickedButton($form->getRoot());
|
||||||
|
|
||||||
|
if (null !== $button) {
|
||||||
|
$groups = $button->getConfig()->getOption('validation_groups');
|
||||||
|
|
||||||
|
if (null !== $groups) {
|
||||||
|
return self::resolveValidationGroups($groups, $form);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
$groups = $form->getConfig()->getOption('validation_groups');
|
$groups = $form->getConfig()->getOption('validation_groups');
|
||||||
|
|
||||||
if (null !== $groups) {
|
if (null !== $groups) {
|
||||||
if (is_callable($groups)) {
|
return self::resolveValidationGroups($groups, $form);
|
||||||
$groups = call_user_func($groups, $form);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (array) $groups;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$form = $form->getParent();
|
$form = $form->getParent();
|
||||||
@ -187,4 +194,43 @@ class FormValidator extends ConstraintValidator
|
|||||||
|
|
||||||
return array(Constraint::DEFAULT_GROUP);
|
return array(Constraint::DEFAULT_GROUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts a clicked button from a form tree, if one exists.
|
||||||
|
*
|
||||||
|
* @param FormInterface $form The root form.
|
||||||
|
*
|
||||||
|
* @return ClickableInterface|null The clicked button or null.
|
||||||
|
*/
|
||||||
|
private static function findClickedButton(FormInterface $form)
|
||||||
|
{
|
||||||
|
if ($form instanceof ClickableInterface && $form->isClicked()) {
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($form as $child) {
|
||||||
|
if (null !== ($button = self::findClickedButton($child))) {
|
||||||
|
return $button;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post-processes the validation groups option for a given form.
|
||||||
|
*
|
||||||
|
* @param array|callable $groups The validation groups.
|
||||||
|
* @param FormInterface $form The validated form.
|
||||||
|
*
|
||||||
|
* @return array The validation groups.
|
||||||
|
*/
|
||||||
|
private static function resolveValidationGroups($groups, FormInterface $form)
|
||||||
|
{
|
||||||
|
if (is_callable($groups)) {
|
||||||
|
$groups = call_user_func($groups, $form);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (array) $groups;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Validator\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encapsulates common logic of {@link FormTypeValidatorExtension} and
|
||||||
|
* {@link SubmitTypeValidatorExtension}.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
abstract class BaseValidatorExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||||
|
{
|
||||||
|
// Make sure that validation groups end up as null, closure or array
|
||||||
|
$validationGroupsNormalizer = function (Options $options, $groups) {
|
||||||
|
if (false === $groups) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($groups)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_callable($groups)) {
|
||||||
|
return $groups;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (array) $groups;
|
||||||
|
};
|
||||||
|
|
||||||
|
$resolver->setDefaults(array(
|
||||||
|
'validation_groups' => null,
|
||||||
|
));
|
||||||
|
|
||||||
|
$resolver->setNormalizers(array(
|
||||||
|
'validation_groups' => $validationGroupsNormalizer,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,7 @@ use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
|||||||
/**
|
/**
|
||||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
*/
|
*/
|
||||||
class FormTypeValidatorExtension extends AbstractTypeExtension
|
class FormTypeValidatorExtension extends BaseValidatorExtension
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var ValidatorInterface
|
* @var ValidatorInterface
|
||||||
@ -53,18 +53,7 @@ class FormTypeValidatorExtension extends AbstractTypeExtension
|
|||||||
*/
|
*/
|
||||||
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
public function setDefaultOptions(OptionsResolverInterface $resolver)
|
||||||
{
|
{
|
||||||
// Make sure that validation groups end up as null, closure or array
|
parent::setDefaultOptions($resolver);
|
||||||
$validationGroupsNormalizer = function (Options $options, $groups) {
|
|
||||||
if (empty($groups)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_callable($groups)) {
|
|
||||||
return $groups;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (array) $groups;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Constraint should always be converted to an array
|
// Constraint should always be converted to an array
|
||||||
$constraintsNormalizer = function (Options $options, $constraints) {
|
$constraintsNormalizer = function (Options $options, $constraints) {
|
||||||
@ -73,8 +62,8 @@ class FormTypeValidatorExtension extends AbstractTypeExtension
|
|||||||
|
|
||||||
$resolver->setDefaults(array(
|
$resolver->setDefaults(array(
|
||||||
'error_mapping' => array(),
|
'error_mapping' => array(),
|
||||||
'validation_groups' => null,
|
'validation_constraint' => null,
|
||||||
'constraints' => null,
|
'constraints' => array(),
|
||||||
'cascade_validation' => false,
|
'cascade_validation' => false,
|
||||||
'invalid_message' => 'This value is not valid.',
|
'invalid_message' => 'This value is not valid.',
|
||||||
'invalid_message_parameters' => array(),
|
'invalid_message_parameters' => array(),
|
||||||
@ -83,7 +72,6 @@ class FormTypeValidatorExtension extends AbstractTypeExtension
|
|||||||
));
|
));
|
||||||
|
|
||||||
$resolver->setNormalizers(array(
|
$resolver->setNormalizers(array(
|
||||||
'validation_groups' => $validationGroupsNormalizer,
|
|
||||||
'constraints' => $constraintsNormalizer,
|
'constraints' => $constraintsNormalizer,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Validator\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class SubmitTypeValidatorExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getExtendedType()
|
||||||
|
{
|
||||||
|
return 'submit';
|
||||||
|
}
|
||||||
|
}
|
@ -51,6 +51,7 @@ class ValidatorExtension extends AbstractExtension
|
|||||||
return array(
|
return array(
|
||||||
new Type\FormTypeValidatorExtension($this->validator),
|
new Type\FormTypeValidatorExtension($this->validator),
|
||||||
new Type\RepeatedTypeValidatorExtension(),
|
new Type\RepeatedTypeValidatorExtension(),
|
||||||
|
new Type\SubmitTypeValidatorExtension(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,13 +37,6 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
|
|||||||
*/
|
*/
|
||||||
private $unresolvedChildren = array();
|
private $unresolvedChildren = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* The parent of this builder.
|
|
||||||
*
|
|
||||||
* @var FormBuilder
|
|
||||||
*/
|
|
||||||
private $parent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new form builder.
|
* Creates a new form builder.
|
||||||
*
|
*
|
||||||
@ -70,7 +63,6 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($child instanceof self) {
|
if ($child instanceof self) {
|
||||||
$child->setParent($this);
|
|
||||||
$this->children[$child->getName()] = $child;
|
$this->children[$child->getName()] = $child;
|
||||||
|
|
||||||
// In case an unresolved child with the same name exists
|
// In case an unresolved child with the same name exists
|
||||||
@ -111,10 +103,10 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $type) {
|
if (null !== $type) {
|
||||||
return $this->getFormFactory()->createNamedBuilder($name, $type, null, $options, $this);
|
return $this->getFormFactory()->createNamedBuilder($name, $type, null, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->getFormFactory()->createBuilderForProperty($this->getDataClass(), $name, null, $options, $this);
|
return $this->getFormFactory()->createBuilderForProperty($this->getDataClass(), $name, null, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -149,9 +141,6 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
|
|||||||
unset($this->unresolvedChildren[$name]);
|
unset($this->unresolvedChildren[$name]);
|
||||||
|
|
||||||
if (array_key_exists($name, $this->children)) {
|
if (array_key_exists($name, $this->children)) {
|
||||||
if ($this->children[$name] instanceof self) {
|
|
||||||
$this->children[$name]->setParent(null);
|
|
||||||
}
|
|
||||||
unset($this->children[$name]);
|
unset($this->children[$name]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +200,6 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
|
|||||||
{
|
{
|
||||||
$config = parent::getFormConfig();
|
$config = parent::getFormConfig();
|
||||||
|
|
||||||
$config->parent = null;
|
|
||||||
$config->children = array();
|
$config->children = array();
|
||||||
$config->unresolvedChildren = array();
|
$config->unresolvedChildren = array();
|
||||||
|
|
||||||
@ -238,44 +226,6 @@ class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormB
|
|||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getParent()
|
|
||||||
{
|
|
||||||
if ($this->locked) {
|
|
||||||
throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function setParent(FormBuilderInterface $parent = null)
|
|
||||||
{
|
|
||||||
if ($this->locked) {
|
|
||||||
throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->parent = $parent;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function hasParent()
|
|
||||||
{
|
|
||||||
if ($this->locked) {
|
|
||||||
throw new BadMethodCallException('FormBuilder methods cannot be accessed anymore once the builder is turned into a FormConfigInterface instance.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return null !== $this->parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
|
@ -392,7 +392,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
|
|||||||
*/
|
*/
|
||||||
public function hasAttribute($name)
|
public function hasAttribute($name)
|
||||||
{
|
{
|
||||||
return isset($this->attributes[$name]);
|
return array_key_exists($name, $this->attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -400,7 +400,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
|
|||||||
*/
|
*/
|
||||||
public function getAttribute($name, $default = null)
|
public function getAttribute($name, $default = null)
|
||||||
{
|
{
|
||||||
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
|
return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -448,7 +448,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
|
|||||||
*/
|
*/
|
||||||
public function hasOption($name)
|
public function hasOption($name)
|
||||||
{
|
{
|
||||||
return isset($this->options[$name]);
|
return array_key_exists($name, $this->options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -456,7 +456,7 @@ class FormConfigBuilder implements FormConfigBuilderInterface
|
|||||||
*/
|
*/
|
||||||
public function getOption($name, $default = null)
|
public function getOption($name, $default = null)
|
||||||
{
|
{
|
||||||
return isset($this->options[$name]) ? $this->options[$name] : $default;
|
return array_key_exists($name, $this->options) ? $this->options[$name] : $default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file is part of the Symfony package.
|
* This file is part of the Symfony package.
|
||||||
*
|
*
|
||||||
|
@ -34,43 +34,43 @@ class FormFactory implements FormFactoryInterface
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function create($type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null)
|
public function create($type = 'form', $data = null, array $options = array())
|
||||||
{
|
{
|
||||||
return $this->createBuilder($type, $data, $options, $parent)->getForm();
|
return $this->createBuilder($type, $data, $options)->getForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function createNamed($name, $type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null)
|
public function createNamed($name, $type = 'form', $data = null, array $options = array())
|
||||||
{
|
{
|
||||||
return $this->createNamedBuilder($name, $type, $data, $options, $parent)->getForm();
|
return $this->createNamedBuilder($name, $type, $data, $options)->getForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function createForProperty($class, $property, $data = null, array $options = array(), FormBuilderInterface $parent = null)
|
public function createForProperty($class, $property, $data = null, array $options = array())
|
||||||
{
|
{
|
||||||
return $this->createBuilderForProperty($class, $property, $data, $options, $parent)->getForm();
|
return $this->createBuilderForProperty($class, $property, $data, $options)->getForm();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function createBuilder($type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null)
|
public function createBuilder($type = 'form', $data = null, array $options = array())
|
||||||
{
|
{
|
||||||
$name = $type instanceof FormTypeInterface || $type instanceof ResolvedFormTypeInterface
|
$name = $type instanceof FormTypeInterface || $type instanceof ResolvedFormTypeInterface
|
||||||
? $type->getName()
|
? $type->getName()
|
||||||
: $type;
|
: $type;
|
||||||
|
|
||||||
return $this->createNamedBuilder($name, $type, $data, $options, $parent);
|
return $this->createNamedBuilder($name, $type, $data, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function createNamedBuilder($name, $type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null)
|
public function createNamedBuilder($name, $type = 'form', $data = null, array $options = array())
|
||||||
{
|
{
|
||||||
if (null !== $data && !array_key_exists('data', $options)) {
|
if (null !== $data && !array_key_exists('data', $options)) {
|
||||||
$options['data'] = $data;
|
$options['data'] = $data;
|
||||||
@ -84,16 +84,16 @@ class FormFactory implements FormFactoryInterface
|
|||||||
throw new UnexpectedTypeException($type, 'string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface');
|
throw new UnexpectedTypeException($type, 'string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $type->createBuilder($this, $name, $options, $parent);
|
return $type->createBuilder($this, $name, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function createBuilderForProperty($class, $property, $data = null, array $options = array(), FormBuilderInterface $parent = null)
|
public function createBuilderForProperty($class, $property, $data = null, array $options = array())
|
||||||
{
|
{
|
||||||
if (null === $guesser = $this->registry->getTypeGuesser()) {
|
if (null === $guesser = $this->registry->getTypeGuesser()) {
|
||||||
return $this->createNamedBuilder($property, 'text', $data, $options, $parent);
|
return $this->createNamedBuilder($property, 'text', $data, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
$typeGuess = $guesser->guessType($class, $property);
|
$typeGuess = $guesser->guessType($class, $property);
|
||||||
@ -123,7 +123,7 @@ class FormFactory implements FormFactoryInterface
|
|||||||
$options = array_merge($typeGuess->getOptions(), $options);
|
$options = array_merge($typeGuess->getOptions(), $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->createNamedBuilder($property, $type, $data, $options, $parent);
|
return $this->createNamedBuilder($property, $type, $data, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,13 +24,12 @@ interface FormFactoryInterface
|
|||||||
* @param string|FormTypeInterface $type The type of the form
|
* @param string|FormTypeInterface $type The type of the form
|
||||||
* @param mixed $data The initial data
|
* @param mixed $data The initial data
|
||||||
* @param array $options The options
|
* @param array $options The options
|
||||||
* @param FormBuilderInterface $parent The parent builder
|
|
||||||
*
|
*
|
||||||
* @return FormInterface The form named after the type
|
* @return FormInterface The form named after the type
|
||||||
*
|
*
|
||||||
* @throws Exception\FormException if any given option is not applicable to the given type
|
* @throws Exception\FormException if any given option is not applicable to the given type
|
||||||
*/
|
*/
|
||||||
public function create($type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null);
|
public function create($type = 'form', $data = null, array $options = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a form.
|
* Returns a form.
|
||||||
@ -41,30 +40,28 @@ interface FormFactoryInterface
|
|||||||
* @param string|FormTypeInterface $type The type of the form
|
* @param string|FormTypeInterface $type The type of the form
|
||||||
* @param mixed $data The initial data
|
* @param mixed $data The initial data
|
||||||
* @param array $options The options
|
* @param array $options The options
|
||||||
* @param FormBuilderInterface $parent The parent builder
|
|
||||||
*
|
*
|
||||||
* @return FormInterface The form
|
* @return FormInterface The form
|
||||||
*
|
*
|
||||||
* @throws Exception\FormException if any given option is not applicable to the given type
|
* @throws Exception\FormException if any given option is not applicable to the given type
|
||||||
*/
|
*/
|
||||||
public function createNamed($name, $type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null);
|
public function createNamed($name, $type = 'form', $data = null, array $options = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a form for a property of a class.
|
* Returns a form for a property of a class.
|
||||||
*
|
*
|
||||||
* @see createBuilderForProperty()
|
* @see createBuilderForProperty()
|
||||||
*
|
*
|
||||||
* @param string $class The fully qualified class name
|
* @param string $class The fully qualified class name
|
||||||
* @param string $property The name of the property to guess for
|
* @param string $property The name of the property to guess for
|
||||||
* @param mixed $data The initial data
|
* @param mixed $data The initial data
|
||||||
* @param array $options The options for the builder
|
* @param array $options The options for the builder
|
||||||
* @param FormBuilderInterface $parent The parent builder
|
|
||||||
*
|
*
|
||||||
* @return FormInterface The form named after the property
|
* @return FormInterface The form named after the property
|
||||||
*
|
*
|
||||||
* @throws Exception\FormException if any given option is not applicable to the form type
|
* @throws Exception\FormException if any given option is not applicable to the form type
|
||||||
*/
|
*/
|
||||||
public function createForProperty($class, $property, $data = null, array $options = array(), FormBuilderInterface $parent = null);
|
public function createForProperty($class, $property, $data = null, array $options = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a form builder.
|
* Returns a form builder.
|
||||||
@ -72,13 +69,12 @@ interface FormFactoryInterface
|
|||||||
* @param string|FormTypeInterface $type The type of the form
|
* @param string|FormTypeInterface $type The type of the form
|
||||||
* @param mixed $data The initial data
|
* @param mixed $data The initial data
|
||||||
* @param array $options The options
|
* @param array $options The options
|
||||||
* @param FormBuilderInterface $parent The parent builder
|
|
||||||
*
|
*
|
||||||
* @return FormBuilderInterface The form builder
|
* @return FormBuilderInterface The form builder
|
||||||
*
|
*
|
||||||
* @throws Exception\FormException if any given option is not applicable to the given type
|
* @throws Exception\FormException if any given option is not applicable to the given type
|
||||||
*/
|
*/
|
||||||
public function createBuilder($type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null);
|
public function createBuilder($type = 'form', $data = null, array $options = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a form builder.
|
* Returns a form builder.
|
||||||
@ -87,13 +83,12 @@ interface FormFactoryInterface
|
|||||||
* @param string|FormTypeInterface $type The type of the form
|
* @param string|FormTypeInterface $type The type of the form
|
||||||
* @param mixed $data The initial data
|
* @param mixed $data The initial data
|
||||||
* @param array $options The options
|
* @param array $options The options
|
||||||
* @param FormBuilderInterface $parent The parent builder
|
|
||||||
*
|
*
|
||||||
* @return FormBuilderInterface The form builder
|
* @return FormBuilderInterface The form builder
|
||||||
*
|
*
|
||||||
* @throws Exception\FormException if any given option is not applicable to the given type
|
* @throws Exception\FormException if any given option is not applicable to the given type
|
||||||
*/
|
*/
|
||||||
public function createNamedBuilder($name, $type = 'form', $data = null, array $options = array(), FormBuilderInterface $parent = null);
|
public function createNamedBuilder($name, $type = 'form', $data = null, array $options = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a form builder for a property of a class.
|
* Returns a form builder for a property of a class.
|
||||||
@ -101,15 +96,14 @@ interface FormFactoryInterface
|
|||||||
* If any of the 'max_length', 'required' and type options can be guessed,
|
* If any of the 'max_length', 'required' and type options can be guessed,
|
||||||
* and are not provided in the options argument, the guessed value is used.
|
* and are not provided in the options argument, the guessed value is used.
|
||||||
*
|
*
|
||||||
* @param string $class The fully qualified class name
|
* @param string $class The fully qualified class name
|
||||||
* @param string $property The name of the property to guess for
|
* @param string $property The name of the property to guess for
|
||||||
* @param mixed $data The initial data
|
* @param mixed $data The initial data
|
||||||
* @param array $options The options for the builder
|
* @param array $options The options for the builder
|
||||||
* @param FormBuilderInterface $parent The parent builder
|
|
||||||
*
|
*
|
||||||
* @return FormBuilderInterface The form builder named after the property
|
* @return FormBuilderInterface The form builder named after the property
|
||||||
*
|
*
|
||||||
* @throws Exception\FormException if any given option is not applicable to the form type
|
* @throws Exception\FormException if any given option is not applicable to the form type
|
||||||
*/
|
*/
|
||||||
public function createBuilderForProperty($class, $property, $data = null, array $options = array(), FormBuilderInterface $parent = null);
|
public function createBuilderForProperty($class, $property, $data = null, array $options = array());
|
||||||
}
|
}
|
||||||
|
@ -150,9 +150,9 @@ interface FormInterface extends \ArrayAccess, \Traversable, \Countable
|
|||||||
public function getConfig();
|
public function getConfig();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the field is bound.
|
* Returns whether the form is submitted.
|
||||||
*
|
*
|
||||||
* @return Boolean true if the form is bound to input values, false otherwise
|
* @return Boolean true if the form is submitted, false otherwise
|
||||||
*/
|
*/
|
||||||
public function isBound();
|
public function isBound();
|
||||||
|
|
||||||
|
@ -104,16 +104,15 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
|||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function createBuilder(FormFactoryInterface $factory, $name, array $options = array(), FormBuilderInterface $parent = null)
|
public function createBuilder(FormFactoryInterface $factory, $name, array $options = array())
|
||||||
{
|
{
|
||||||
$options = $this->getOptionsResolver()->resolve($options);
|
$options = $this->getOptionsResolver()->resolve($options);
|
||||||
|
|
||||||
// Should be decoupled from the specific option at some point
|
// Should be decoupled from the specific option at some point
|
||||||
$dataClass = isset($options['data_class']) ? $options['data_class'] : null;
|
$dataClass = isset($options['data_class']) ? $options['data_class'] : null;
|
||||||
|
|
||||||
$builder = new FormBuilder($name, $dataClass, new EventDispatcher(), $factory, $options);
|
$builder = $this->newBuilder($name, $dataClass, $factory, $options);
|
||||||
$builder->setType($this);
|
$builder->setType($this);
|
||||||
$builder->setParent($parent);
|
|
||||||
|
|
||||||
$this->buildForm($builder, $options);
|
$this->buildForm($builder, $options);
|
||||||
|
|
||||||
@ -127,7 +126,7 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
|||||||
{
|
{
|
||||||
$options = $form->getConfig()->getOptions();
|
$options = $form->getConfig()->getOptions();
|
||||||
|
|
||||||
$view = new FormView($parent);
|
$view = $this->newView($parent);
|
||||||
|
|
||||||
$this->buildView($view, $form, $options);
|
$this->buildView($view, $form, $options);
|
||||||
|
|
||||||
@ -243,4 +242,43 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
|||||||
|
|
||||||
return $this->optionsResolver;
|
return $this->optionsResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new builder instance.
|
||||||
|
*
|
||||||
|
* Override this method if you want to customize the builder class.
|
||||||
|
*
|
||||||
|
* @param string $name The name of the builder.
|
||||||
|
* @param string $dataClass The data class.
|
||||||
|
* @param FormFactoryInterface $factory The current form factory.
|
||||||
|
* @param array $options The builder options.
|
||||||
|
*
|
||||||
|
* @return FormBuilderInterface The new builder instance.
|
||||||
|
*/
|
||||||
|
protected function newBuilder($name, $dataClass, FormFactoryInterface $factory, array $options)
|
||||||
|
{
|
||||||
|
if ($this->innerType instanceof ButtonTypeInterface) {
|
||||||
|
return new ButtonBuilder($name, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->innerType instanceof SubmitButtonTypeInterface) {
|
||||||
|
return new SubmitButtonBuilder($name, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new FormBuilder($name, $dataClass, new EventDispatcher(), $factory, $options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new view instance.
|
||||||
|
*
|
||||||
|
* Override this method if you want to customize the view class.
|
||||||
|
*
|
||||||
|
* @param FormView|null $parent The parent view, if available.
|
||||||
|
*
|
||||||
|
* @return FormView A new view instance.
|
||||||
|
*/
|
||||||
|
protected function newView(FormView $parent = null)
|
||||||
|
{
|
||||||
|
return new FormView($parent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,11 +52,10 @@ interface ResolvedFormTypeInterface
|
|||||||
* @param FormFactoryInterface $factory The form factory.
|
* @param FormFactoryInterface $factory The form factory.
|
||||||
* @param string $name The name for the builder.
|
* @param string $name The name for the builder.
|
||||||
* @param array $options The builder options.
|
* @param array $options The builder options.
|
||||||
* @param FormBuilderInterface $parent The parent builder object or null.
|
|
||||||
*
|
*
|
||||||
* @return FormBuilderInterface The created form builder.
|
* @return FormBuilderInterface The created form builder.
|
||||||
*/
|
*/
|
||||||
public function createBuilder(FormFactoryInterface $factory, $name, array $options = array(), FormBuilderInterface $parent = null);
|
public function createBuilder(FormFactoryInterface $factory, $name, array $options = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new form view for a form of this type.
|
* Creates a new form view for a form of this type.
|
||||||
|
51
src/Symfony/Component/Form/SubmitButton.php
Normal file
51
src/Symfony/Component/Form/SubmitButton.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A button that submits the form.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class SubmitButton extends Button implements ClickableInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Boolean
|
||||||
|
*/
|
||||||
|
private $clicked = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isClicked()
|
||||||
|
{
|
||||||
|
return $this->clicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds data to the button.
|
||||||
|
*
|
||||||
|
* @param null|string $submittedData The data
|
||||||
|
*
|
||||||
|
* @return SubmitButton The button instance
|
||||||
|
*
|
||||||
|
* @throws Exception\AlreadyBoundException If the form has already been bound.
|
||||||
|
*/
|
||||||
|
public function bind($submittedData)
|
||||||
|
{
|
||||||
|
parent::bind($submittedData);
|
||||||
|
|
||||||
|
$this->clicked = null !== $submittedData;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
30
src/Symfony/Component/Form/SubmitButtonBuilder.php
Normal file
30
src/Symfony/Component/Form/SubmitButtonBuilder.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder for {@link SubmitButton} instances.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class SubmitButtonBuilder extends ButtonBuilder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates the button.
|
||||||
|
*
|
||||||
|
* @return Button The button
|
||||||
|
*/
|
||||||
|
public function getForm()
|
||||||
|
{
|
||||||
|
return new SubmitButton($this->getFormConfig());
|
||||||
|
}
|
||||||
|
}
|
21
src/Symfony/Component/Form/SubmitButtonTypeInterface.php
Normal file
21
src/Symfony/Component/Form/SubmitButtonTypeInterface.php
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A type that should be converted into a {@link SubmitButton} instance.
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
interface SubmitButtonTypeInterface extends FormTypeInterface
|
||||||
|
{
|
||||||
|
}
|
@ -82,6 +82,22 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testButtonRow()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'button');
|
||||||
|
$view = $form->createView();
|
||||||
|
$html = $this->renderRow($view);
|
||||||
|
|
||||||
|
$this->assertMatchesXpath($html,
|
||||||
|
'/div
|
||||||
|
[
|
||||||
|
./button[@type="button"][@name="name"]
|
||||||
|
]
|
||||||
|
[count(//label)=0]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testRest()
|
public function testRest()
|
||||||
{
|
{
|
||||||
$view = $this->factory->createNamedBuilder('name', 'form')
|
$view = $this->factory->createNamedBuilder('name', 'form')
|
||||||
|
@ -1762,4 +1762,38 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
|||||||
//input[@type="text"][@id="child"][@name="child"]'
|
//input[@type="text"][@id="child"][@name="child"]'
|
||||||
, 2);
|
, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testButton()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'button');
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
||||||
|
'/button[@type="button"][@name="name"]'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testButtonLabelIsEmpty()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'button');
|
||||||
|
|
||||||
|
$this->assertSame('', $this->renderLabel($form->createView()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSubmit()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'submit');
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
||||||
|
'/button[@type="submit"][@name="name"]'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testReset()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'reset');
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
||||||
|
'/button[@type="reset"][@name="name"]'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,6 +125,25 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testButtonRow()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'button');
|
||||||
|
$view = $form->createView();
|
||||||
|
$html = $this->renderRow($view);
|
||||||
|
|
||||||
|
$this->assertMatchesXpath($html,
|
||||||
|
'/tr
|
||||||
|
[
|
||||||
|
./td
|
||||||
|
[.=""]
|
||||||
|
/following-sibling::td
|
||||||
|
[./button[@type="button"][@name="name"]]
|
||||||
|
]
|
||||||
|
[count(//label)=0]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testRest()
|
public function testRest()
|
||||||
{
|
{
|
||||||
$view = $this->factory->createNamedBuilder('name', 'form')
|
$view = $this->factory->createNamedBuilder('name', 'form')
|
||||||
|
@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
abstract class BaseTypeTest extends TypeTestCase
|
||||||
|
{
|
||||||
|
public function testPassDisabledAsOption()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create($this->getTestedType(), null, array('disabled' => true));
|
||||||
|
|
||||||
|
$this->assertTrue($form->isDisabled());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPassIdAndNameToView()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', $this->getTestedType());
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertEquals('name', $view->vars['id']);
|
||||||
|
$this->assertEquals('name', $view->vars['name']);
|
||||||
|
$this->assertEquals('name', $view->vars['full_name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testStripLeadingUnderscoresAndDigitsFromId()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('_09name', $this->getTestedType());
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertEquals('name', $view->vars['id']);
|
||||||
|
$this->assertEquals('_09name', $view->vars['name']);
|
||||||
|
$this->assertEquals('_09name', $view->vars['full_name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPassIdAndNameToViewWithParent()
|
||||||
|
{
|
||||||
|
$parent = $this->factory->createNamed('parent', 'form');
|
||||||
|
$parent->add($this->factory->createNamed('child', $this->getTestedType()));
|
||||||
|
$view = $parent->createView();
|
||||||
|
|
||||||
|
$this->assertEquals('parent_child', $view['child']->vars['id']);
|
||||||
|
$this->assertEquals('child', $view['child']->vars['name']);
|
||||||
|
$this->assertEquals('parent[child]', $view['child']->vars['full_name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPassIdAndNameToViewWithGrandParent()
|
||||||
|
{
|
||||||
|
$parent = $this->factory->createNamed('parent', 'form');
|
||||||
|
$parent->add($this->factory->createNamed('child', 'form'));
|
||||||
|
$parent['child']->add($this->factory->createNamed('grand_child', $this->getTestedType()));
|
||||||
|
$view = $parent->createView();
|
||||||
|
|
||||||
|
$this->assertEquals('parent_child_grand_child', $view['child']['grand_child']->vars['id']);
|
||||||
|
$this->assertEquals('grand_child', $view['child']['grand_child']->vars['name']);
|
||||||
|
$this->assertEquals('parent[child][grand_child]', $view['child']['grand_child']->vars['full_name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPassTranslationDomainToView()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create($this->getTestedType(), null, array(
|
||||||
|
'translation_domain' => 'domain',
|
||||||
|
));
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertSame('domain', $view->vars['translation_domain']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testInheritTranslationDomainFromParent()
|
||||||
|
{
|
||||||
|
$parent = $this->factory->createNamed('parent', 'form', null, array(
|
||||||
|
'translation_domain' => 'domain',
|
||||||
|
));
|
||||||
|
$child = $this->factory->createNamed('child', $this->getTestedType());
|
||||||
|
$view = $parent->add($child)->createView();
|
||||||
|
|
||||||
|
$this->assertEquals('domain', $view['child']->vars['translation_domain']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPreferOwnTranslationDomain()
|
||||||
|
{
|
||||||
|
$parent = $this->factory->createNamed('parent', 'form', null, array(
|
||||||
|
'translation_domain' => 'parent_domain',
|
||||||
|
));
|
||||||
|
$child = $this->factory->createNamed('child', $this->getTestedType(), null, array(
|
||||||
|
'translation_domain' => 'domain',
|
||||||
|
));
|
||||||
|
$view = $parent->add($child)->createView();
|
||||||
|
|
||||||
|
$this->assertEquals('domain', $view['child']->vars['translation_domain']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDefaultTranslationDomain()
|
||||||
|
{
|
||||||
|
$parent = $this->factory->createNamed('parent', 'form');
|
||||||
|
$child = $this->factory->createNamed('child', $this->getTestedType());
|
||||||
|
$view = $parent->add($child)->createView();
|
||||||
|
|
||||||
|
$this->assertEquals('messages', $view['child']->vars['translation_domain']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPassLabelToView()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('__test___field', $this->getTestedType(), null, array('label' => 'My label'));
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertSame('My label', $view->vars['label']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPassMultipartFalseToView()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create($this->getTestedType());
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertFalse($view->vars['multipart']);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract protected function getTestedType();
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class ButtonTypeTest extends BaseTypeTest
|
||||||
|
{
|
||||||
|
public function testCreateButtonInstances()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Button', $this->factory->create('button'));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTestedType()
|
||||||
|
{
|
||||||
|
return 'button';
|
||||||
|
}
|
||||||
|
}
|
@ -50,8 +50,13 @@ class FormTest_AuthorWithoutRefSetter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FormTypeTest extends TypeTestCase
|
class FormTypeTest extends BaseTypeTest
|
||||||
{
|
{
|
||||||
|
public function testCreateFormInstances()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\Form', $this->factory->create('form'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testPassRequiredAsOption()
|
public function testPassRequiredAsOption()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('form', null, array('required' => false));
|
$form = $this->factory->create('form', null, array('required' => false));
|
||||||
@ -63,13 +68,6 @@ class FormTypeTest extends TypeTestCase
|
|||||||
$this->assertTrue($form->isRequired());
|
$this->assertTrue($form->isRequired());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPassDisabledAsOption()
|
|
||||||
{
|
|
||||||
$form = $this->factory->create('form', null, array('disabled' => true));
|
|
||||||
|
|
||||||
$this->assertTrue($form->isDisabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testBoundDataIsTrimmedBeforeTransforming()
|
public function testBoundDataIsTrimmedBeforeTransforming()
|
||||||
{
|
{
|
||||||
$form = $this->factory->createBuilder('form')
|
$form = $this->factory->createBuilder('form')
|
||||||
@ -102,49 +100,6 @@ class FormTypeTest extends TypeTestCase
|
|||||||
$this->assertEquals('reverse[ a ]', $form->getData());
|
$this->assertEquals('reverse[ a ]', $form->getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPassIdAndNameToView()
|
|
||||||
{
|
|
||||||
$form = $this->factory->createNamed('name', 'form');
|
|
||||||
$view = $form->createView();
|
|
||||||
|
|
||||||
$this->assertEquals('name', $view->vars['id']);
|
|
||||||
$this->assertEquals('name', $view->vars['name']);
|
|
||||||
$this->assertEquals('name', $view->vars['full_name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testStripLeadingUnderscoresAndDigitsFromId()
|
|
||||||
{
|
|
||||||
$form = $this->factory->createNamed('_09name', 'form');
|
|
||||||
$view = $form->createView();
|
|
||||||
|
|
||||||
$this->assertEquals('name', $view->vars['id']);
|
|
||||||
$this->assertEquals('_09name', $view->vars['name']);
|
|
||||||
$this->assertEquals('_09name', $view->vars['full_name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testPassIdAndNameToViewWithParent()
|
|
||||||
{
|
|
||||||
$parent = $this->factory->createNamed('parent', 'form');
|
|
||||||
$parent->add($this->factory->createNamed('child', 'form'));
|
|
||||||
$view = $parent->createView();
|
|
||||||
|
|
||||||
$this->assertEquals('parent_child', $view['child']->vars['id']);
|
|
||||||
$this->assertEquals('child', $view['child']->vars['name']);
|
|
||||||
$this->assertEquals('parent[child]', $view['child']->vars['full_name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testPassIdAndNameToViewWithGrandParent()
|
|
||||||
{
|
|
||||||
$parent = $this->factory->createNamed('parent', 'form');
|
|
||||||
$parent->add($this->factory->createNamed('child', 'form'));
|
|
||||||
$parent['child']->add($this->factory->createNamed('grand_child', 'form'));
|
|
||||||
$view = $parent->createView();
|
|
||||||
|
|
||||||
$this->assertEquals('parent_child_grand_child', $view['child']['grand_child']->vars['id']);
|
|
||||||
$this->assertEquals('grand_child', $view['child']['grand_child']->vars['name']);
|
|
||||||
$this->assertEquals('parent[child][grand_child]', $view['child']['grand_child']->vars['full_name']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testNonReadOnlyFormWithReadOnlyParentBeingReadOnly()
|
public function testNonReadOnlyFormWithReadOnlyParentBeingReadOnly()
|
||||||
{
|
{
|
||||||
$parent = $this->factory->createNamed('parent', 'form', null, array('read_only' => true));
|
$parent = $this->factory->createNamed('parent', 'form', null, array('read_only' => true));
|
||||||
@ -180,57 +135,6 @@ class FormTypeTest extends TypeTestCase
|
|||||||
$this->assertSame(10, $view->vars['max_length']);
|
$this->assertSame(10, $view->vars['max_length']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPassTranslationDomainToView()
|
|
||||||
{
|
|
||||||
$form = $this->factory->create('form', null, array('translation_domain' => 'test'));
|
|
||||||
$view = $form->createView();
|
|
||||||
|
|
||||||
$this->assertSame('test', $view->vars['translation_domain']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testNonTranslationDomainFormWithTranslationDomainParentBeingTranslationDomain()
|
|
||||||
{
|
|
||||||
$parent = $this->factory->createNamed('parent', 'form', null, array('translation_domain' => 'test'));
|
|
||||||
$child = $this->factory->createNamed('child', 'form');
|
|
||||||
$view = $parent->add($child)->createView();
|
|
||||||
|
|
||||||
$this->assertEquals('test', $view['child']->vars['translation_domain']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testTranslationDomainFormWithNonTranslationDomainParentBeingTranslationDomain()
|
|
||||||
{
|
|
||||||
$parent = $this->factory->createNamed('parent', 'form');
|
|
||||||
$child = $this->factory->createNamed('child', 'form', null, array('translation_domain' => 'test'));
|
|
||||||
$view = $parent->add($child)->createView();
|
|
||||||
|
|
||||||
$this->assertEquals('test', $view['child']->vars['translation_domain']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testNonTranslationDomainFormWithNonTranslationDomainParentBeingTranslationDomainDefault()
|
|
||||||
{
|
|
||||||
$parent = $this->factory->createNamed('parent', 'form');
|
|
||||||
$child = $this->factory->createNamed('child', 'form');
|
|
||||||
$view = $parent->add($child)->createView();
|
|
||||||
|
|
||||||
$this->assertEquals('messages', $view['child']->vars['translation_domain']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testPassLabelToView()
|
|
||||||
{
|
|
||||||
$form = $this->factory->createNamed('__test___field', 'form', null, array('label' => 'My label'));
|
|
||||||
$view = $form->createView();
|
|
||||||
|
|
||||||
$this->assertSame('My label', $view->vars['label']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testDefaultTranslationDomain()
|
|
||||||
{
|
|
||||||
$form = $this->factory->create('form');
|
|
||||||
$view = $form->createView();
|
|
||||||
|
|
||||||
$this->assertSame('messages', $view->vars['translation_domain']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testBindWithEmptyDataCreatesObjectIfClassAvailable()
|
public function testBindWithEmptyDataCreatesObjectIfClassAvailable()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('form', null, array(
|
$form = $this->factory->create('form', null, array(
|
||||||
@ -404,6 +308,7 @@ class FormTypeTest extends TypeTestCase
|
|||||||
|
|
||||||
$this->assertEquals('', $form->getName());
|
$this->assertEquals('', $form->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSubformDoesntCallSetters()
|
public function testSubformDoesntCallSetters()
|
||||||
{
|
{
|
||||||
$author = new FormTest_AuthorWithoutRefSetter(new Author());
|
$author = new FormTest_AuthorWithoutRefSetter(new Author());
|
||||||
@ -523,14 +428,6 @@ class FormTypeTest extends TypeTestCase
|
|||||||
$this->assertSame($ref2, $author['referenceCopy']);
|
$this->assertSame($ref2, $author['referenceCopy']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPassMultipartFalseToView()
|
|
||||||
{
|
|
||||||
$form = $this->factory->create('form');
|
|
||||||
$view = $form->createView();
|
|
||||||
|
|
||||||
$this->assertFalse($view->vars['multipart']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testPassMultipartTrueIfAnyChildIsMultipartToView()
|
public function testPassMultipartTrueIfAnyChildIsMultipartToView()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('form');
|
$form = $this->factory->create('form');
|
||||||
@ -661,4 +558,9 @@ class FormTypeTest extends TypeTestCase
|
|||||||
|
|
||||||
$this->assertSame('0', $view->vars['label']);
|
$this->assertSame('0', $view->vars['label']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getTestedType()
|
||||||
|
{
|
||||||
|
return 'form';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||||
|
*/
|
||||||
|
class SubmitTypeTest extends TypeTestCase
|
||||||
|
{
|
||||||
|
public function testCreateSubmitButtonInstances()
|
||||||
|
{
|
||||||
|
$this->assertInstanceOf('Symfony\Component\Form\SubmitButton', $this->factory->create('submit'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNotClickedByDefault()
|
||||||
|
{
|
||||||
|
$button = $this->factory->create('submit');
|
||||||
|
|
||||||
|
$this->assertFalse($button->isClicked());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNotClickedIfBoundWithNull()
|
||||||
|
{
|
||||||
|
$button = $this->factory->create('submit');
|
||||||
|
$button->bind(null);
|
||||||
|
|
||||||
|
$this->assertFalse($button->isClicked());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClickedIfBoundWithEmptyString()
|
||||||
|
{
|
||||||
|
$button = $this->factory->create('submit');
|
||||||
|
$button->bind('');
|
||||||
|
|
||||||
|
$this->assertTrue($button->isClicked());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testClickedIfBoundWithUnemptyString()
|
||||||
|
{
|
||||||
|
$button = $this->factory->create('submit');
|
||||||
|
$button->bind('foo');
|
||||||
|
|
||||||
|
$this->assertTrue($button->isClicked());
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,7 @@ use Symfony\Component\Form\CallbackTransformer;
|
|||||||
use Symfony\Component\Form\FormInterface;
|
use Symfony\Component\Form\FormInterface;
|
||||||
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
|
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
|
||||||
use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
|
use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
|
||||||
|
use Symfony\Component\Form\SubmitButtonBuilder;
|
||||||
use Symfony\Component\Validator\Constraint;
|
use Symfony\Component\Validator\Constraint;
|
||||||
use Symfony\Component\Validator\Constraints\NotNull;
|
use Symfony\Component\Validator\Constraints\NotNull;
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
@ -169,6 +170,51 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->validator->validate($form, new Form());
|
$this->validator->validate($form, new Form());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDontValidateIfNoValidationGroups()
|
||||||
|
{
|
||||||
|
$context = $this->getMockExecutionContext();
|
||||||
|
$object = $this->getMock('\stdClass');
|
||||||
|
|
||||||
|
$form = $this->getBuilder('name', '\stdClass', array(
|
||||||
|
'validation_groups' => array(),
|
||||||
|
))
|
||||||
|
->setData($object)
|
||||||
|
->getForm();
|
||||||
|
|
||||||
|
$form->setData($object);
|
||||||
|
|
||||||
|
$context->expects($this->never())
|
||||||
|
->method('validate');
|
||||||
|
|
||||||
|
$this->validator->initialize($context);
|
||||||
|
$this->validator->validate($form, new Form());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDontValidateConstraintsIfNoValidationGroups()
|
||||||
|
{
|
||||||
|
$context = $this->getMockExecutionContext();
|
||||||
|
$object = $this->getMock('\stdClass');
|
||||||
|
$constraint1 = $this->getMock('Symfony\Component\Validator\Constraint');
|
||||||
|
$constraint2 = $this->getMock('Symfony\Component\Validator\Constraint');
|
||||||
|
|
||||||
|
$options = array(
|
||||||
|
'validation_groups' => array(),
|
||||||
|
'constraints' => array($constraint1, $constraint2),
|
||||||
|
);
|
||||||
|
$form = $this->getBuilder('name', '\stdClass', $options)
|
||||||
|
->setData($object)
|
||||||
|
->getForm();
|
||||||
|
|
||||||
|
// Launch transformer
|
||||||
|
$form->bind(array());
|
||||||
|
|
||||||
|
$context->expects($this->never())
|
||||||
|
->method('validate');
|
||||||
|
|
||||||
|
$this->validator->initialize($context);
|
||||||
|
$this->validator->validate($form, new Form());
|
||||||
|
}
|
||||||
|
|
||||||
public function testDontValidateIfNotSynchronized()
|
public function testDontValidateIfNotSynchronized()
|
||||||
{
|
{
|
||||||
$context = $this->getMockExecutionContext();
|
$context = $this->getMockExecutionContext();
|
||||||
@ -208,6 +254,46 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->validator->validate($form, new Form());
|
$this->validator->validate($form, new Form());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAddInvalidErrorEvenIfNoValidationGroups()
|
||||||
|
{
|
||||||
|
$context = $this->getMockExecutionContext();
|
||||||
|
$object = $this->getMock('\stdClass');
|
||||||
|
|
||||||
|
$form = $this->getBuilder('name', '\stdClass', array(
|
||||||
|
'invalid_message' => 'invalid_message_key',
|
||||||
|
// Invalid message parameters must be supported, because the
|
||||||
|
// invalid message can be a translation key
|
||||||
|
// see https://github.com/symfony/symfony/issues/5144
|
||||||
|
'invalid_message_parameters' => array('{{ foo }}' => 'bar'),
|
||||||
|
'validation_groups' => array(),
|
||||||
|
))
|
||||||
|
->setData($object)
|
||||||
|
->addViewTransformer(new CallbackTransformer(
|
||||||
|
function ($data) { return $data; },
|
||||||
|
function () { throw new TransformationFailedException(); }
|
||||||
|
))
|
||||||
|
->getForm();
|
||||||
|
|
||||||
|
// Launch transformer
|
||||||
|
$form->bind('foo');
|
||||||
|
|
||||||
|
$context->expects($this->never())
|
||||||
|
->method('validate');
|
||||||
|
|
||||||
|
$context->expects($this->once())
|
||||||
|
->method('addViolation')
|
||||||
|
->with(
|
||||||
|
'invalid_message_key',
|
||||||
|
array('{{ value }}' => 'foo', '{{ foo }}' => 'bar'),
|
||||||
|
'foo'
|
||||||
|
);
|
||||||
|
$context->expects($this->never())
|
||||||
|
->method('addViolationAt');
|
||||||
|
|
||||||
|
$this->validator->initialize($context);
|
||||||
|
$this->validator->validate($form, new Form());
|
||||||
|
}
|
||||||
|
|
||||||
public function testDontValidateConstraintsIfNotSynchronized()
|
public function testDontValidateConstraintsIfNotSynchronized()
|
||||||
{
|
{
|
||||||
$context = $this->getMockExecutionContext();
|
$context = $this->getMockExecutionContext();
|
||||||
@ -313,6 +399,62 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->validator->validate($form, new Form());
|
$this->validator->validate($form, new Form());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testUseValidationGroupOfClickedButton()
|
||||||
|
{
|
||||||
|
$context = $this->getMockExecutionContext();
|
||||||
|
$object = $this->getMock('\stdClass');
|
||||||
|
|
||||||
|
$parent = $this->getBuilder('parent', null, array('cascade_validation' => true))
|
||||||
|
->setCompound(true)
|
||||||
|
->setDataMapper($this->getDataMapper())
|
||||||
|
->getForm();
|
||||||
|
$form = $this->getForm('name', '\stdClass', array(
|
||||||
|
'validation_groups' => 'form_group',
|
||||||
|
));
|
||||||
|
|
||||||
|
$parent->add($form);
|
||||||
|
$parent->add($this->getClickedSubmitButton('submit', array(
|
||||||
|
'validation_groups' => 'button_group',
|
||||||
|
)));
|
||||||
|
|
||||||
|
$form->setData($object);
|
||||||
|
|
||||||
|
$context->expects($this->once())
|
||||||
|
->method('validate')
|
||||||
|
->with($object, 'data', 'button_group', true);
|
||||||
|
|
||||||
|
$this->validator->initialize($context);
|
||||||
|
$this->validator->validate($form, new Form());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDontUseValidationGroupOfUnclickedButton()
|
||||||
|
{
|
||||||
|
$context = $this->getMockExecutionContext();
|
||||||
|
$object = $this->getMock('\stdClass');
|
||||||
|
|
||||||
|
$parent = $this->getBuilder('parent', null, array('cascade_validation' => true))
|
||||||
|
->setCompound(true)
|
||||||
|
->setDataMapper($this->getDataMapper())
|
||||||
|
->getForm();
|
||||||
|
$form = $this->getForm('name', '\stdClass', array(
|
||||||
|
'validation_groups' => 'form_group',
|
||||||
|
));
|
||||||
|
|
||||||
|
$parent->add($form);
|
||||||
|
$parent->add($this->getSubmitButton('submit', array(
|
||||||
|
'validation_groups' => 'button_group',
|
||||||
|
)));
|
||||||
|
|
||||||
|
$form->setData($object);
|
||||||
|
|
||||||
|
$context->expects($this->once())
|
||||||
|
->method('validate')
|
||||||
|
->with($object, 'data', 'form_group', true);
|
||||||
|
|
||||||
|
$this->validator->initialize($context);
|
||||||
|
$this->validator->validate($form, new Form());
|
||||||
|
}
|
||||||
|
|
||||||
public function testUseInheritedValidationGroup()
|
public function testUseInheritedValidationGroup()
|
||||||
{
|
{
|
||||||
$context = $this->getMockExecutionContext();
|
$context = $this->getMockExecutionContext();
|
||||||
@ -561,9 +703,21 @@ class FormValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
return new FormBuilder($name, $dataClass, $this->dispatcher, $this->factory, $options);
|
return new FormBuilder($name, $dataClass, $this->dispatcher, $this->factory, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getForm($name = 'name', $dataClass = null)
|
private function getForm($name = 'name', $dataClass = null, array $options = array())
|
||||||
{
|
{
|
||||||
return $this->getBuilder($name, $dataClass)->getForm();
|
return $this->getBuilder($name, $dataClass, $options)->getForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSubmitButton($name = 'name', array $options = array())
|
||||||
|
{
|
||||||
|
$builder = new SubmitButtonBuilder($name, $options);
|
||||||
|
|
||||||
|
return $builder->getForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getClickedSubmitButton($name = 'name', array $options = array())
|
||||||
|
{
|
||||||
|
return $this->getSubmitButton($name, $options)->bind('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +40,15 @@ class FormTypeValidatorExtensionTest extends TypeTestCase
|
|||||||
$this->assertEquals(array('group1', 'group2'), $form->getConfig()->getOption('validation_groups'));
|
$this->assertEquals(array('group1', 'group2'), $form->getConfig()->getOption('validation_groups'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testValidationGroupsCanBeSetToFalse()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('form', null, array(
|
||||||
|
'validation_groups' => false,
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertEquals(array(), $form->getConfig()->getOption('validation_groups'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testValidationGroupsCanBeSetToCallback()
|
public function testValidationGroupsCanBeSetToCallback()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('form', null, array(
|
$form = $this->factory->create('form', null, array(
|
||||||
|
@ -781,7 +781,7 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase
|
|||||||
} else {
|
} else {
|
||||||
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
|
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
|
||||||
$this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one');
|
$this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one');
|
||||||
$this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName. ' should have an error, but has none');
|
$this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1253,7 +1253,7 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase
|
|||||||
} else {
|
} else {
|
||||||
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
|
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
|
||||||
$this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one');
|
$this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one');
|
||||||
$this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName. ' should have an error, but has none');
|
$this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1442,7 +1442,7 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertCount(0, $errorChild->getErrors(), $errorName.' should not have an error, but has one');
|
$this->assertCount(0, $errorChild->getErrors(), $errorName.' should not have an error, but has one');
|
||||||
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
|
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
|
||||||
$this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one');
|
$this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one');
|
||||||
$this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName. ' should have an error, but has none');
|
$this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1497,7 +1497,7 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase
|
|||||||
} else {
|
} else {
|
||||||
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
|
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
|
||||||
$this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one');
|
$this->assertCount(0, $child->getErrors(), $childName.' should not have an error, but has one');
|
||||||
$this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName. ' should have an error, but has none');
|
$this->assertEquals(array($this->getFormError()), $grandChild->getErrors(), $grandChildName.' should have an error, but has none');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,62 +200,19 @@ class FormBuilderTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertNotSame($builder, $this->builder);
|
$this->assertNotSame($builder, $this->builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetParent()
|
|
||||||
{
|
|
||||||
$this->assertNull($this->builder->getParent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetParentForAddedBuilder()
|
|
||||||
{
|
|
||||||
$builder = new FormBuilder('name', null, $this->dispatcher, $this->factory);
|
|
||||||
$this->builder->add($builder);
|
|
||||||
$this->assertSame($this->builder, $builder->getParent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetParentForRemovedBuilder()
|
|
||||||
{
|
|
||||||
$builder = new FormBuilder('name', null, $this->dispatcher, $this->factory);
|
|
||||||
$this->builder->add($builder);
|
|
||||||
$this->builder->remove('name');
|
|
||||||
$this->assertNull($builder->getParent());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetParentForCreatedBuilder()
|
|
||||||
{
|
|
||||||
$this->builder = new FormBuilder('name', 'stdClass', $this->dispatcher, $this->factory);
|
|
||||||
$this->factory
|
|
||||||
->expects($this->once())
|
|
||||||
->method('createNamedBuilder')
|
|
||||||
->with('bar', 'text', null, array(), $this->builder)
|
|
||||||
;
|
|
||||||
|
|
||||||
$this->factory
|
|
||||||
->expects($this->once())
|
|
||||||
->method('createBuilderForProperty')
|
|
||||||
->with('stdClass', 'foo', null, array(), $this->builder)
|
|
||||||
;
|
|
||||||
|
|
||||||
$this->builder->create('foo');
|
|
||||||
$this->builder->create('bar', 'text');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testGetFormConfigErasesReferences()
|
public function testGetFormConfigErasesReferences()
|
||||||
{
|
{
|
||||||
$builder = new FormBuilder('name', null, $this->dispatcher, $this->factory);
|
$builder = new FormBuilder('name', null, $this->dispatcher, $this->factory);
|
||||||
$builder->setParent(new FormBuilder('parent', null, $this->dispatcher, $this->factory));
|
|
||||||
$builder->add(new FormBuilder('child', null, $this->dispatcher, $this->factory));
|
$builder->add(new FormBuilder('child', null, $this->dispatcher, $this->factory));
|
||||||
|
|
||||||
$config = $builder->getFormConfig();
|
$config = $builder->getFormConfig();
|
||||||
$reflClass = new \ReflectionClass($config);
|
$reflClass = new \ReflectionClass($config);
|
||||||
$parent = $reflClass->getProperty('parent');
|
|
||||||
$children = $reflClass->getProperty('children');
|
$children = $reflClass->getProperty('children');
|
||||||
$unresolvedChildren = $reflClass->getProperty('unresolvedChildren');
|
$unresolvedChildren = $reflClass->getProperty('unresolvedChildren');
|
||||||
|
|
||||||
$parent->setAccessible(true);
|
|
||||||
$children->setAccessible(true);
|
$children->setAccessible(true);
|
||||||
$unresolvedChildren->setAccessible(true);
|
$unresolvedChildren->setAccessible(true);
|
||||||
|
|
||||||
$this->assertNull($parent->getValue($config));
|
|
||||||
$this->assertEmpty($children->getValue($config));
|
$this->assertEmpty($children->getValue($config));
|
||||||
$this->assertEmpty($unresolvedChildren->getValue($config));
|
$this->assertEmpty($unresolvedChildren->getValue($config));
|
||||||
}
|
}
|
||||||
|
@ -171,25 +171,6 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertSame('BUILDER', $this->factory->createNamedBuilder('name', $resolvedType, null, $options));
|
$this->assertSame('BUILDER', $this->factory->createNamedBuilder('name', $resolvedType, null, $options));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCreateNamedBuilderWithParentBuilder()
|
|
||||||
{
|
|
||||||
$options = array('a' => '1', 'b' => '2');
|
|
||||||
$parentBuilder = $this->getMockFormBuilder();
|
|
||||||
$resolvedType = $this->getMockResolvedType();
|
|
||||||
|
|
||||||
$this->registry->expects($this->once())
|
|
||||||
->method('getType')
|
|
||||||
->with('type')
|
|
||||||
->will($this->returnValue($resolvedType));
|
|
||||||
|
|
||||||
$resolvedType->expects($this->once())
|
|
||||||
->method('createBuilder')
|
|
||||||
->with($this->factory, 'name', $options, $parentBuilder)
|
|
||||||
->will($this->returnValue('BUILDER'));
|
|
||||||
|
|
||||||
$this->assertSame('BUILDER', $this->factory->createNamedBuilder('name', 'type', null, $options, $parentBuilder));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testCreateNamedBuilderFillsDataOption()
|
public function testCreateNamedBuilderFillsDataOption()
|
||||||
{
|
{
|
||||||
$givenOptions = array('a' => '1', 'b' => '2');
|
$givenOptions = array('a' => '1', 'b' => '2');
|
||||||
@ -228,7 +209,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException
|
* @expectedException \Symfony\Component\Form\Exception\UnexpectedTypeException
|
||||||
* @expectedExceptionMessage Expected argument of type "string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface", "stdClass" given
|
* @expectedExceptionMessage Expected argument of type "string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface", "stdClass" given
|
||||||
*/
|
*/
|
||||||
public function testCreateNamedBuilderThrowsUnderstandableException()
|
public function testCreateNamedBuilderThrowsUnderstandableException()
|
||||||
|
@ -134,10 +134,8 @@ class ResolvedFormTypeTest extends \PHPUnit_Framework_TestCase
|
|||||||
->will($this->returnCallback($assertIndex(7)));
|
->will($this->returnCallback($assertIndex(7)));
|
||||||
|
|
||||||
$factory = $this->getMockFormFactory();
|
$factory = $this->getMockFormFactory();
|
||||||
$parentBuilder = $this->getBuilder('parent');
|
$builder = $resolvedType->createBuilder($factory, 'name', $givenOptions);
|
||||||
$builder = $resolvedType->createBuilder($factory, 'name', $givenOptions, $parentBuilder);
|
|
||||||
|
|
||||||
$this->assertSame($parentBuilder, $builder->getParent());
|
|
||||||
$this->assertSame($resolvedType, $builder->getType());
|
$this->assertSame($resolvedType, $builder->getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ class XliffFileLoaderTest extends \PHPUnit_Framework_TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException Symfony\Component\Translation\Exception\InvalidResourceException
|
* @expectedException \Symfony\Component\Translation\Exception\InvalidResourceException
|
||||||
* @expectedExceptionMessage Document types are not allowed.
|
* @expectedExceptionMessage Document types are not allowed.
|
||||||
*/
|
*/
|
||||||
public function testDocTypeIsNotAllowed()
|
public function testDocTypeIsNotAllowed()
|
||||||
|
@ -82,7 +82,7 @@ class XmlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @expectedException Symfony\Component\Validator\Exception\MappingException
|
* @expectedException \Symfony\Component\Validator\Exception\MappingException
|
||||||
* @expectedExceptionMessage Document types are not allowed.
|
* @expectedExceptionMessage Document types are not allowed.
|
||||||
*/
|
*/
|
||||||
public function testDocTypeIsNotAllowed()
|
public function testDocTypeIsNotAllowed()
|
||||||
|
Reference in New Issue
Block a user