@@ -64,11 +64,7 @@
|
||||
<argument /> <!-- filter -->
|
||||
</service>
|
||||
|
||||
<service id="assetic.parameter_bag" class="Symfony\Component\DependencyInjection\ParameterBag\ParameterBag" public="false">
|
||||
<argument type="service" id="assetic.parameters" />
|
||||
</service>
|
||||
|
||||
<service id="assetic.parameters" class="stdClass" factory-service="service_container" factory-method="getDefaultParameters" public="false" />
|
||||
<service id="assetic.parameter_bag" class="Symfony\Component\DependencyInjection\ParameterBag\ParameterBag" factory-service="service_container" factory-method="getParameterBag" public="false"/>
|
||||
|
||||
<service id="assetic.value_supplier.default" class="%assetic.value_supplier.class%" public="false">
|
||||
<argument type="service" id="service_container" />
|
||||
|
18
vendor/symfony/symfony/UPGRADE-2.1.md
vendored
18
vendor/symfony/symfony/UPGRADE-2.1.md
vendored
@@ -247,11 +247,10 @@
|
||||
reasons. It is now not possible anymore to use custom implementations of
|
||||
`FormBuilderInterface` for specific form types.
|
||||
|
||||
If you are in such a situation, you can subclass `FormRegistry` instead and override
|
||||
`resolveType` to return a custom `ResolvedFormTypeInterface` implementation, within
|
||||
which you can create your own `FormBuilderInterface` implementation. You should
|
||||
register this custom registry class under the service name "form.registry" in order
|
||||
to replace the default implementation.
|
||||
If you are in such a situation, you can implement a custom `ResolvedFormTypeInterface`
|
||||
where you create your own `FormBuilderInterface` implementation. You also need to
|
||||
register a custom `ResolvedFormTypeFactoryInterface` implementation under the service
|
||||
name "form.resolved_type_factory" in order to replace the default implementation.
|
||||
|
||||
* If you previously inherited from `FieldType`, you should now inherit from
|
||||
`FormType`. You should also set the option `compound` to `false` if your field
|
||||
@@ -1199,8 +1198,8 @@
|
||||
}
|
||||
```
|
||||
|
||||
* Core translation messages are changed. Dot is added at the end of each message.
|
||||
Overwritten core translations should be fixed if any. More info here.
|
||||
* Core translation messages changed. A dot is added at the end of each message.
|
||||
Overwritten core translations need to be fixed.
|
||||
|
||||
* Collections (arrays or instances of `\Traversable`) in properties
|
||||
annotated with `Valid` are not traversed recursively by default anymore.
|
||||
@@ -1353,6 +1352,11 @@
|
||||
decoded twice before. Note that the `urldecode()` calls have been changed for a
|
||||
single `rawurldecode()` in order to support `+` for input paths.
|
||||
|
||||
* Two new parameters have been added to the DIC: `router.request_context.host`
|
||||
and `router.request_context.scheme`. You can customize them for your
|
||||
functional tests or for generating urls with the right host and scheme
|
||||
when your are in the cli context.
|
||||
|
||||
### FrameworkBundle
|
||||
|
||||
* session options: lifetime, path, domain, secure, httponly were deprecated.
|
||||
|
@@ -312,7 +312,7 @@ class EntityChoiceList extends ObjectChoiceList
|
||||
*
|
||||
* Otherwise a new integer is generated.
|
||||
*
|
||||
* @param mixed $choice The choice to create an index for
|
||||
* @param mixed $entity The choice to create an index for
|
||||
*
|
||||
* @return integer|string A unique index containing only ASCII letters,
|
||||
* digits and underscores.
|
||||
@@ -333,7 +333,7 @@ class EntityChoiceList extends ObjectChoiceList
|
||||
*
|
||||
* Otherwise a new integer is generated.
|
||||
*
|
||||
* @param mixed $choice The choice to create a value for
|
||||
* @param mixed $entity The choice to create a value for
|
||||
*
|
||||
* @return integer|string A unique value without character limitations.
|
||||
*/
|
||||
|
@@ -186,8 +186,8 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
|
||||
|
||||
$this->assertSame(array(1 => $entity1, 2 => $entity2), $choiceList->getChoices());
|
||||
$this->assertEquals(array(
|
||||
'group1' => array(1 => new ChoiceView('1', 'Foo')),
|
||||
'group2' => array(2 => new ChoiceView('2', 'Bar'))
|
||||
'group1' => array(1 => new ChoiceView($entity1, '1', 'Foo')),
|
||||
'group2' => array(2 => new ChoiceView($entity2, '2', 'Bar'))
|
||||
), $choiceList->getRemainingViews());
|
||||
}
|
||||
|
||||
@@ -219,9 +219,9 @@ class EntityChoiceListTest extends DoctrineOrmTestCase
|
||||
|
||||
$this->assertEquals(array(1 => $item1, 2 => $item2, 3 => $item3, 4 => $item4), $choiceList->getChoices());
|
||||
$this->assertEquals(array(
|
||||
'Group1' => array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')),
|
||||
'Group2' => array(3 => new ChoiceView('3', 'Baz')),
|
||||
4 => new ChoiceView('4', 'Boo!')
|
||||
'Group1' => array(1 => new ChoiceView($item1, '1', 'Foo'), 2 => new ChoiceView($item2, '2', 'Bar')),
|
||||
'Group2' => array(3 => new ChoiceView($item3, '3', 'Baz')),
|
||||
4 => new ChoiceView($item4, '4', 'Boo!')
|
||||
), $choiceList->getRemainingViews());
|
||||
}
|
||||
|
||||
|
@@ -124,7 +124,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
'property' => 'name'
|
||||
));
|
||||
|
||||
$this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->vars['choices']);
|
||||
$this->assertEquals(array(1 => new ChoiceView($entity1, '1', 'Foo'), 2 => new ChoiceView($entity2, '2', 'Bar')), $field->createView()->vars['choices']);
|
||||
}
|
||||
|
||||
public function testSetDataToUninitializedEntityWithNonRequiredToString()
|
||||
@@ -140,7 +140,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
'required' => false,
|
||||
));
|
||||
|
||||
$this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->vars['choices']);
|
||||
$this->assertEquals(array(1 => new ChoiceView($entity1, '1', 'Foo'), 2 => new ChoiceView($entity2, '2', 'Bar')), $field->createView()->vars['choices']);
|
||||
}
|
||||
|
||||
public function testSetDataToUninitializedEntityWithNonRequiredQueryBuilder()
|
||||
@@ -159,7 +159,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
'query_builder' => $qb
|
||||
));
|
||||
|
||||
$this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->vars['choices']);
|
||||
$this->assertEquals(array(1 => new ChoiceView($entity1, '1', 'Foo'), 2 => new ChoiceView($entity2, '2', 'Bar')), $field->createView()->vars['choices']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -503,7 +503,7 @@ class EntityTypeTest extends TypeTestCase
|
||||
|
||||
$field->bind('2');
|
||||
|
||||
$this->assertEquals(array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')), $field->createView()->vars['choices']);
|
||||
$this->assertEquals(array(1 => new ChoiceView($entity1, '1', 'Foo'), 2 => new ChoiceView($entity2, '2', 'Bar')), $field->createView()->vars['choices']);
|
||||
$this->assertTrue($field->isSynchronized());
|
||||
$this->assertSame($entity2, $field->getData());
|
||||
$this->assertSame('2', $field->getClientData());
|
||||
@@ -530,9 +530,9 @@ class EntityTypeTest extends TypeTestCase
|
||||
|
||||
$this->assertSame('2', $field->getClientData());
|
||||
$this->assertEquals(array(
|
||||
'Group1' => array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')),
|
||||
'Group2' => array(3 => new ChoiceView('3', 'Baz')),
|
||||
'4' => new ChoiceView('4', 'Boo!')
|
||||
'Group1' => array(1 => new ChoiceView($item1, '1', 'Foo'), 2 => new ChoiceView($item2, '2', 'Bar')),
|
||||
'Group2' => array(3 => new ChoiceView($item3, '3', 'Baz')),
|
||||
'4' => new ChoiceView($item4, '4', 'Boo!')
|
||||
), $field->createView()->vars['choices']);
|
||||
}
|
||||
|
||||
|
@@ -75,6 +75,7 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
;
|
||||
$refl = $this->getMockBuilder('Doctrine\Common\Reflection\StaticReflectionProperty')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(array('getValue'))
|
||||
->getMock()
|
||||
;
|
||||
$refl
|
||||
|
@@ -276,7 +276,7 @@ class ModelChoiceList extends ObjectChoiceList
|
||||
*
|
||||
* Otherwise a new integer is generated.
|
||||
*
|
||||
* @param mixed $choice The choice to create an index for
|
||||
* @param mixed $model The choice to create an index for
|
||||
*
|
||||
* @return integer|string A unique index containing only ASCII letters,
|
||||
* digits and underscores.
|
||||
@@ -297,7 +297,7 @@ class ModelChoiceList extends ObjectChoiceList
|
||||
*
|
||||
* Otherwise a new integer is generated.
|
||||
*
|
||||
* @param mixed $choice The choice to create a value for
|
||||
* @param mixed $model The choice to create a value for
|
||||
*
|
||||
* @return integer|string A unique value without character limitations.
|
||||
*/
|
||||
|
@@ -86,8 +86,8 @@ class ModelChoiceListTest extends Propel1TestCase
|
||||
|
||||
$this->assertSame(array(1 => $item1, 2 => $item2), $choiceList->getChoices());
|
||||
$this->assertEquals(array(
|
||||
'group1' => array(1 => new ChoiceView('1', 'Foo')),
|
||||
'group2' => array(2 => new ChoiceView('2', 'Bar'))
|
||||
'group1' => array(1 => new ChoiceView($item1, '1', 'Foo')),
|
||||
'group2' => array(2 => new ChoiceView($item2, '2', 'Bar'))
|
||||
), $choiceList->getRemainingViews());
|
||||
}
|
||||
|
||||
@@ -113,9 +113,9 @@ class ModelChoiceListTest extends Propel1TestCase
|
||||
|
||||
$this->assertEquals(array(1 => $item1, 2 => $item2, 3 => $item3, 4 => $item4), $choiceList->getChoices());
|
||||
$this->assertEquals(array(
|
||||
'Group1' => array(1 => new ChoiceView('1', 'Foo'), 2 => new ChoiceView('2', 'Bar')),
|
||||
'Group2' => array(3 => new ChoiceView('3', 'Baz')),
|
||||
4 => new ChoiceView('4', 'Boo!')
|
||||
'Group1' => array(1 => new ChoiceView($item1, '1', 'Foo'), 2 => new ChoiceView($item2, '2', 'Bar')),
|
||||
'Group2' => array(3 => new ChoiceView($item3, '3', 'Baz')),
|
||||
4 => new ChoiceView($item4, '4', 'Boo!')
|
||||
), $choiceList->getRemainingViews());
|
||||
}
|
||||
|
||||
|
@@ -32,21 +32,71 @@ class SearchAndRenderBlockNode extends \Twig_Node_Expression_Function
|
||||
$compiler->raw(', \'' . $blockNameSuffix . '\'');
|
||||
|
||||
if (isset($arguments[1])) {
|
||||
$compiler->raw(', ');
|
||||
|
||||
// The "label" function allows one extra argument here, the label
|
||||
if ('label' === $blockNameSuffix) {
|
||||
if (isset($arguments[2])) {
|
||||
$compiler->subcompile($arguments[2]);
|
||||
$compiler->raw(' + ');
|
||||
// The "label" function expects the label in the second and
|
||||
// the variables in the third argument
|
||||
$label = $arguments[1];
|
||||
$variables = isset($arguments[2]) ? $arguments[2] : null;
|
||||
$lineno = $label->getLine();
|
||||
|
||||
if ($label instanceof \Twig_Node_Expression_Constant) {
|
||||
// If the label argument is given as a constant, we can either
|
||||
// strip it away if it is empty, or integrate it into the array
|
||||
// of variables at compile time.
|
||||
$labelIsExpression = false;
|
||||
|
||||
// Only insert the label into the array if it is not empty
|
||||
if (!twig_test_empty($label->getAttribute('value'))) {
|
||||
$originalVariables = $variables;
|
||||
$variables = new \Twig_Node_Expression_Array(array(), $lineno);
|
||||
$labelKey = new \Twig_Node_Expression_Constant('label', $lineno);
|
||||
|
||||
if (null !== $originalVariables) {
|
||||
foreach ($originalVariables->getKeyValuePairs() as $pair) {
|
||||
// Don't copy the original label attribute over if it exists
|
||||
if ((string) $labelKey !== (string) $pair['key']) {
|
||||
$variables->addElement($pair['value'], $pair['key']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert the label argument into the array
|
||||
$variables->addElement($label, $labelKey);
|
||||
}
|
||||
} else {
|
||||
// The label argument is not a constant, but some kind of
|
||||
// expression. This expression needs to be evaluated at runtime.
|
||||
// Depending on the result (whether it is null or not), the
|
||||
// label in the arguments should take precedence over the label
|
||||
// in the attributes or not.
|
||||
$labelIsExpression = true;
|
||||
}
|
||||
} else {
|
||||
// All other functions than "label" expect the variables
|
||||
// in the second argument
|
||||
$label = null;
|
||||
$variables = $arguments[1];
|
||||
$labelIsExpression = false;
|
||||
}
|
||||
|
||||
if (null !== $variables || $labelIsExpression) {
|
||||
$compiler->raw(', ');
|
||||
|
||||
if (null !== $variables) {
|
||||
$compiler->subcompile($variables);
|
||||
}
|
||||
|
||||
// Add the label to the variable array
|
||||
$compiler->raw('array(\'label\' => ');
|
||||
$compiler->subcompile($arguments[1]);
|
||||
$compiler->raw(')');
|
||||
} else {
|
||||
$compiler->subcompile($arguments[1]);
|
||||
if ($labelIsExpression) {
|
||||
if (null !== $variables) {
|
||||
$compiler->raw(' + ');
|
||||
}
|
||||
|
||||
// Check at runtime whether the label is empty.
|
||||
// If not, add it to the array at runtime.
|
||||
$compiler->raw('(twig_test_empty($_label_ = ');
|
||||
$compiler->subcompile($label);
|
||||
$compiler->raw(') ? array() : array("label" => $_label_))');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -249,7 +249,7 @@
|
||||
{% block form_row %}
|
||||
{% spaceless %}
|
||||
<div>
|
||||
{{ form_label(form, label|default(null)) }}
|
||||
{{ form_label(form) }}
|
||||
{{ form_errors(form) }}
|
||||
{{ form_widget(form) }}
|
||||
</div>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
{% spaceless %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ form_label(form, label|default(null)) }}
|
||||
{{ form_label(form) }}
|
||||
</td>
|
||||
<td>
|
||||
{{ form_errors(form) }}
|
||||
|
@@ -134,7 +134,7 @@ class FormExtensionDivLayoutTest extends AbstractDivLayoutTest
|
||||
*/
|
||||
public function testIsChoiceSelected($expected, $choice, $value)
|
||||
{
|
||||
$choice = new ChoiceView($choice, $choice . ' label');
|
||||
$choice = new ChoiceView($choice, $choice, $choice . ' label');
|
||||
|
||||
$this->assertSame($expected, $this->extension->isSelectedChoice($choice, $value));
|
||||
}
|
||||
|
282
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php
vendored
Normal file
282
vendor/symfony/symfony/src/Symfony/Bridge/Twig/Tests/Node/SearchAndRenderBlockNodeTest.php
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
<?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\Bridge\Twig\Tests\Node;
|
||||
|
||||
use Symfony\Bridge\Twig\Tests\TestCase;
|
||||
use Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode;
|
||||
|
||||
class SearchAndRenderBlockNodeTest extends TestCase
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if (version_compare(\Twig_Environment::VERSION, '1.5.0', '<')) {
|
||||
$this->markTestSkipped('Requires Twig version to be at least 1.5.0.');
|
||||
}
|
||||
}
|
||||
|
||||
public function testCompileWidget()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_widget', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'widget\')',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompileWidgetWithVariables()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
new \Twig_Node_Expression_Array(array(
|
||||
new \Twig_Node_Expression_Constant('foo', 0),
|
||||
new \Twig_Node_Expression_Constant('bar', 0),
|
||||
), 0),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_widget', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'widget\', array("foo" => "bar"))',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompileLabelWithLabel()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
new \Twig_Node_Expression_Constant('my label', 0),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'label\', array("label" => "my label"))',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompileLabelWithNullLabel()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
new \Twig_Node_Expression_Constant(null, 0),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
// "label" => null must not be included in the output!
|
||||
// Otherwise the default label is overwritten with null.
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'label\')',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompileLabelWithEmptyStringLabel()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
new \Twig_Node_Expression_Constant('', 0),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
// "label" => null must not be included in the output!
|
||||
// Otherwise the default label is overwritten with null.
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'label\')',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompileLabelWithDefaultLabel()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'label\')',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompileLabelWithAttributes()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
new \Twig_Node_Expression_Constant(null, 0),
|
||||
new \Twig_Node_Expression_Array(array(
|
||||
new \Twig_Node_Expression_Constant('foo', 0),
|
||||
new \Twig_Node_Expression_Constant('bar', 0),
|
||||
), 0),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
// "label" => null must not be included in the output!
|
||||
// Otherwise the default label is overwritten with null.
|
||||
// https://github.com/symfony/symfony/issues/5029
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'label\', array("foo" => "bar"))',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompileLabelWithLabelAndAttributes()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
new \Twig_Node_Expression_Constant('value in argument', 0),
|
||||
new \Twig_Node_Expression_Array(array(
|
||||
new \Twig_Node_Expression_Constant('foo', 0),
|
||||
new \Twig_Node_Expression_Constant('bar', 0),
|
||||
new \Twig_Node_Expression_Constant('label', 0),
|
||||
new \Twig_Node_Expression_Constant('value in attributes', 0),
|
||||
), 0),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'label\', array("foo" => "bar", "label" => "value in argument"))',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompileLabelWithLabelThatEvaluatesToNull()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
new \Twig_Node_Expression_Conditional(
|
||||
// if
|
||||
new \Twig_Node_Expression_Constant(true, 0),
|
||||
// then
|
||||
new \Twig_Node_Expression_Constant(null, 0),
|
||||
// else
|
||||
new \Twig_Node_Expression_Constant(null, 0),
|
||||
0
|
||||
),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
// "label" => null must not be included in the output!
|
||||
// Otherwise the default label is overwritten with null.
|
||||
// https://github.com/symfony/symfony/issues/5029
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'label\', (twig_test_empty($_label_ = ((true) ? (null) : (null))) ? array() : array("label" => $_label_)))',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
public function testCompileLabelWithLabelThatEvaluatesToNullAndAttributes()
|
||||
{
|
||||
$arguments = new \Twig_Node(array(
|
||||
new \Twig_Node_Expression_Name('form', 0),
|
||||
new \Twig_Node_Expression_Conditional(
|
||||
// if
|
||||
new \Twig_Node_Expression_Constant(true, 0),
|
||||
// then
|
||||
new \Twig_Node_Expression_Constant(null, 0),
|
||||
// else
|
||||
new \Twig_Node_Expression_Constant(null, 0),
|
||||
0
|
||||
),
|
||||
new \Twig_Node_Expression_Array(array(
|
||||
new \Twig_Node_Expression_Constant('foo', 0),
|
||||
new \Twig_Node_Expression_Constant('bar', 0),
|
||||
new \Twig_Node_Expression_Constant('label', 0),
|
||||
new \Twig_Node_Expression_Constant('value in attributes', 0),
|
||||
), 0),
|
||||
));
|
||||
|
||||
$node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
|
||||
|
||||
$compiler = new \Twig_Compiler(new \Twig_Environment());
|
||||
|
||||
// "label" => null must not be included in the output!
|
||||
// Otherwise the default label is overwritten with null.
|
||||
// https://github.com/symfony/symfony/issues/5029
|
||||
$this->assertEquals(
|
||||
sprintf(
|
||||
'$this->env->getExtension(\'form\')->renderer->searchAndRenderBlock(%s, \'label\', array("foo" => "bar", "label" => "value in attributes") + (twig_test_empty($_label_ = ((true) ? (null) : (null))) ? array() : array("label" => $_label_)))',
|
||||
$this->getVariableGetter('form')
|
||||
),
|
||||
trim($compiler->compile($node)->getSource())
|
||||
);
|
||||
}
|
||||
|
||||
protected function getVariableGetter($name)
|
||||
{
|
||||
if (version_compare(phpversion(), '5.4.0RC1', '>=')) {
|
||||
return sprintf('(isset($context["%s"]) ? $context["%s"] : null)', $name, $name);
|
||||
}
|
||||
|
||||
return sprintf('$this->getContext($context, "%s")', $name);
|
||||
}
|
||||
}
|
@@ -33,7 +33,7 @@ class AssetsInstallCommand extends ContainerAwareCommand
|
||||
$this
|
||||
->setName('assets:install')
|
||||
->setDefinition(array(
|
||||
new InputArgument('target', InputArgument::REQUIRED, 'The target directory (usually "web")'),
|
||||
new InputArgument('target', InputArgument::OPTIONAL, 'The target directory', 'web'),
|
||||
))
|
||||
->addOption('symlink', null, InputOption::VALUE_NONE, 'Symlinks the assets instead of copying it')
|
||||
->addOption('relative', null, InputOption::VALUE_NONE, 'Make relative symlinks')
|
||||
|
@@ -44,7 +44,7 @@ class RegisterKernelListenersPass implements CompilerPassInterface
|
||||
}
|
||||
|
||||
foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) {
|
||||
// We must assume that the class value has been correcly filled, even if the service is created by a factory
|
||||
// We must assume that the class value has been correctly filled, even if the service is created by a factory
|
||||
$class = $container->getDefinition($id)->getClass();
|
||||
|
||||
$refClass = new \ReflectionClass($class);
|
||||
|
@@ -196,9 +196,10 @@ class HttpKernel extends BaseHttpKernel
|
||||
*
|
||||
* This method uses the "_internal" route, which should be available.
|
||||
*
|
||||
* @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI
|
||||
* @param array $attributes An array of request attributes
|
||||
* @param array $query An array of request query parameters
|
||||
* @param string $controller A controller name to execute (a string like BlogBundle:Post:index), or a relative URI
|
||||
* @param array $attributes An array of request attributes
|
||||
* @param array $query An array of request query parameters
|
||||
* @param boolean $secure
|
||||
*
|
||||
* @return string An internal URI
|
||||
*/
|
||||
@@ -226,6 +227,7 @@ class HttpKernel extends BaseHttpKernel
|
||||
* Renders an HInclude tag.
|
||||
*
|
||||
* @param string $uri A URI
|
||||
* @param string $defaultContent Default content
|
||||
*/
|
||||
public function renderHIncludeTag($uri, $defaultContent = null)
|
||||
{
|
||||
|
@@ -5,47 +5,45 @@
|
||||
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
|
||||
|
||||
<parameters>
|
||||
<parameter key="form.extension.class">Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension</parameter>
|
||||
<parameter key="form.resolved_type_factory.class">Symfony\Component\Form\ResolvedFormTypeFactory</parameter>
|
||||
<parameter key="form.registry.class">Symfony\Component\Form\FormRegistry</parameter>
|
||||
<parameter key="form.factory.class">Symfony\Component\Form\FormFactory</parameter>
|
||||
<parameter key="form.extension.class">Symfony\Component\Form\Extension\DependencyInjection\DependencyInjectionExtension</parameter>
|
||||
<parameter key="form.type_guesser.validator.class">Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
<!-- ResolvedFormTypeFactory -->
|
||||
<service id="form.resolved_type_factory" class="%form.resolved_type_factory.class%" />
|
||||
|
||||
<!-- FormRegistry -->
|
||||
<service id="form.registry" class="%form.registry.class%">
|
||||
<argument type="collection">
|
||||
<!--
|
||||
We don't need to be able to add more extensions.
|
||||
* more types can be registered with the form.type tag
|
||||
* more type extensions can be registered with the form.type_extension tag
|
||||
* more type_guessers can be registered with the form.type.type_guesser tag
|
||||
-->
|
||||
<argument type="service" id="form.extension" />
|
||||
</argument>
|
||||
<argument type="service" id="form.resolved_type_factory" />
|
||||
</service>
|
||||
|
||||
<!-- FormFactory -->
|
||||
<service id="form.factory" class="%form.factory.class%">
|
||||
<argument type="service" id="form.registry" />
|
||||
<argument type="service" id="form.resolved_type_factory" />
|
||||
</service>
|
||||
|
||||
<!-- DependencyInjectionExtension -->
|
||||
<service id="form.extension" class="%form.extension.class%" public="false">
|
||||
<argument type="service" id="service_container" />
|
||||
<!--
|
||||
All services with tag "form.type" are inserted here by
|
||||
InitFormsPass
|
||||
-->
|
||||
<!-- All services with tag "form.type" are inserted here by FormPass -->
|
||||
<argument type="collection" />
|
||||
<!--
|
||||
All services with tag "form.type_extension" are inserted here by
|
||||
InitFormsPass
|
||||
-->
|
||||
<!-- All services with tag "form.type_extension" are inserted here by FormPass -->
|
||||
<argument type="collection" />
|
||||
<!--
|
||||
All services with tag "form.type_guesser" are inserted here by
|
||||
InitFormsPass
|
||||
-->
|
||||
<!-- All services with tag "form.type_guesser" are inserted here by FormPass -->
|
||||
<argument type="collection" />
|
||||
</service>
|
||||
|
||||
@@ -138,6 +136,11 @@
|
||||
<tag name="form.type" alias="url" />
|
||||
</service>
|
||||
|
||||
<!-- FormTypeHttpFoundationExtension -->
|
||||
<service id="form.type_extension.form.http_foundation" class="Symfony\Component\Form\Extension\HttpFoundation\Type\FormTypeHttpFoundationExtension">
|
||||
<tag name="form.type_extension" alias="form" />
|
||||
</service>
|
||||
|
||||
<!-- FormTypeValidatorExtension -->
|
||||
<service id="form.type_extension.form.validator" class="Symfony\Component\Form\Extension\Validator\Type\FormTypeValidatorExtension">
|
||||
<tag name="form.type_extension" alias="form" />
|
||||
|
@@ -22,6 +22,8 @@
|
||||
<parameter key="router.options.matcher.cache_class">%kernel.name%%kernel.environment%UrlMatcher</parameter>
|
||||
<parameter key="router.options.generator.cache_class">%kernel.name%%kernel.environment%UrlGenerator</parameter>
|
||||
<parameter key="router_listener.class">Symfony\Component\HttpKernel\EventListener\RouterListener</parameter>
|
||||
<parameter key="router.request_context.host">localhost</parameter>
|
||||
<parameter key="router.request_context.scheme">http</parameter>
|
||||
</parameters>
|
||||
|
||||
<services>
|
||||
@@ -74,8 +76,8 @@
|
||||
<service id="router.request_context" class="%router.request_context.class%" public="false">
|
||||
<argument></argument>
|
||||
<argument>GET</argument>
|
||||
<argument>localhost</argument>
|
||||
<argument>http</argument>
|
||||
<argument>%router.request_context.host%</argument>
|
||||
<argument>%router.request_context.scheme%</argument>
|
||||
<argument>%request_listener.http_port%</argument>
|
||||
<argument>%request_listener.https_port%</argument>
|
||||
</service>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<div>
|
||||
<?php echo $view['form']->label($form, isset($label) ? $label : null) ?>
|
||||
<?php echo $view['form']->label($form) ?>
|
||||
<?php echo $view['form']->errors($form) ?>
|
||||
<?php echo $view['form']->widget($form) ?>
|
||||
</div>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<tr>
|
||||
<td>
|
||||
<?php echo $view['form']->label($form, isset($label) ? $label : null) ?>
|
||||
<?php echo $view['form']->label($form) ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo $view['form']->errors($form) ?>
|
||||
|
@@ -125,7 +125,7 @@ class FormHelper extends Helper
|
||||
*/
|
||||
public function label(FormView $view, $label = null, array $variables = array())
|
||||
{
|
||||
if ($label !== null) {
|
||||
if (null !== $label) {
|
||||
$variables += array('label' => $label);
|
||||
}
|
||||
|
||||
|
@@ -224,6 +224,25 @@ class ClientTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('http://www.example.com/foo', $client->getRequest()->getUri(), '->click() clicks on links');
|
||||
}
|
||||
|
||||
public function testClickForm()
|
||||
{
|
||||
if (!class_exists('Symfony\Component\DomCrawler\Crawler')) {
|
||||
$this->markTestSkipped('The "DomCrawler" component is not available');
|
||||
}
|
||||
|
||||
if (!class_exists('Symfony\Component\CssSelector\CssSelector')) {
|
||||
$this->markTestSkipped('The "CssSelector" component is not available');
|
||||
}
|
||||
|
||||
$client = new TestClient();
|
||||
$client->setNextResponse(new Response('<html><form action="/foo"><input type="submit" /></form></html>'));
|
||||
$crawler = $client->request('GET', 'http://www.example.com/foo/foobar');
|
||||
|
||||
$client->click($crawler->filter('input')->form());
|
||||
|
||||
$this->assertEquals('http://www.example.com/foo', $client->getRequest()->getUri(), '->click() Form submit forms');
|
||||
}
|
||||
|
||||
public function testSubmit()
|
||||
{
|
||||
if (!class_exists('Symfony\Component\DomCrawler\Crawler')) {
|
||||
|
@@ -144,6 +144,29 @@ class CookieJarTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(array('foo' => 'bar%3Dbaz'), $cookieJar->allRawValues('/'));
|
||||
}
|
||||
|
||||
public function testCookieExpireWithSameNameButDifferentPaths()
|
||||
{
|
||||
$cookieJar = new CookieJar();
|
||||
$cookieJar->set($cookie1 = new Cookie('foo', 'bar1', null, '/foo'));
|
||||
$cookieJar->set($cookie2 = new Cookie('foo', 'bar2', null, '/bar'));
|
||||
$cookieJar->expire('foo', '/foo');
|
||||
|
||||
$this->assertNull($cookieJar->get('foo'), '->get() returns null if the cookie is expired');
|
||||
$this->assertEquals(array(), array_keys($cookieJar->allValues('http://example.com/')));
|
||||
$this->assertEquals(array(), $cookieJar->allValues('http://example.com/foo'));
|
||||
$this->assertEquals(array('foo' => 'bar2'), $cookieJar->allValues('http://example.com/bar'));
|
||||
}
|
||||
|
||||
public function testCookieExpireWithNullPaths()
|
||||
{
|
||||
$cookieJar = new CookieJar();
|
||||
$cookieJar->set($cookie1 = new Cookie('foo', 'bar1', null, '/'));
|
||||
$cookieJar->expire('foo', null);
|
||||
|
||||
$this->assertNull($cookieJar->get('foo'), '->get() returns null if the cookie is expired');
|
||||
$this->assertEquals(array(), array_keys($cookieJar->allValues('http://example.com/')));
|
||||
}
|
||||
|
||||
public function testCookieWithSameNameButDifferentPaths()
|
||||
{
|
||||
$cookieJar = new CookieJar();
|
||||
|
@@ -58,6 +58,7 @@ class CookieTest extends \PHPUnit_Framework_TestCase
|
||||
array('foo=bar; expires=Fri, 31 Jul 2020 08:49:37 GMT'),
|
||||
array('foo=bar; expires=Friday, 31-Jul-20 08:49:37 GMT'),
|
||||
array('foo=bar; expires=Fri Jul 31 08:49:37 2020'),
|
||||
array('foo=bar; expires=\'Fri Jul 31 08:49:37 2020\''),
|
||||
);
|
||||
}
|
||||
|
||||
|
@@ -69,7 +69,7 @@ class ArrayNodeDefinitionTest extends \PHPUnit_Framework_TestCase
|
||||
/**
|
||||
* @expectedException Symfony\Component\Config\Definition\Exception\InvalidDefinitionException
|
||||
*/
|
||||
public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaulChildren()
|
||||
public function testPrototypeNodesCantHaveADefaultValueWhenUsingDefaultChildren()
|
||||
{
|
||||
$node = new ArrayNodeDefinition('root');
|
||||
$node
|
||||
|
@@ -200,9 +200,9 @@ class ExprBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* Assert that the given test builder, will return the given value
|
||||
* @param mixed $value The value to test
|
||||
* @param TreeBuilder $test The tree builder to finalize
|
||||
* @param mixed $config The config values that new to be finalized
|
||||
* @param mixed $value The value to test
|
||||
* @param TreeBuilder $treeBuilder The tree builder to finalize
|
||||
* @param mixed $config The config values that new to be finalized
|
||||
*/
|
||||
protected function assertFinalizedValueIs($value, $treeBuilder, $config=null)
|
||||
{
|
||||
|
@@ -90,7 +90,7 @@ class TreeBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
->end();
|
||||
}
|
||||
|
||||
public function testDefinitionInfoGetsTransferedToNode()
|
||||
public function testDefinitionInfoGetsTransferredToNode()
|
||||
{
|
||||
$builder = new TreeBuilder();
|
||||
|
||||
@@ -107,7 +107,7 @@ class TreeBuilderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('child info', $children['child']->getInfo());
|
||||
}
|
||||
|
||||
public function testDefinitionExampleGetsTransferedToNode()
|
||||
public function testDefinitionExampleGetsTransferredToNode()
|
||||
{
|
||||
$builder = new TreeBuilder();
|
||||
|
||||
|
@@ -1041,7 +1041,7 @@ class Application
|
||||
* if nothing is found in $collection, try in $abbrevs
|
||||
*
|
||||
* @param string $name The string
|
||||
* @param array|Traversable $collection The collecion
|
||||
* @param array|Traversable $collection The collection
|
||||
* @param array $abbrevs The abbreviations
|
||||
* @param Closure|string|array $callback The callable to transform collection item before comparison
|
||||
*
|
||||
|
@@ -50,7 +50,7 @@ interface OutputFormatterStyleInterface
|
||||
/**
|
||||
* Unsets some specific style option.
|
||||
*
|
||||
* @param string $option Theoption name
|
||||
* @param string $option The option name
|
||||
*/
|
||||
public function unsetOption($option);
|
||||
|
||||
|
@@ -224,7 +224,7 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$application->add(new \Foo2Command());
|
||||
|
||||
try {
|
||||
$application->find($commandName = 'Unknow command');
|
||||
$application->find($commandName = 'Unknown command');
|
||||
$this->fail('->find() throws an \InvalidArgumentException if command does not exist');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if command does not exist');
|
||||
@@ -264,11 +264,11 @@ class ApplicationTest extends \PHPUnit_Framework_TestCase
|
||||
$application->add(new \foo3Command());
|
||||
|
||||
try {
|
||||
$application->find('Unknow-namespace:Unknow-command');
|
||||
$application->find('Unknown-namespace:Unknown-command');
|
||||
$this->fail('->find() throws an \InvalidArgumentException if namespace does not exist');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\InvalidArgumentException', $e, '->find() throws an \InvalidArgumentException if namespace does not exist');
|
||||
$this->assertEquals('There are no commands defined in the "Unknow-namespace" namespace.', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, without alternatives');
|
||||
$this->assertEquals('There are no commands defined in the "Unknown-namespace" namespace.', $e->getMessage(), '->find() throws an \InvalidArgumentException if namespace does not exist, without alternatives');
|
||||
}
|
||||
|
||||
try {
|
||||
|
@@ -81,7 +81,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isInlinableDefinition($container, $id, $definition = $container->getDefinition($id))) {
|
||||
if ($this->isInlineableDefinition($container, $id, $definition = $container->getDefinition($id))) {
|
||||
$this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId));
|
||||
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope()) {
|
||||
@@ -109,7 +109,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||
*
|
||||
* @return Boolean If the definition is inlineable
|
||||
*/
|
||||
private function isInlinableDefinition(ContainerBuilder $container, $id, Definition $definition)
|
||||
private function isInlineableDefinition(ContainerBuilder $container, $id, Definition $definition)
|
||||
{
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
|
||||
return true;
|
||||
|
@@ -27,9 +27,9 @@ class Filesystem
|
||||
*
|
||||
* By default, if the target already exists, it is not overridden.
|
||||
*
|
||||
* @param string $originFile The original filename
|
||||
* @param string $targetFile The target filename
|
||||
* @param array $override Whether to override an existing file or not
|
||||
* @param string $originFile The original filename
|
||||
* @param string $targetFile The target filename
|
||||
* @param boolean $override Whether to override an existing file or not
|
||||
*
|
||||
* @throws IOException When copy fails
|
||||
*/
|
||||
|
@@ -31,7 +31,7 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
public function setUp()
|
||||
{
|
||||
$this->filesystem = new Filesystem();
|
||||
$this->workspace = sys_get_temp_dir().DIRECTORY_SEPARATOR.time().rand(0, 1000);
|
||||
$this->workspace = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR.time().rand(0, 1000);
|
||||
mkdir($this->workspace, 0777, true);
|
||||
}
|
||||
|
||||
@@ -319,7 +319,7 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
mkdir($basePath);
|
||||
mkdir($basePath.'dir');
|
||||
// create symlink to unexisting file
|
||||
symlink($basePath.'file', $basePath.'link');
|
||||
@symlink($basePath.'file', $basePath.'link');
|
||||
|
||||
$this->filesystem->remove($basePath);
|
||||
|
||||
@@ -388,8 +388,8 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
$this->filesystem->chmod($file, 0400);
|
||||
$this->filesystem->chmod($dir, 0753);
|
||||
|
||||
$this->assertEquals(753, $this->getFilePermisions($dir));
|
||||
$this->assertEquals(400, $this->getFilePermisions($file));
|
||||
$this->assertEquals(753, $this->getFilePermissions($dir));
|
||||
$this->assertEquals(400, $this->getFilePermissions($file));
|
||||
}
|
||||
|
||||
public function testChmodWrongMod()
|
||||
@@ -414,8 +414,8 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
$this->filesystem->chmod($file, 0400, 0000, true);
|
||||
$this->filesystem->chmod($dir, 0753, 0000, true);
|
||||
|
||||
$this->assertEquals(753, $this->getFilePermisions($dir));
|
||||
$this->assertEquals(753, $this->getFilePermisions($file));
|
||||
$this->assertEquals(753, $this->getFilePermissions($dir));
|
||||
$this->assertEquals(753, $this->getFilePermissions($file));
|
||||
}
|
||||
|
||||
public function testChmodAppliesUmask()
|
||||
@@ -426,7 +426,7 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
touch($file);
|
||||
|
||||
$this->filesystem->chmod($file, 0770, 0022);
|
||||
$this->assertEquals(750, $this->getFilePermisions($file));
|
||||
$this->assertEquals(750, $this->getFilePermissions($file));
|
||||
}
|
||||
|
||||
public function testChmodChangesModeOfArrayOfFiles()
|
||||
@@ -442,8 +442,8 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->filesystem->chmod($files, 0753);
|
||||
|
||||
$this->assertEquals(753, $this->getFilePermisions($file));
|
||||
$this->assertEquals(753, $this->getFilePermisions($directory));
|
||||
$this->assertEquals(753, $this->getFilePermissions($file));
|
||||
$this->assertEquals(753, $this->getFilePermissions($directory));
|
||||
}
|
||||
|
||||
public function testChmodChangesModeOfTraversableFileObject()
|
||||
@@ -459,8 +459,8 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->filesystem->chmod($files, 0753);
|
||||
|
||||
$this->assertEquals(753, $this->getFilePermisions($file));
|
||||
$this->assertEquals(753, $this->getFilePermisions($directory));
|
||||
$this->assertEquals(753, $this->getFilePermissions($file));
|
||||
$this->assertEquals(753, $this->getFilePermissions($directory));
|
||||
}
|
||||
|
||||
public function testChown()
|
||||
@@ -701,6 +701,8 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
$link1 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'link';
|
||||
$link2 = $this->workspace.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'subdir'.DIRECTORY_SEPARATOR.'link';
|
||||
|
||||
touch($file);
|
||||
|
||||
$this->filesystem->symlink($file, $link1);
|
||||
$this->filesystem->symlink($file, $link2);
|
||||
|
||||
@@ -830,13 +832,15 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
private function getFilePermisions($filePath)
|
||||
private function getFilePermissions($filePath)
|
||||
{
|
||||
return (int) substr(sprintf('%o', fileperms($filePath)), -3);
|
||||
}
|
||||
|
||||
private function getFileOwner($filepath)
|
||||
{
|
||||
$this->markAsSkippedIfPosixIsMissing();
|
||||
|
||||
$infos = stat($filepath);
|
||||
if ($datas = posix_getpwuid($infos['uid'])) {
|
||||
return $datas['name'];
|
||||
@@ -845,6 +849,8 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
private function getFileGroup($filepath)
|
||||
{
|
||||
$this->markAsSkippedIfPosixIsMissing();
|
||||
|
||||
$infos = stat($filepath);
|
||||
if ($datas = posix_getgrgid($infos['gid'])) {
|
||||
return $datas['name'];
|
||||
@@ -867,8 +873,8 @@ class FilesystemTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
private function markAsSkippedIfPosixIsMissing()
|
||||
{
|
||||
if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
|
||||
$this->markTestSkipped('Posix uids are not available on windows');
|
||||
if (defined('PHP_WINDOWS_VERSION_MAJOR') || !function_exists('posix_isatty')) {
|
||||
$this->markTestSkipped('Posix is not supported');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class CustomFilterIterator extends \FilterIterator
|
||||
class CustomFilterIterator extends FilterIterator
|
||||
{
|
||||
private $filters = array();
|
||||
|
||||
|
@@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class DateRangeFilterIterator extends \FilterIterator
|
||||
class DateRangeFilterIterator extends FilterIterator
|
||||
{
|
||||
private $comparators = array();
|
||||
|
||||
|
@@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class DepthRangeFilterIterator extends \FilterIterator
|
||||
class DepthRangeFilterIterator extends FilterIterator
|
||||
{
|
||||
private $minDepth = 0;
|
||||
|
||||
|
@@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ExcludeDirectoryFilterIterator extends \FilterIterator
|
||||
class ExcludeDirectoryFilterIterator extends FilterIterator
|
||||
{
|
||||
private $patterns;
|
||||
|
||||
|
@@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class FileTypeFilterIterator extends \FilterIterator
|
||||
class FileTypeFilterIterator extends FilterIterator
|
||||
{
|
||||
const ONLY_FILES = 1;
|
||||
const ONLY_DIRECTORIES = 2;
|
||||
|
42
vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/FilterIterator.php
vendored
Normal file
42
vendor/symfony/symfony/src/Symfony/Component/Finder/Iterator/FilterIterator.php
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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\Finder\Iterator;
|
||||
|
||||
/**
|
||||
* This iterator just overrides the rewind method in order to correct a PHP bug.
|
||||
*
|
||||
* @see https://bugs.php.net/bug.php?id=49104
|
||||
*
|
||||
* @author Alex Bogomazov
|
||||
*/
|
||||
abstract class FilterIterator extends \FilterIterator
|
||||
{
|
||||
/**
|
||||
* This is a workaround for the problem with \FilterIterator leaving inner \FilesystemIterator in wrong state after
|
||||
* rewind in some cases.
|
||||
*
|
||||
* @see FilterIterator::rewind()
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$iterator = $this;
|
||||
while ($iterator instanceof \OuterIterator) {
|
||||
if ($iterator->getInnerIterator() instanceof \FilesystemIterator) {
|
||||
$iterator->getInnerIterator()->next();
|
||||
$iterator->getInnerIterator()->rewind();
|
||||
}
|
||||
$iterator = $iterator->getInnerIterator();
|
||||
}
|
||||
|
||||
parent::rewind();
|
||||
}
|
||||
}
|
@@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class MultiplePcreFilterIterator extends \FilterIterator
|
||||
abstract class MultiplePcreFilterIterator extends FilterIterator
|
||||
{
|
||||
protected $matchRegexps;
|
||||
protected $noMatchRegexps;
|
||||
|
@@ -16,7 +16,7 @@ namespace Symfony\Component\Finder\Iterator;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class SizeRangeFilterIterator extends \FilterIterator
|
||||
class SizeRangeFilterIterator extends FilterIterator
|
||||
{
|
||||
private $comparators = array();
|
||||
|
||||
|
@@ -440,4 +440,23 @@ class FinderTest extends Iterator\RealIteratorTestCase
|
||||
$this->assertIterator(array(), $finder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator
|
||||
* with inner FilesystemIterator in an ivalid state.
|
||||
*
|
||||
* @see https://bugs.php.net/bug.php?id=49104
|
||||
*/
|
||||
public function testMultipleLocations()
|
||||
{
|
||||
$locations = array(
|
||||
self::$tmpDir.'/',
|
||||
self::$tmpDir.'/toto/',
|
||||
);
|
||||
|
||||
// it is expected that there are test.py test.php in the tmpDir
|
||||
$finder = new Finder();
|
||||
$finder->in($locations)->depth('< 1')->name('test.php');
|
||||
|
||||
$this->assertEquals(1, count($finder));
|
||||
}
|
||||
}
|
||||
|
@@ -165,12 +165,10 @@ class MockSplFileInfo extends \SplFileInfo
|
||||
if (is_string($type)) {
|
||||
switch ($type) {
|
||||
case 'directory':
|
||||
$this->type = self::TYPE_DIRECTORY;
|
||||
case 'd':
|
||||
$this->type = self::TYPE_DIRECTORY;
|
||||
break;
|
||||
case 'file':
|
||||
$this->type = self::TYPE_FILE;
|
||||
case 'f':
|
||||
$this->type = self::TYPE_FILE;
|
||||
break;
|
||||
|
50
vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php
vendored
Normal file
50
vendor/symfony/symfony/src/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?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\Finder\Tests\Iterator;
|
||||
|
||||
/**
|
||||
* @author Alex Bogomazov
|
||||
*/
|
||||
class FilterIteratorTest extends RealIteratorTestCase
|
||||
{
|
||||
public function testFilterFilesystemIterators()
|
||||
{
|
||||
$i = new \FilesystemIterator(sys_get_temp_dir().'/symfony2_finder');
|
||||
|
||||
// it is expected that there are test.py test.php in the tmpDir
|
||||
$i = $this->getMockForAbstractClass('Symfony\Component\Finder\Iterator\FilterIterator', array($i));
|
||||
$i->expects($this->any())
|
||||
->method('accept')
|
||||
->will($this->returnCallback(function () use ($i) {
|
||||
return (bool) preg_match('/\.php/', (string) $i->current());
|
||||
})
|
||||
);
|
||||
|
||||
$c = 0;
|
||||
foreach ($i as $item) {
|
||||
$c++;
|
||||
}
|
||||
|
||||
$this->assertEquals(1, $c);
|
||||
|
||||
$i->rewind();
|
||||
|
||||
$c = 0;
|
||||
foreach ($i as $item) {
|
||||
$c++;
|
||||
}
|
||||
|
||||
// This would fail with \FilterIterator but works with Symfony\Component\Finder\Iterator\FilterIterator
|
||||
// see https://bugs.php.net/bug.php?id=49104
|
||||
$this->assertEquals(1, $c);
|
||||
}
|
||||
}
|
@@ -21,7 +21,7 @@ abstract class AbstractRendererEngine implements FormRendererEngineInterface
|
||||
/**
|
||||
* The variable in {@link FormView} used as cache key.
|
||||
*/
|
||||
const CACHE_KEY_VAR = 'full_block_name';
|
||||
const CACHE_KEY_VAR = 'cache_key';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
|
@@ -152,12 +152,12 @@ CHANGELOG
|
||||
* deprecated the options "data_timezone" and "user_timezone" in DateType, DateTimeType and TimeType
|
||||
and renamed them to "model_timezone" and "view_timezone"
|
||||
* fixed: TransformationFailedExceptions thrown in the model transformer are now caught by the form
|
||||
* added FormRegistry and ResolvedFormTypeInterface
|
||||
* added FormRegistryInterface, ResolvedFormTypeInterface and ResolvedFormTypeFactoryInterface
|
||||
* deprecated FormFactory methods
|
||||
* `addType`
|
||||
* `hasType`
|
||||
* `getType`
|
||||
* [BC BREAK] FormFactory now expects a FormRegistryInterface as constructor argument
|
||||
* [BC BREAK] FormFactory now expects a FormRegistryInterface and a ResolvedFormTypeFactoryInterface as constructor argument
|
||||
* [BC BREAK] The method `createBuilder` in FormTypeInterface is not supported anymore for performance reasons
|
||||
* [BC BREAK] Removed `setTypes` from FormBuilder
|
||||
* deprecated AbstractType methods
|
||||
@@ -175,3 +175,5 @@ CHANGELOG
|
||||
* `isChoiceSelected`
|
||||
* [BC BREAK] renamed method `renderBlock` in FormHelper to `block` and changed its signature
|
||||
* made FormView properties public and deprecated their accessor methods
|
||||
* made the normalized data of a form accessible in the template through the variable "form.vars.data"
|
||||
* made the original data of a choice accessible in the template through the property "choice.data"
|
||||
|
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\Form\Extension\Core\ChoiceList;
|
||||
|
||||
use Symfony\Component\Form\FormConfig;
|
||||
use Symfony\Component\Form\FormConfigBuilder;
|
||||
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Form\Exception\InvalidConfigurationException;
|
||||
use Symfony\Component\Form\Extension\Core\View\ChoiceView;
|
||||
@@ -20,7 +20,10 @@ use Symfony\Component\Form\Extension\Core\View\ChoiceView;
|
||||
* A choice list for choices of arbitrary data types.
|
||||
*
|
||||
* Choices and labels are passed in two arrays. The indices of the choices
|
||||
* and the labels should match.
|
||||
* and the labels should match. Choices may also be given as hierarchy of
|
||||
* unlimited depth by creating nested arrays. The title of the sub-hierarchy
|
||||
* can be stored in the array key pointing to the nested array. The topmost
|
||||
* level of the hierarchy may also be a \Traversable.
|
||||
*
|
||||
* <code>
|
||||
* $choices = array(true, false);
|
||||
@@ -66,17 +69,24 @@ class ChoiceList implements ChoiceListInterface
|
||||
* Creates a new choice list.
|
||||
*
|
||||
* @param array|\Traversable $choices The array of choices. Choices may also be given
|
||||
* as hierarchy of unlimited depth. Hierarchies are
|
||||
* created by creating nested arrays. The title of
|
||||
* the sub-hierarchy can be stored in the array
|
||||
* key pointing to the nested array.
|
||||
* as hierarchy of unlimited depth. Hierarchies are
|
||||
* created by creating nested arrays. The title of
|
||||
* the sub-hierarchy can be stored in the array
|
||||
* key pointing to the nested array. The topmost
|
||||
* level of the hierarchy may also be a \Traversable.
|
||||
* @param array $labels The array of labels. The structure of this array
|
||||
* should match the structure of $choices.
|
||||
* should match the structure of $choices.
|
||||
* @param array $preferredChoices A flat array of choices that should be
|
||||
* presented to the user with priority.
|
||||
* presented to the user with priority.
|
||||
*
|
||||
* @throws UnexpectedTypeException If the choices are not an array or \Traversable.
|
||||
*/
|
||||
public function __construct($choices, array $labels, array $preferredChoices = array())
|
||||
{
|
||||
if (!is_array($choices) && !$choices instanceof \Traversable) {
|
||||
throw new UnexpectedTypeException($choices, 'array or \Traversable');
|
||||
}
|
||||
|
||||
$this->initialize($choices, $labels, $preferredChoices);
|
||||
}
|
||||
|
||||
@@ -236,22 +246,25 @@ class ChoiceList implements ChoiceListInterface
|
||||
/**
|
||||
* Recursively adds the given choices to the list.
|
||||
*
|
||||
* @param array $bucketForPreferred The bucket where to store the preferred
|
||||
* view objects.
|
||||
* @param array $bucketForRemaining The bucket where to store the
|
||||
* non-preferred view objects.
|
||||
* @param array $choices The list of choices.
|
||||
* @param array $labels The labels corresponding to the choices.
|
||||
* @param array $preferredChoices The preferred choices.
|
||||
* @param array $bucketForPreferred The bucket where to store the preferred
|
||||
* view objects.
|
||||
* @param array $bucketForRemaining The bucket where to store the
|
||||
* non-preferred view objects.
|
||||
* @param array|\Traversable $choices The list of choices.
|
||||
* @param array $labels The labels corresponding to the choices.
|
||||
* @param array $preferredChoices The preferred choices.
|
||||
*
|
||||
* @throws UnexpectedTypeException If the structure of the $labels array
|
||||
* does not match the structure of the
|
||||
* $choices array.
|
||||
* @throws \InvalidArgumentException If the structures of the choices and labels array do not match.
|
||||
* @throws InvalidConfigurationException If no valid value or index could be created for a choice.
|
||||
*/
|
||||
protected function addChoices(&$bucketForPreferred, &$bucketForRemaining, array $choices, array $labels, array $preferredChoices)
|
||||
protected function addChoices(array &$bucketForPreferred, array &$bucketForRemaining, $choices, array $labels, array $preferredChoices)
|
||||
{
|
||||
// Add choices to the nested buckets
|
||||
foreach ($choices as $group => $choice) {
|
||||
if (!isset($labels[$group])) {
|
||||
throw new \InvalidArgumentException('The structures of the choices and labels array do not match.');
|
||||
}
|
||||
|
||||
if (is_array($choice)) {
|
||||
// Don't do the work if the array is empty
|
||||
if (count($choice) > 0) {
|
||||
@@ -281,14 +294,16 @@ class ChoiceList implements ChoiceListInterface
|
||||
*
|
||||
* @param string $group The name of the group.
|
||||
* @param array $bucketForPreferred The bucket where to store the preferred
|
||||
* view objects.
|
||||
* @param array $bucketForRemaining The bucket where to store the
|
||||
* non-preferred view objects.
|
||||
* @param array $choices The list of choices in the group.
|
||||
* @param array $labels The labels corresponding to the choices in the group.
|
||||
* @param array $preferredChoices The preferred choices.
|
||||
* view objects.
|
||||
* @param array $bucketForRemaining The bucket where to store the
|
||||
* non-preferred view objects.
|
||||
* @param array $choices The list of choices in the group.
|
||||
* @param array $labels The labels corresponding to the choices in the group.
|
||||
* @param array $preferredChoices The preferred choices.
|
||||
*
|
||||
* @throws InvalidConfigurationException If no valid value or index could be created for a choice.
|
||||
*/
|
||||
protected function addChoiceGroup($group, &$bucketForPreferred, &$bucketForRemaining, array $choices, array $labels, array $preferredChoices)
|
||||
protected function addChoiceGroup($group, array &$bucketForPreferred, array &$bucketForRemaining, array $choices, array $labels, array $preferredChoices)
|
||||
{
|
||||
// If this is a choice group, create a new level in the choice
|
||||
// key hierarchy
|
||||
@@ -325,11 +340,11 @@ class ChoiceList implements ChoiceListInterface
|
||||
*
|
||||
* @throws InvalidConfigurationException If no valid value or index could be created.
|
||||
*/
|
||||
protected function addChoice(&$bucketForPreferred, &$bucketForRemaining, $choice, $label, array $preferredChoices)
|
||||
protected function addChoice(array &$bucketForPreferred, array &$bucketForRemaining, $choice, $label, array $preferredChoices)
|
||||
{
|
||||
$index = $this->createIndex($choice);
|
||||
|
||||
if ('' === $index || null === $index || !FormConfig::isValidName((string) $index)) {
|
||||
if ('' === $index || null === $index || !FormConfigBuilder::isValidName((string) $index)) {
|
||||
throw new InvalidConfigurationException('The index "' . $index . '" created by the choice list is invalid. It should be a valid, non-empty Form name.');
|
||||
}
|
||||
|
||||
@@ -339,7 +354,7 @@ class ChoiceList implements ChoiceListInterface
|
||||
throw new InvalidConfigurationException('The value created by the choice list is of type "' . gettype($value) . '", but should be a string.');
|
||||
}
|
||||
|
||||
$view = new ChoiceView($value, $label);
|
||||
$view = new ChoiceView($choice, $value, $label);
|
||||
|
||||
$this->choices[$index] = $this->fixChoice($choice);
|
||||
$this->values[$index] = $value;
|
||||
@@ -481,7 +496,7 @@ class ChoiceList implements ChoiceListInterface
|
||||
/**
|
||||
* Fixes the data type of the given choices to avoid comparison problems.
|
||||
*
|
||||
* @param array $choice The choices.
|
||||
* @param array $choices The choices.
|
||||
*
|
||||
* @return array The fixed choices.
|
||||
*
|
||||
|
@@ -13,7 +13,6 @@ namespace Symfony\Component\Form\Extension\Core\ChoiceList;
|
||||
|
||||
use Symfony\Component\Form\Util\PropertyPath;
|
||||
use Symfony\Component\Form\Exception\StringCastException;
|
||||
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Form\Exception\InvalidPropertyException;
|
||||
|
||||
/**
|
||||
@@ -57,11 +56,12 @@ class ObjectChoiceList extends ChoiceList
|
||||
/**
|
||||
* Creates a new object choice list.
|
||||
*
|
||||
* @param array $choices The array of choices. Choices may also be given
|
||||
* as hierarchy of unlimited depth. Hierarchies are
|
||||
* created by creating nested arrays. The title of
|
||||
* the sub-hierarchy can be stored in the array
|
||||
* key pointing to the nested array.
|
||||
* @param array|\Traversable $choices The array of choices. Choices may also be given
|
||||
* as hierarchy of unlimited depth by creating nested
|
||||
* arrays. The title of the sub-hierarchy can be
|
||||
* stored in the array key pointing to the nested
|
||||
* array. The topmost level of the hierarchy may also
|
||||
* be a \Traversable.
|
||||
* @param string $labelPath A property path pointing to the property used
|
||||
* for the choice labels. The value is obtained
|
||||
* by calling the getter on the object. If the
|
||||
@@ -78,9 +78,9 @@ class ObjectChoiceList extends ChoiceList
|
||||
*/
|
||||
public function __construct($choices, $labelPath = null, array $preferredChoices = array(), $groupPath = null, $valuePath = null)
|
||||
{
|
||||
$this->labelPath = $labelPath ? new PropertyPath($labelPath) : null;
|
||||
$this->groupPath = $groupPath ? new PropertyPath($groupPath) : null;
|
||||
$this->valuePath = $valuePath ? new PropertyPath($valuePath) : null;
|
||||
$this->labelPath = null !== $labelPath ? new PropertyPath($labelPath) : null;
|
||||
$this->groupPath = null !== $groupPath ? new PropertyPath($groupPath) : null;
|
||||
$this->valuePath = null !== $valuePath ? new PropertyPath($valuePath) : null;
|
||||
|
||||
parent::__construct($choices, array(), $preferredChoices);
|
||||
}
|
||||
@@ -93,19 +93,18 @@ class ObjectChoiceList extends ChoiceList
|
||||
* @param array|\Traversable $choices The choices to write into the list.
|
||||
* @param array $labels Ignored.
|
||||
* @param array $preferredChoices The choices to display with priority.
|
||||
*
|
||||
* @throws \InvalidArgumentException When passing a hierarchy of choices and using
|
||||
* the "groupPath" option at the same time.
|
||||
*/
|
||||
protected function initialize($choices, array $labels, array $preferredChoices)
|
||||
{
|
||||
if (!is_array($choices) && !$choices instanceof \Traversable) {
|
||||
throw new UnexpectedTypeException($choices, 'array or \Traversable');
|
||||
}
|
||||
|
||||
if (null !== $this->groupPath) {
|
||||
$groupedChoices = array();
|
||||
|
||||
foreach ($choices as $i => $choice) {
|
||||
if (is_array($choice)) {
|
||||
throw new \InvalidArgumentException('You should pass a plain object array (without groups, $code, $previous) when using the "groupPath" option');
|
||||
throw new \InvalidArgumentException('You should pass a plain object array (without groups) when using the "groupPath" option.');
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -142,10 +141,10 @@ class ObjectChoiceList extends ChoiceList
|
||||
*
|
||||
* If a property path for the value was given at object creation,
|
||||
* the getter behind that path is now called to obtain a new value.
|
||||
*
|
||||
* Otherwise a new integer is generated.
|
||||
*
|
||||
* @param mixed $choice The choice to create a value for
|
||||
*
|
||||
* @return integer|string A unique value without character limitations.
|
||||
*/
|
||||
protected function createValue($choice)
|
||||
@@ -160,7 +159,7 @@ class ObjectChoiceList extends ChoiceList
|
||||
private function extractLabels($choices, array &$labels)
|
||||
{
|
||||
foreach ($choices as $i => $choice) {
|
||||
if (is_array($choice) || $choice instanceof \Traversable) {
|
||||
if (is_array($choice)) {
|
||||
$labels[$i] = array();
|
||||
$this->extractLabels($choice, $labels[$i]);
|
||||
} elseif ($this->labelPath) {
|
||||
|
@@ -11,14 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\Form\Extension\Core\ChoiceList;
|
||||
|
||||
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||
|
||||
/**
|
||||
* A choice list for choices of type string or integer.
|
||||
*
|
||||
* Choices and their associated labels can be passed in a single array. Since
|
||||
* choices are passed as array keys, only strings or integer choices are
|
||||
* allowed.
|
||||
* allowed. Choices may also be given as hierarchy of unlimited depth by
|
||||
* creating nested arrays. The title of the sub-hierarchy can be stored in the
|
||||
* array key pointing to the nested array.
|
||||
*
|
||||
* <code>
|
||||
* $choiceList = new SimpleChoiceList(array(
|
||||
@@ -35,13 +35,12 @@ class SimpleChoiceList extends ChoiceList
|
||||
* Creates a new simple choice list.
|
||||
*
|
||||
* @param array $choices The array of choices with the choices as keys and
|
||||
* the labels as values. Choices may also be given
|
||||
* as hierarchy of unlimited depth. Hierarchies are
|
||||
* created by creating nested arrays. The title of
|
||||
* the sub-hierarchy is stored in the array
|
||||
* key pointing to the nested array.
|
||||
* the labels as values. Choices may also be given
|
||||
* as hierarchy of unlimited depth by creating nested
|
||||
* arrays. The title of the sub-hierarchy is stored
|
||||
* in the array key pointing to the nested array.
|
||||
* @param array $preferredChoices A flat array of choices that should be
|
||||
* presented to the user with priority.
|
||||
* presented to the user with priority.
|
||||
*/
|
||||
public function __construct(array $choices, array $preferredChoices = array())
|
||||
{
|
||||
@@ -79,17 +78,15 @@ class SimpleChoiceList extends ChoiceList
|
||||
* Takes care of splitting the single $choices array passed in the
|
||||
* constructor into choices and labels.
|
||||
*
|
||||
* @param array $bucketForPreferred
|
||||
* @param array $bucketForRemaining
|
||||
* @param array $choices
|
||||
* @param array $labels
|
||||
* @param array $preferredChoices
|
||||
*
|
||||
* @throws UnexpectedTypeException
|
||||
*
|
||||
* @see parent::addChoices
|
||||
* @param array $bucketForPreferred The bucket where to store the preferred
|
||||
* view objects.
|
||||
* @param array $bucketForRemaining The bucket where to store the
|
||||
* non-preferred view objects.
|
||||
* @param array|\Traversable $choices The list of choices.
|
||||
* @param array $labels Ignored.
|
||||
* @param array $preferredChoices The preferred choices.
|
||||
*/
|
||||
protected function addChoices(&$bucketForPreferred, &$bucketForRemaining, array $choices, array $labels, array $preferredChoices)
|
||||
protected function addChoices(array &$bucketForPreferred, array &$bucketForRemaining, $choices, array $labels, array $preferredChoices)
|
||||
{
|
||||
// Add choices to the nested buckets
|
||||
foreach ($choices as $choice => $label) {
|
||||
|
@@ -11,7 +11,6 @@
|
||||
|
||||
namespace Symfony\Component\Form\Extension\Core;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\Type;
|
||||
use Symfony\Component\Form\AbstractExtension;
|
||||
|
||||
/**
|
||||
|
@@ -17,7 +17,6 @@ use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\Extension\Core\EventListener\BindRequestListener;
|
||||
use Symfony\Component\Form\Extension\Core\EventListener\TrimListener;
|
||||
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
|
||||
use Symfony\Component\Form\Exception\FormException;
|
||||
@@ -45,7 +44,6 @@ class FormType extends AbstractType
|
||||
->setData(isset($options['data']) ? $options['data'] : null)
|
||||
->setDataLocked(isset($options['data']))
|
||||
->setDataMapper($options['compound'] ? new PropertyPathMapper() : null)
|
||||
->addEventSubscriber(new BindRequestListener())
|
||||
;
|
||||
|
||||
if ($options['trim']) {
|
||||
@@ -71,11 +69,11 @@ class FormType extends AbstractType
|
||||
if ('' !== ($parentFullName = $view->parent->vars['full_name'])) {
|
||||
$id = sprintf('%s_%s', $view->parent->vars['id'], $name);
|
||||
$fullName = sprintf('%s[%s]', $parentFullName, $name);
|
||||
$fullBlockName = sprintf('%s_%s', $view->parent->vars['full_block_name'], $blockName);
|
||||
$uniqueBlockPrefix = sprintf('%s_%s', $view->parent->vars['unique_block_prefix'], $blockName);
|
||||
} else {
|
||||
$id = $name;
|
||||
$fullName = $name;
|
||||
$fullBlockName = '_' . $blockName;
|
||||
$uniqueBlockPrefix = '_' . $blockName;
|
||||
}
|
||||
|
||||
// Complex fields are read-only if they themselves or their parents are.
|
||||
@@ -89,7 +87,7 @@ class FormType extends AbstractType
|
||||
} else {
|
||||
$id = $name;
|
||||
$fullName = $name;
|
||||
$fullBlockName = '_' . $blockName;
|
||||
$uniqueBlockPrefix = '_' . $blockName;
|
||||
|
||||
// Strip leading underscores and digits. These are allowed in
|
||||
// form names, but not in HTML4 ID attributes.
|
||||
@@ -97,37 +95,46 @@ class FormType extends AbstractType
|
||||
$id = ltrim($id, '_0123456789');
|
||||
}
|
||||
|
||||
$types = array();
|
||||
$blockPrefixes = array();
|
||||
for ($type = $form->getConfig()->getType(); null !== $type; $type = $type->getParent()) {
|
||||
array_unshift($types, $type->getName());
|
||||
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,
|
||||
'full_block_name' => $fullBlockName,
|
||||
'read_only' => $readOnly,
|
||||
'errors' => $form->getErrors(),
|
||||
'valid' => $form->isBound() ? $form->isValid() : true,
|
||||
'value' => $form->getViewData(),
|
||||
'disabled' => $form->isDisabled(),
|
||||
'required' => $form->isRequired(),
|
||||
'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(),
|
||||
'types' => $types,
|
||||
'translation_domain' => $translationDomain,
|
||||
'form' => $view,
|
||||
'id' => $id,
|
||||
'name' => $name,
|
||||
'full_name' => $fullName,
|
||||
'read_only' => $readOnly,
|
||||
'errors' => $form->getErrors(),
|
||||
'valid' => $form->isBound() ? $form->isValid() : true,
|
||||
'value' => $form->getViewData(),
|
||||
'data' => $form->getNormData(),
|
||||
'disabled' => $form->isDisabled(),
|
||||
'required' => $form->isRequired(),
|
||||
'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(),
|
||||
));
|
||||
}
|
||||
|
||||
|
@@ -18,6 +18,13 @@ namespace Symfony\Component\Form\Extension\Core\View;
|
||||
*/
|
||||
class ChoiceView
|
||||
{
|
||||
/**
|
||||
* The original choice value.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $data;
|
||||
|
||||
/**
|
||||
* The view representation of the choice.
|
||||
*
|
||||
@@ -35,11 +42,13 @@ class ChoiceView
|
||||
/**
|
||||
* Creates a new ChoiceView.
|
||||
*
|
||||
* @param mixed $data The original choice.
|
||||
* @param string $value The view representation of the choice.
|
||||
* @param string $label The label displayed to humans.
|
||||
*/
|
||||
public function __construct($value, $label)
|
||||
public function __construct($data, $value, $label)
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->value = $value;
|
||||
$this->label = $label;
|
||||
}
|
||||
|
@@ -56,8 +56,9 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
|
||||
/**
|
||||
* Adds a CSRF field to the root form view.
|
||||
*
|
||||
* @param FormView $view The form view
|
||||
* @param FormInterface $form The form
|
||||
* @param FormView $view The form view
|
||||
* @param FormInterface $form The form
|
||||
* @param array $options The options
|
||||
*/
|
||||
public function finishView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
|
@@ -9,7 +9,7 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form\Extension\Core\EventListener;
|
||||
namespace Symfony\Component\Form\Extension\HttpFoundation\EventListener;
|
||||
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormEvent;
|
@@ -0,0 +1,29 @@
|
||||
<?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\HttpFoundation;
|
||||
|
||||
use Symfony\Component\Form\AbstractExtension;
|
||||
|
||||
/**
|
||||
* Integrates the HttpFoundation component with the Form library.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class HttpFoundationExtension extends AbstractExtension
|
||||
{
|
||||
protected function loadTypes()
|
||||
{
|
||||
return array(
|
||||
new Type\FormTypeHttpFoundationExtension(),
|
||||
);
|
||||
}
|
||||
}
|
@@ -0,0 +1,50 @@
|
||||
<?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\HttpFoundation\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractTypeExtension;
|
||||
use Symfony\Component\Form\Extension\HttpFoundation\EventListener\BindRequestListener;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class FormTypeHttpFoundationExtension extends AbstractTypeExtension
|
||||
{
|
||||
/**
|
||||
* @var BindRequestListener
|
||||
*/
|
||||
private $listener;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->listener = new BindRequestListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$builder->addEventSubscriber($this->listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getExtendedType()
|
||||
{
|
||||
return 'form';
|
||||
}
|
||||
}
|
@@ -125,10 +125,10 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
||||
return new TypeGuess('country', array(), Guess::HIGH_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Date':
|
||||
return new TypeGuess('date', array('type' => 'string'), Guess::HIGH_CONFIDENCE);
|
||||
return new TypeGuess('date', array('input' => 'string'), Guess::HIGH_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\DateTime':
|
||||
return new TypeGuess('datetime', array('type' => 'string'), Guess::HIGH_CONFIDENCE);
|
||||
return new TypeGuess('datetime', array('input' => 'string'), Guess::HIGH_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Email':
|
||||
return new TypeGuess('email', array(), Guess::HIGH_CONFIDENCE);
|
||||
@@ -144,7 +144,7 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
||||
return new TypeGuess('locale', array(), Guess::HIGH_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Time':
|
||||
return new TypeGuess('time', array('type' => 'string'), Guess::HIGH_CONFIDENCE);
|
||||
return new TypeGuess('time', array('input' => 'string'), Guess::HIGH_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Url':
|
||||
return new TypeGuess('url', array(), Guess::HIGH_CONFIDENCE);
|
||||
@@ -157,7 +157,6 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
||||
case 'Symfony\Component\Validator\Constraints\Regex':
|
||||
return new TypeGuess('text', array(), Guess::LOW_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Size':
|
||||
case 'Symfony\Component\Validator\Constraints\Min':
|
||||
case 'Symfony\Component\Validator\Constraints\Max':
|
||||
return new TypeGuess('number', array(), Guess::LOW_CONFIDENCE);
|
||||
@@ -220,9 +219,6 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Max':
|
||||
return new ValueGuess(strlen((string) $constraint->limit), Guess::LOW_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Size':
|
||||
return new ValueGuess(strlen((string) $constraint->max), Guess::LOW_CONFIDENCE);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -252,9 +248,6 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
||||
case 'Symfony\Component\Validator\Constraints\Min':
|
||||
return new ValueGuess(sprintf('.{%s,}', strlen((string) $constraint->limit)), Guess::LOW_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Size':
|
||||
return new ValueGuess(sprintf('.{%s,%s}', strlen((string) $constraint->min), strlen((string) $constraint->max)), Guess::LOW_CONFIDENCE);
|
||||
|
||||
case 'Symfony\Component\Validator\Constraints\Type':
|
||||
if (in_array($constraint->type, array('double', 'float', 'numeric', 'real'))) {
|
||||
return new ValueGuess(null, Guess::MEDIUM_CONFIDENCE);
|
||||
@@ -269,12 +262,12 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
||||
* Iterates over the constraints of a property, executes a constraints on
|
||||
* them and returns the best guess
|
||||
*
|
||||
* @param string $class The class to read the constraints from
|
||||
* @param string $property The property for which to find constraints
|
||||
* @param \Closure $closure The closure that returns a guess
|
||||
* for a given constraint
|
||||
* @param mixed $default The default value assumed if no other value
|
||||
* can be guessed.
|
||||
* @param string $class The class to read the constraints from
|
||||
* @param string $property The property for which to find constraints
|
||||
* @param \Closure $closure The closure that returns a guess
|
||||
* for a given constraint
|
||||
* @param mixed $defaultValue The default value assumed if no other value
|
||||
* can be guessed.
|
||||
*
|
||||
* @return Guess The guessed value with the highest confidence
|
||||
*/
|
||||
|
@@ -146,10 +146,6 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
*/
|
||||
public function __construct(FormConfigInterface $config)
|
||||
{
|
||||
if (!$config instanceof ImmutableFormConfig) {
|
||||
$config = new ImmutableFormConfig($config);
|
||||
}
|
||||
|
||||
// Compound forms always need a data mapper, otherwise calls to
|
||||
// `setData` and `add` will not lead to the correct population of
|
||||
// the child forms.
|
||||
@@ -170,7 +166,7 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
/**
|
||||
* Returns the configuration of the form.
|
||||
*
|
||||
* @return ImmutableFormConfig The form's immutable configuration.
|
||||
* @return FormConfigInterface The form's configuration.
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
@@ -372,13 +368,16 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
}
|
||||
|
||||
$this->lockSetData = true;
|
||||
$dispatcher = $this->config->getEventDispatcher();
|
||||
|
||||
// Hook to change content of the data
|
||||
$event = new FormEvent($this, $modelData);
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::PRE_SET_DATA, $event);
|
||||
// BC until 2.3
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::SET_DATA, $event);
|
||||
$modelData = $event->getData();
|
||||
if ($dispatcher->hasListeners(FormEvents::PRE_SET_DATA) || $dispatcher->hasListeners(FormEvents::SET_DATA)) {
|
||||
$event = new FormEvent($this, $modelData);
|
||||
$dispatcher->dispatch(FormEvents::PRE_SET_DATA, $event);
|
||||
// BC until 2.3
|
||||
$dispatcher->dispatch(FormEvents::SET_DATA, $event);
|
||||
$modelData = $event->getData();
|
||||
}
|
||||
|
||||
// Treat data as strings unless a value transformer exists
|
||||
if (!$this->config->getViewTransformers() && !$this->config->getModelTransformers() && is_scalar($modelData)) {
|
||||
@@ -432,8 +431,10 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
$this->config->getDataMapper()->mapDataToForms($viewData, $this->children);
|
||||
}
|
||||
|
||||
$event = new FormEvent($this, $modelData);
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::POST_SET_DATA, $event);
|
||||
if ($dispatcher->hasListeners(FormEvents::POST_SET_DATA)) {
|
||||
$event = new FormEvent($this, $modelData);
|
||||
$dispatcher->dispatch(FormEvents::POST_SET_DATA, $event);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -526,6 +527,13 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
// The data must be initialized if it was not initialized yet.
|
||||
// This is necessary to guarantee that the *_SET_DATA listeners
|
||||
// are always invoked before bind() takes place.
|
||||
if (!$this->initialized) {
|
||||
$this->setData($this->config->getData());
|
||||
}
|
||||
|
||||
// Don't convert NULL to a string here in order to determine later
|
||||
// whether an empty value has been submitted or whether no value has
|
||||
// been submitted at all. This is important for processing checkboxes
|
||||
@@ -542,13 +550,16 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
$normData = null;
|
||||
$extraData = array();
|
||||
$synchronized = false;
|
||||
$dispatcher = $this->config->getEventDispatcher();
|
||||
|
||||
// Hook to change content of the data bound by the browser
|
||||
$event = new FormEvent($this, $submittedData);
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::PRE_BIND, $event);
|
||||
// BC until 2.3
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::BIND_CLIENT_DATA, $event);
|
||||
$submittedData = $event->getData();
|
||||
if ($dispatcher->hasListeners(FormEvents::PRE_BIND) || $dispatcher->hasListeners(FormEvents::BIND_CLIENT_DATA)) {
|
||||
$event = new FormEvent($this, $submittedData);
|
||||
$dispatcher->dispatch(FormEvents::PRE_BIND, $event);
|
||||
// BC until 2.3
|
||||
$dispatcher->dispatch(FormEvents::BIND_CLIENT_DATA, $event);
|
||||
$submittedData = $event->getData();
|
||||
}
|
||||
|
||||
// By default, the submitted data is also the data in view format
|
||||
$viewData = $submittedData;
|
||||
@@ -610,11 +621,13 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
|
||||
// Hook to change content of the data into the normalized
|
||||
// representation
|
||||
$event = new FormEvent($this, $normData);
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::BIND, $event);
|
||||
// BC until 2.3
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::BIND_NORM_DATA, $event);
|
||||
$normData = $event->getData();
|
||||
if ($dispatcher->hasListeners(FormEvents::BIND) || $dispatcher->hasListeners(FormEvents::BIND_NORM_DATA)) {
|
||||
$event = new FormEvent($this, $normData);
|
||||
$dispatcher->dispatch(FormEvents::BIND, $event);
|
||||
// BC until 2.3
|
||||
$dispatcher->dispatch(FormEvents::BIND_NORM_DATA, $event);
|
||||
$normData = $event->getData();
|
||||
}
|
||||
|
||||
// Synchronize representations - must not change the content!
|
||||
$modelData = $this->normToModel($normData);
|
||||
@@ -630,10 +643,11 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
$this->viewData = $viewData;
|
||||
$this->extraData = $extraData;
|
||||
$this->synchronized = $synchronized;
|
||||
$this->initialized = true;
|
||||
|
||||
$event = new FormEvent($this, $viewData);
|
||||
$this->config->getEventDispatcher()->dispatch(FormEvents::POST_BIND, $event);
|
||||
if ($dispatcher->hasListeners(FormEvents::POST_BIND)) {
|
||||
$event = new FormEvent($this, $viewData);
|
||||
$dispatcher->dispatch(FormEvents::POST_BIND, $event);
|
||||
}
|
||||
|
||||
foreach ($this->config->getValidators() as $validator) {
|
||||
$validator->validate($this);
|
||||
|
@@ -20,7 +20,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class FormBuilder extends FormConfig implements \IteratorAggregate, FormBuilderInterface
|
||||
class FormBuilder extends FormConfigBuilder implements \IteratorAggregate, FormBuilderInterface
|
||||
{
|
||||
/**
|
||||
* The form factory.
|
||||
@@ -56,6 +56,7 @@ class FormBuilder extends FormConfig implements \IteratorAggregate, FormBuilderI
|
||||
* @param string $dataClass
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
* @param FormFactoryInterface $factory
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct($name, $dataClass, EventDispatcherInterface $dispatcher, FormFactoryInterface $factory, array $options = array())
|
||||
{
|
||||
@@ -77,6 +78,10 @@ class FormBuilder extends FormConfig implements \IteratorAggregate, FormBuilderI
|
||||
*/
|
||||
public function add($child, $type = null, array $options = array())
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The form builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
if ($child instanceof self) {
|
||||
$child->setParent($this);
|
||||
$this->children[$child->getName()] = $child;
|
||||
@@ -110,6 +115,10 @@ class FormBuilder extends FormConfig implements \IteratorAggregate, FormBuilderI
|
||||
*/
|
||||
public function create($name, $type = null, array $options = array())
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The form builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
if (null === $type && null === $this->getDataClass()) {
|
||||
$type = 'text';
|
||||
}
|
||||
@@ -142,6 +151,10 @@ class FormBuilder extends FormConfig implements \IteratorAggregate, FormBuilderI
|
||||
*/
|
||||
public function remove($name)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The form builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
unset($this->unresolvedChildren[$name]);
|
||||
|
||||
if (array_key_exists($name, $this->children)) {
|
||||
@@ -195,7 +208,7 @@ class FormBuilder extends FormConfig implements \IteratorAggregate, FormBuilderI
|
||||
{
|
||||
$this->resolveChildren();
|
||||
|
||||
$form = new Form($this);
|
||||
$form = new Form($this->getFormConfig());
|
||||
|
||||
foreach ($this->children as $child) {
|
||||
$form->add($child->getForm());
|
||||
@@ -217,6 +230,10 @@ class FormBuilder extends FormConfig implements \IteratorAggregate, FormBuilderI
|
||||
*/
|
||||
public function setParent(FormBuilderInterface $parent = null)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The form builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->parent = $parent;
|
||||
|
||||
return $this;
|
||||
|
@@ -14,7 +14,7 @@ namespace Symfony\Component\Form;
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
interface FormBuilderInterface extends FormConfigEditorInterface, \Traversable, \Countable
|
||||
interface FormBuilderInterface extends \Traversable, \Countable, FormConfigBuilderInterface
|
||||
{
|
||||
/**
|
||||
* Adds a new field to this group. A field must have a unique name within
|
||||
|
@@ -11,18 +11,25 @@
|
||||
|
||||
namespace Symfony\Component\Form;
|
||||
|
||||
use Symfony\Component\Form\Exception\FormException;
|
||||
use Symfony\Component\Form\Exception\UnexpectedTypeException;
|
||||
use Symfony\Component\Form\Util\PropertyPath;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\EventDispatcher\ImmutableEventDispatcher;
|
||||
|
||||
/**
|
||||
* A basic form configuration.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class FormConfig implements FormConfigEditorInterface
|
||||
class FormConfigBuilder implements FormConfigBuilderInterface
|
||||
{
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
protected $locked = false;
|
||||
|
||||
/**
|
||||
* @var EventDispatcherInterface
|
||||
*/
|
||||
@@ -161,6 +168,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function addEventListener($eventName, $listener, $priority = 0)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->dispatcher->addListener($eventName, $listener, $priority);
|
||||
|
||||
return $this;
|
||||
@@ -171,6 +182,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function addEventSubscriber(EventSubscriberInterface $subscriber)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->dispatcher->addSubscriber($subscriber);
|
||||
|
||||
return $this;
|
||||
@@ -181,6 +196,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function addValidator(FormValidatorInterface $validator)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->validators[] = $validator;
|
||||
|
||||
return $this;
|
||||
@@ -191,6 +210,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function addViewTransformer(DataTransformerInterface $viewTransformer, $forcePrepend = false)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
if ($forcePrepend) {
|
||||
array_unshift($this->viewTransformers, $viewTransformer);
|
||||
} else {
|
||||
@@ -205,6 +228,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function resetViewTransformers()
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->viewTransformers = array();
|
||||
|
||||
return $this;
|
||||
@@ -215,13 +242,17 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*
|
||||
* @param DataTransformerInterface $viewTransformer
|
||||
*
|
||||
* @return self The configuration object.
|
||||
* @return FormConfigBuilder The configuration object.
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* {@link addViewTransformer()} instead.
|
||||
*/
|
||||
public function appendClientTransformer(DataTransformerInterface $viewTransformer)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
return $this->addViewTransformer($viewTransformer);
|
||||
}
|
||||
|
||||
@@ -230,25 +261,33 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*
|
||||
* @param DataTransformerInterface $viewTransformer
|
||||
*
|
||||
* @return self The configuration object.
|
||||
* @return FormConfigBuilder The configuration object.
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
|
||||
*/
|
||||
public function prependClientTransformer(DataTransformerInterface $viewTransformer)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
return $this->addViewTransformer($viewTransformer, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of {@link resetViewTransformers()}.
|
||||
*
|
||||
* @return self The configuration object.
|
||||
* @return FormConfigBuilder The configuration object.
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* {@link resetViewTransformers()} instead.
|
||||
*/
|
||||
public function resetClientTransformers()
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
return $this->resetViewTransformers();
|
||||
}
|
||||
|
||||
@@ -257,6 +296,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function addModelTransformer(DataTransformerInterface $modelTransformer, $forceAppend = false)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
if ($forceAppend) {
|
||||
$this->modelTransformers[] = $modelTransformer;
|
||||
} else {
|
||||
@@ -271,6 +314,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function resetModelTransformers()
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->modelTransformers = array();
|
||||
|
||||
return $this;
|
||||
@@ -281,12 +328,16 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*
|
||||
* @param DataTransformerInterface $modelTransformer
|
||||
*
|
||||
* @return self The configuration object.
|
||||
* @return FormConfigBuilder The configuration object.
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3.
|
||||
*/
|
||||
public function appendNormTransformer(DataTransformerInterface $modelTransformer)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
return $this->addModelTransformer($modelTransformer, true);
|
||||
}
|
||||
|
||||
@@ -295,26 +346,34 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*
|
||||
* @param DataTransformerInterface $modelTransformer
|
||||
*
|
||||
* @return self The configuration object.
|
||||
* @return FormConfigBuilder The configuration object.
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* {@link addModelTransformer()} instead.
|
||||
*/
|
||||
public function prependNormTransformer(DataTransformerInterface $modelTransformer)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
return $this->addModelTransformer($modelTransformer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias of {@link resetModelTransformers()}.
|
||||
*
|
||||
* @return self The configuration object.
|
||||
* @return FormConfigBuilder The configuration object.
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* {@link resetModelTransformers()} instead.
|
||||
*/
|
||||
public function resetNormTransformers()
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
return $this->resetModelTransformers();
|
||||
}
|
||||
|
||||
@@ -549,6 +608,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this;
|
||||
@@ -559,6 +622,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setAttributes(array $attributes)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->attributes = $attributes;
|
||||
|
||||
return $this;
|
||||
@@ -569,6 +636,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setDataMapper(DataMapperInterface $dataMapper = null)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->dataMapper = $dataMapper;
|
||||
|
||||
return $this;
|
||||
@@ -579,6 +650,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setDisabled($disabled)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->disabled = (Boolean) $disabled;
|
||||
|
||||
return $this;
|
||||
@@ -589,6 +664,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setEmptyData($emptyData)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->emptyData = $emptyData;
|
||||
|
||||
return $this;
|
||||
@@ -599,6 +678,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setErrorBubbling($errorBubbling)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->errorBubbling = null === $errorBubbling ? null : (Boolean) $errorBubbling;
|
||||
|
||||
return $this;
|
||||
@@ -609,6 +692,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setRequired($required)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->required = (Boolean) $required;
|
||||
|
||||
return $this;
|
||||
@@ -619,6 +706,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setPropertyPath($propertyPath)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
if (null !== $propertyPath && !$propertyPath instanceof PropertyPath) {
|
||||
$propertyPath = new PropertyPath($propertyPath);
|
||||
}
|
||||
@@ -633,6 +724,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setMapped($mapped)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->mapped = $mapped;
|
||||
|
||||
return $this;
|
||||
@@ -643,6 +738,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setByReference($byReference)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->byReference = $byReference;
|
||||
|
||||
return $this;
|
||||
@@ -653,6 +752,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setVirtual($virtual)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->virtual = $virtual;
|
||||
|
||||
return $this;
|
||||
@@ -663,6 +766,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setCompound($compound)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->compound = $compound;
|
||||
|
||||
return $this;
|
||||
@@ -673,6 +780,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setType(ResolvedFormTypeInterface $type)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
@@ -683,6 +794,10 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setData($data)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->data = $data;
|
||||
|
||||
return $this;
|
||||
@@ -693,11 +808,31 @@ class FormConfig implements FormConfigEditorInterface
|
||||
*/
|
||||
public function setDataLocked($locked)
|
||||
{
|
||||
if ($this->locked) {
|
||||
throw new FormException('The config builder cannot be modified anymore.');
|
||||
}
|
||||
|
||||
$this->dataLocked = $locked;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFormConfig()
|
||||
{
|
||||
// This method should be idempotent, so clone the builder
|
||||
$config = clone $this;
|
||||
$config->locked = true;
|
||||
|
||||
if (!$config->dispatcher instanceof ImmutableEventDispatcher) {
|
||||
$config->dispatcher = new ImmutableEventDispatcher($config->dispatcher);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates whether the given variable is a valid form name.
|
||||
*
|
@@ -16,7 +16,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
interface FormConfigEditorInterface extends FormConfigInterface
|
||||
interface FormConfigBuilderInterface extends FormConfigInterface
|
||||
{
|
||||
/**
|
||||
* Adds an event listener to an event on this form.
|
||||
@@ -240,4 +240,11 @@ interface FormConfigEditorInterface extends FormConfigInterface
|
||||
* @return self The configuration object.
|
||||
*/
|
||||
public function setDataLocked($locked);
|
||||
|
||||
/**
|
||||
* Builds and returns the form configuration.
|
||||
*
|
||||
* @return FormConfigInterface
|
||||
*/
|
||||
public function getFormConfig();
|
||||
}
|
@@ -23,9 +23,15 @@ class FormFactory implements FormFactoryInterface
|
||||
*/
|
||||
private $registry;
|
||||
|
||||
public function __construct(FormRegistryInterface $registry)
|
||||
/**
|
||||
* @var ResolvedFormTypeFactoryInterface
|
||||
*/
|
||||
private $resolvedTypeFactory;
|
||||
|
||||
public function __construct(FormRegistryInterface $registry, ResolvedFormTypeFactoryInterface $resolvedTypeFactory)
|
||||
{
|
||||
$this->registry = $registry;
|
||||
$this->resolvedTypeFactory = $resolvedTypeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,14 +79,20 @@ class FormFactory implements FormFactoryInterface
|
||||
$options['data'] = $data;
|
||||
}
|
||||
|
||||
if ($type instanceof ResolvedFormTypeInterface) {
|
||||
$this->registry->addType($type);
|
||||
} elseif ($type instanceof FormTypeInterface) {
|
||||
$type = $this->registry->resolveType($type);
|
||||
$this->registry->addType($type);
|
||||
if ($type instanceof FormTypeInterface) {
|
||||
// An unresolved type instance was passed. Type extensions
|
||||
// are not supported for these. If you want to use type
|
||||
// extensions, you should create form extensions or register
|
||||
// your type in the Dependency Injection configuration instead.
|
||||
$parentType = $type->getParent();
|
||||
$type = $this->resolvedTypeFactory->createResolvedType(
|
||||
$type,
|
||||
array(),
|
||||
$parentType ? $this->registry->getType($parentType) : null
|
||||
);
|
||||
} elseif (is_string($type)) {
|
||||
$type = $this->registry->getType($type);
|
||||
} else {
|
||||
} elseif (!$type instanceof ResolvedFormTypeInterface) {
|
||||
throw new UnexpectedTypeException($type, 'string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface');
|
||||
}
|
||||
|
||||
@@ -152,12 +164,18 @@ class FormFactory implements FormFactoryInterface
|
||||
* @param FormTypeInterface $type The type
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* {@link FormRegistryInterface::resolveType()} and
|
||||
* {@link FormRegistryInterface::addType()} instead.
|
||||
* form extensions or type registration in the Dependency
|
||||
* Injection Container instead.
|
||||
*/
|
||||
public function addType(FormTypeInterface $type)
|
||||
{
|
||||
$this->registry->addType($this->registry->resolveType($type));
|
||||
$parentType = $type->getParent();
|
||||
|
||||
$this->registry->addType($this->resolvedTypeFactory->createResolvedType(
|
||||
$type,
|
||||
array(),
|
||||
$parentType ? $this->registry->getType($parentType) : null
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -37,14 +37,20 @@ class FormRegistry implements FormRegistryInterface
|
||||
*/
|
||||
private $guesser;
|
||||
|
||||
/**
|
||||
* @var ResolvedFormTypeFactoryInterface
|
||||
*/
|
||||
private $resolvedTypeFactory;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $extensions An array of FormExtensionInterface
|
||||
* @param array $extensions An array of FormExtensionInterface
|
||||
* @param ResolvedFormTypeFactoryInterface $resolvedTypeFactory The factory for resolved form types.
|
||||
*
|
||||
* @throws UnexpectedTypeException if any extension does not implement FormExtensionInterface
|
||||
*/
|
||||
public function __construct(array $extensions)
|
||||
public function __construct(array $extensions, ResolvedFormTypeFactoryInterface $resolvedTypeFactory)
|
||||
{
|
||||
foreach ($extensions as $extension) {
|
||||
if (!$extension instanceof FormExtensionInterface) {
|
||||
@@ -53,26 +59,7 @@ class FormRegistry implements FormRegistryInterface
|
||||
}
|
||||
|
||||
$this->extensions = $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolveType(FormTypeInterface $type)
|
||||
{
|
||||
$typeExtensions = array();
|
||||
|
||||
foreach ($this->extensions as $extension) {
|
||||
/* @var FormExtensionInterface $extension */
|
||||
$typeExtensions = array_merge(
|
||||
$typeExtensions,
|
||||
$extension->getTypeExtensions($type->getName())
|
||||
);
|
||||
}
|
||||
|
||||
$parent = $type->getParent() ? $this->getType($type->getParent()) : null;
|
||||
|
||||
return new ResolvedFormType($type, $typeExtensions, $parent);
|
||||
$this->resolvedTypeFactory = $resolvedTypeFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,6 +80,7 @@ class FormRegistry implements FormRegistryInterface
|
||||
}
|
||||
|
||||
if (!isset($this->types[$name])) {
|
||||
/** @var FormTypeInterface $type */
|
||||
$type = null;
|
||||
|
||||
foreach ($this->extensions as $extension) {
|
||||
@@ -107,7 +95,22 @@ class FormRegistry implements FormRegistryInterface
|
||||
throw new FormException(sprintf('Could not load type "%s"', $name));
|
||||
}
|
||||
|
||||
$this->addType($this->resolveType($type));
|
||||
$parentType = $type->getParent();
|
||||
$typeExtensions = array();
|
||||
|
||||
foreach ($this->extensions as $extension) {
|
||||
/* @var FormExtensionInterface $extension */
|
||||
$typeExtensions = array_merge(
|
||||
$typeExtensions,
|
||||
$extension->getTypeExtensions($name)
|
||||
);
|
||||
}
|
||||
|
||||
$this->addType($this->resolvedTypeFactory->createResolvedType(
|
||||
$type,
|
||||
$typeExtensions,
|
||||
$parentType ? $this->getType($parentType) : null
|
||||
));
|
||||
}
|
||||
|
||||
return $this->types[$name];
|
||||
|
@@ -22,6 +22,10 @@ interface FormRegistryInterface
|
||||
* Adds a form type.
|
||||
*
|
||||
* @param ResolvedFormTypeInterface $type The type
|
||||
*
|
||||
* @deprecated Deprecated since version 2.1, to be removed in 2.3. Use
|
||||
* form extensions or type registration in the Dependency
|
||||
* Injection Container instead.
|
||||
*/
|
||||
public function addType(ResolvedFormTypeInterface $type);
|
||||
|
||||
@@ -48,18 +52,6 @@ interface FormRegistryInterface
|
||||
*/
|
||||
public function hasType($name);
|
||||
|
||||
/**
|
||||
* Resolves a form type.
|
||||
*
|
||||
* @param FormTypeInterface $type
|
||||
*
|
||||
* @return ResolvedFormTypeInterface
|
||||
*
|
||||
* @throws Exception\UnexpectedTypeException if the types parent {@link FormTypeInterface::getParent()} is not a string
|
||||
* @throws Exception\FormException if the types parent can not be retrieved from any extension
|
||||
*/
|
||||
public function resolveType(FormTypeInterface $type);
|
||||
|
||||
/**
|
||||
* Returns the guesser responsible for guessing types.
|
||||
*
|
||||
|
@@ -22,6 +22,8 @@ use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
|
||||
*/
|
||||
class FormRenderer implements FormRendererInterface
|
||||
{
|
||||
const CACHE_KEY_VAR = 'unique_block_prefix';
|
||||
|
||||
/**
|
||||
* @var FormRendererEngineInterface
|
||||
*/
|
||||
@@ -42,11 +44,6 @@ class FormRenderer implements FormRendererInterface
|
||||
*/
|
||||
private $hierarchyLevelMap = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $variableMap = array();
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@@ -95,7 +92,8 @@ class FormRenderer implements FormRendererInterface
|
||||
throw new FormException('This method should only be called while rendering a form element.');
|
||||
}
|
||||
|
||||
$scopeVariables = end($this->variableStack);
|
||||
$viewCacheKey = $view->vars[self::CACHE_KEY_VAR];
|
||||
$scopeVariables = end($this->variableStack[$viewCacheKey]);
|
||||
|
||||
$resource = $this->engine->getResourceForBlockName($view, $blockName);
|
||||
|
||||
@@ -117,13 +115,13 @@ class FormRenderer implements FormRendererInterface
|
||||
// cannot be overwritten
|
||||
$variables = array_replace($scopeVariables, $variables);
|
||||
|
||||
$this->variableStack[] = $variables;
|
||||
$this->variableStack[$viewCacheKey][] = $variables;
|
||||
|
||||
// Do the rendering
|
||||
$html = $this->engine->renderBlock($view, $resource, $blockName, $variables);
|
||||
|
||||
// Clear the stack
|
||||
array_pop($this->variableStack);
|
||||
array_pop($this->variableStack[$viewCacheKey]);
|
||||
|
||||
return $html;
|
||||
}
|
||||
@@ -133,14 +131,15 @@ class FormRenderer implements FormRendererInterface
|
||||
*/
|
||||
public function searchAndRenderBlock(FormView $view, $blockNameSuffix, array $variables = array())
|
||||
{
|
||||
$renderOnlyOnce = in_array($blockNameSuffix, array('row', 'widget'));
|
||||
$renderOnlyOnce = 'row' === $blockNameSuffix || 'widget' === $blockNameSuffix;
|
||||
|
||||
if ($renderOnlyOnce && $view->isRendered()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// The cache key for storing the variables and types
|
||||
$mapKey = $uniqueBlockName = $view->vars['full_block_name'] . '_' . $blockNameSuffix;
|
||||
$viewCacheKey = $view->vars[self::CACHE_KEY_VAR];
|
||||
$viewAndSuffixCacheKey = $viewCacheKey . $blockNameSuffix;
|
||||
|
||||
// In templates, we have to deal with two kinds of block hierarchies:
|
||||
//
|
||||
@@ -169,29 +168,40 @@ class FormRenderer implements FormRendererInterface
|
||||
// widget() function again to render the block for the parent type.
|
||||
//
|
||||
// The second kind is implemented in the following blocks.
|
||||
if (!isset($this->blockNameHierarchyMap[$mapKey])) {
|
||||
if (!isset($this->blockNameHierarchyMap[$viewAndSuffixCacheKey])) {
|
||||
// INITIAL CALL
|
||||
// Calculate the hierarchy of template blocks and start on
|
||||
// the bottom level of the hierarchy (= "_<id>_<section>" block)
|
||||
$blockNameHierarchy = array();
|
||||
foreach ($view->vars['types'] as $type) {
|
||||
$blockNameHierarchy[] = $type . '_' . $blockNameSuffix;
|
||||
foreach ($view->vars['block_prefixes'] as $blockNamePrefix) {
|
||||
$blockNameHierarchy[] = $blockNamePrefix . '_' . $blockNameSuffix;
|
||||
}
|
||||
$blockNameHierarchy[] = $uniqueBlockName;
|
||||
$hierarchyLevel = count($blockNameHierarchy) - 1;
|
||||
|
||||
// The default variable scope contains all view variables, merged with
|
||||
// the variables passed explicitly to the helper
|
||||
$scopeVariables = $view->vars;
|
||||
$hierarchyInit = true;
|
||||
} else {
|
||||
// RECURSIVE CALL
|
||||
// If a block recursively calls renderSection() again, resume rendering
|
||||
// using the parent type in the hierarchy.
|
||||
$blockNameHierarchy = $this->blockNameHierarchyMap[$mapKey];
|
||||
$hierarchyLevel = $this->hierarchyLevelMap[$mapKey] - 1;
|
||||
$blockNameHierarchy = $this->blockNameHierarchyMap[$viewAndSuffixCacheKey];
|
||||
$hierarchyLevel = $this->hierarchyLevelMap[$viewAndSuffixCacheKey] - 1;
|
||||
|
||||
$hierarchyInit = false;
|
||||
}
|
||||
|
||||
// The variables are cached globally for a view (instead of for the
|
||||
// current suffix)
|
||||
if (!isset($this->variableStack[$viewCacheKey])) {
|
||||
// The default variable scope contains all view variables, merged with
|
||||
// the variables passed explicitly to the helper
|
||||
$scopeVariables = $view->vars;
|
||||
|
||||
$varInit = true;
|
||||
} else {
|
||||
// Reuse the current scope and merge it with the explicitly passed variables
|
||||
$scopeVariables = $this->variableMap[$mapKey];
|
||||
$scopeVariables = end($this->variableStack[$viewCacheKey]);
|
||||
|
||||
$varInit = false;
|
||||
}
|
||||
|
||||
// Load the resource where this block can be found
|
||||
@@ -235,28 +245,29 @@ class FormRenderer implements FormRendererInterface
|
||||
// We need to store these values in maps (associative arrays) because within a
|
||||
// call to widget() another call to widget() can be made, but for a different view
|
||||
// object. These nested calls should not override each other.
|
||||
$this->blockNameHierarchyMap[$mapKey] = $blockNameHierarchy;
|
||||
$this->hierarchyLevelMap[$mapKey] = $hierarchyLevel;
|
||||
$this->variableMap[$mapKey] = $variables;
|
||||
$this->blockNameHierarchyMap[$viewAndSuffixCacheKey] = $blockNameHierarchy;
|
||||
$this->hierarchyLevelMap[$viewAndSuffixCacheKey] = $hierarchyLevel;
|
||||
|
||||
// We also need to store the view and the variables so that we can render custom
|
||||
// blocks with renderBlock() using the same themes and variables as in the outer
|
||||
// block.
|
||||
//
|
||||
// A stack is sufficient for this purpose, because renderBlock() always accesses
|
||||
// the immediate next outer scope, which is always stored at the end of the stack.
|
||||
$this->variableStack[] = $variables;
|
||||
// We also need to store the variables for the view so that we can render other
|
||||
// blocks for the same view using the same variables as in the outer block.
|
||||
$this->variableStack[$viewCacheKey][] = $variables;
|
||||
|
||||
// Do the rendering
|
||||
$html = $this->engine->renderBlock($view, $resource, $blockName, $variables);
|
||||
|
||||
// Clear the stack
|
||||
array_pop($this->variableStack);
|
||||
array_pop($this->variableStack[$viewCacheKey]);
|
||||
|
||||
// Clear the maps
|
||||
unset($this->blockNameHierarchyMap[$mapKey]);
|
||||
unset($this->hierarchyLevelMap[$mapKey]);
|
||||
unset($this->variableMap[$mapKey]);
|
||||
// Clear the caches if they were filled for the first time within
|
||||
// this function call
|
||||
if ($hierarchyInit) {
|
||||
unset($this->blockNameHierarchyMap[$viewAndSuffixCacheKey]);
|
||||
unset($this->hierarchyLevelMap[$viewAndSuffixCacheKey]);
|
||||
}
|
||||
|
||||
if ($varInit) {
|
||||
unset($this->variableStack[$viewCacheKey]);
|
||||
}
|
||||
|
||||
if ($renderOnlyOnce) {
|
||||
$view->setRendered();
|
||||
|
@@ -1,365 +0,0 @@
|
||||
<?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\Util\PropertyPath;
|
||||
use Symfony\Component\EventDispatcher\ImmutableEventDispatcher;
|
||||
|
||||
/**
|
||||
* A read-only form configuration.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class ImmutableFormConfig implements FormConfigInterface
|
||||
{
|
||||
/**
|
||||
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
|
||||
*/
|
||||
private $dispatcher;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* @var PropertyPath
|
||||
*/
|
||||
private $propertyPath;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $mapped;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $byReference;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $virtual;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $compound;
|
||||
|
||||
/**
|
||||
* @var ResolvedFormTypeInterface
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $viewTransformers;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $modelTransformers;
|
||||
|
||||
/**
|
||||
* @var DataMapperInterface
|
||||
*/
|
||||
private $dataMapper;
|
||||
|
||||
/**
|
||||
* @var FormValidatorInterface
|
||||
*/
|
||||
private $validators;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $required;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $disabled;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $errorBubbling;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $emptyData;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $attributes;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $dataClass;
|
||||
|
||||
/**
|
||||
* @var Boolean
|
||||
*/
|
||||
private $dataLocked;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Creates an unmodifiable copy of a given configuration.
|
||||
*
|
||||
* @param FormConfigInterface $config The configuration to copy.
|
||||
*/
|
||||
public function __construct(FormConfigInterface $config)
|
||||
{
|
||||
$dispatcher = $config->getEventDispatcher();
|
||||
if (!$dispatcher instanceof ImmutableEventDispatcher) {
|
||||
$dispatcher = new ImmutableEventDispatcher($dispatcher);
|
||||
}
|
||||
|
||||
$this->dispatcher = $dispatcher;
|
||||
$this->name = $config->getName();
|
||||
$this->propertyPath = $config->getPropertyPath();
|
||||
$this->mapped = $config->getMapped();
|
||||
$this->byReference = $config->getByReference();
|
||||
$this->virtual = $config->getVirtual();
|
||||
$this->compound = $config->getCompound();
|
||||
$this->type = $config->getType();
|
||||
$this->viewTransformers = $config->getViewTransformers();
|
||||
$this->modelTransformers = $config->getModelTransformers();
|
||||
$this->dataMapper = $config->getDataMapper();
|
||||
$this->validators = $config->getValidators();
|
||||
$this->required = $config->getRequired();
|
||||
$this->disabled = $config->getDisabled();
|
||||
$this->errorBubbling = $config->getErrorBubbling();
|
||||
$this->emptyData = $config->getEmptyData();
|
||||
$this->attributes = $config->getAttributes();
|
||||
$this->data = $config->getData();
|
||||
$this->dataClass = $config->getDataClass();
|
||||
$this->dataLocked = $config->getDataLocked();
|
||||
$this->options = $config->getOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEventDispatcher()
|
||||
{
|
||||
return $this->dispatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getPropertyPath()
|
||||
{
|
||||
return $this->propertyPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getMapped()
|
||||
{
|
||||
return $this->mapped;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getByReference()
|
||||
{
|
||||
return $this->byReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getVirtual()
|
||||
{
|
||||
return $this->virtual;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getCompound()
|
||||
{
|
||||
return $this->compound;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getViewTransformers()
|
||||
{
|
||||
return $this->viewTransformers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getModelTransformers()
|
||||
{
|
||||
return $this->modelTransformers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data mapper of the form.
|
||||
*
|
||||
* @return DataMapperInterface The data mapper.
|
||||
*/
|
||||
public function getDataMapper()
|
||||
{
|
||||
return $this->dataMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getValidators()
|
||||
{
|
||||
return $this->validators;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getRequired()
|
||||
{
|
||||
return $this->required;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDisabled()
|
||||
{
|
||||
return $this->disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getErrorBubbling()
|
||||
{
|
||||
return $this->errorBubbling;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEmptyData()
|
||||
{
|
||||
return $this->emptyData;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasAttribute($name)
|
||||
{
|
||||
return isset($this->attributes[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttribute($name, $default = null)
|
||||
{
|
||||
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDataClass()
|
||||
{
|
||||
return $this->dataClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getDataLocked()
|
||||
{
|
||||
return $this->dataLocked;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOptions()
|
||||
{
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function hasOption($name)
|
||||
{
|
||||
return isset($this->options[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getOption($name, $default = null)
|
||||
{
|
||||
return isset($this->options[$name]) ? $this->options[$name] : $default;
|
||||
}
|
||||
}
|
@@ -35,7 +35,7 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
private $typeExtensions;
|
||||
|
||||
/**
|
||||
* @var ResolvedFormType
|
||||
* @var ResolvedFormTypeInterface
|
||||
*/
|
||||
private $parent;
|
||||
|
||||
@@ -44,7 +44,7 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
*/
|
||||
private $optionsResolver;
|
||||
|
||||
public function __construct(FormTypeInterface $innerType, array $typeExtensions = array(), ResolvedFormType $parent = null)
|
||||
public function __construct(FormTypeInterface $innerType, array $typeExtensions = array(), ResolvedFormTypeInterface $parent = null)
|
||||
{
|
||||
if (!preg_match('/^[a-z0-9_]*$/i', $innerType->getName())) {
|
||||
throw new FormException(sprintf(
|
||||
@@ -148,7 +148,16 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function buildForm(FormBuilderInterface $builder, array $options)
|
||||
/**
|
||||
* Configures a form builder for the type hierarchy.
|
||||
*
|
||||
* This method is protected in order to allow implementing classes
|
||||
* to change or call it in re-implementations of {@link createBuilder()}.
|
||||
*
|
||||
* @param FormBuilderInterface $builder The builder to configure.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
if (null !== $this->parent) {
|
||||
$this->parent->buildForm($builder, $options);
|
||||
@@ -162,7 +171,19 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function buildView(FormView $view, FormInterface $form, array $options)
|
||||
/**
|
||||
* Configures a form view for the type hierarchy.
|
||||
*
|
||||
* This method is protected in order to allow implementing classes
|
||||
* to change or call it in re-implementations of {@link createView()}.
|
||||
*
|
||||
* It is called before the children of the view are built.
|
||||
*
|
||||
* @param FormView $view The form view to configure.
|
||||
* @param FormInterface $form The form corresponding to the view.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
if (null !== $this->parent) {
|
||||
$this->parent->buildView($view, $form, $options);
|
||||
@@ -176,7 +197,19 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function finishView(FormView $view, FormInterface $form, array $options)
|
||||
/**
|
||||
* Finishes a form view for the type hierarchy.
|
||||
*
|
||||
* This method is protected in order to allow implementing classes
|
||||
* to change or call it in re-implementations of {@link createView()}.
|
||||
*
|
||||
* It is called after the children of the view have been built.
|
||||
*
|
||||
* @param FormView $view The form view to configure.
|
||||
* @param FormInterface $form The form corresponding to the view.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function finishView(FormView $view, FormInterface $form, array $options)
|
||||
{
|
||||
if (null !== $this->parent) {
|
||||
$this->parent->finishView($view, $form, $options);
|
||||
@@ -190,7 +223,15 @@ class ResolvedFormType implements ResolvedFormTypeInterface
|
||||
}
|
||||
}
|
||||
|
||||
private function getOptionsResolver()
|
||||
/**
|
||||
* Returns the configured options resolver used for this type.
|
||||
*
|
||||
* This method is protected in order to allow implementing classes
|
||||
* to change or call it in re-implementations of {@link createBuilder()}.
|
||||
*
|
||||
* @return \Symfony\Component\OptionsResolver\OptionsResolverInterface The options resolver.
|
||||
*/
|
||||
public function getOptionsResolver()
|
||||
{
|
||||
if (null === $this->optionsResolver) {
|
||||
if (null !== $this->parent) {
|
||||
|
26
vendor/symfony/symfony/src/Symfony/Component/Form/ResolvedFormTypeFactory.php
vendored
Normal file
26
vendor/symfony/symfony/src/Symfony/Component/Form/ResolvedFormTypeFactory.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
class ResolvedFormTypeFactory implements ResolvedFormTypeFactoryInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createResolvedType(FormTypeInterface $type, array $typeExtensions, ResolvedFormTypeInterface $parent = null)
|
||||
{
|
||||
return new ResolvedFormType($type, $typeExtensions, $parent);
|
||||
}
|
||||
}
|
38
vendor/symfony/symfony/src/Symfony/Component/Form/ResolvedFormTypeFactoryInterface.php
vendored
Normal file
38
vendor/symfony/symfony/src/Symfony/Component/Form/ResolvedFormTypeFactoryInterface.php
vendored
Normal file
@@ -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;
|
||||
|
||||
/**
|
||||
* Creates ResolvedFormTypeInterface instances.
|
||||
*
|
||||
* This interface allows you to use your custom ResolvedFormTypeInterface
|
||||
* implementation, within which you can customize the concrete FormBuilderInterface
|
||||
* implementations or FormView subclasses that are used by the framework.
|
||||
*
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
interface ResolvedFormTypeFactoryInterface
|
||||
{
|
||||
/**
|
||||
* Resolves a form type.
|
||||
*
|
||||
* @param FormTypeInterface $type
|
||||
* @param array $typeExtensions
|
||||
* @param ResolvedFormTypeInterface $parent
|
||||
*
|
||||
* @return ResolvedFormTypeInterface
|
||||
*
|
||||
* @throws Exception\UnexpectedTypeException if the types parent {@link FormTypeInterface::getParent()} is not a string
|
||||
* @throws Exception\FormException if the types parent can not be retrieved from any extension
|
||||
*/
|
||||
public function createResolvedType(FormTypeInterface $type, array $typeExtensions, ResolvedFormTypeInterface $parent = null);
|
||||
}
|
@@ -67,4 +67,41 @@ interface ResolvedFormTypeInterface
|
||||
* @return FormView The created form view.
|
||||
*/
|
||||
public function createView(FormInterface $form, FormView $parent = null);
|
||||
|
||||
/**
|
||||
* Configures a form builder for the type hierarchy.
|
||||
*
|
||||
* @param FormBuilderInterface $builder The builder to configure.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options);
|
||||
|
||||
/**
|
||||
* Configures a form view for the type hierarchy.
|
||||
*
|
||||
* It is called before the children of the view are built.
|
||||
*
|
||||
* @param FormView $view The form view to configure.
|
||||
* @param FormInterface $form The form corresponding to the view.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function buildView(FormView $view, FormInterface $form, array $options);
|
||||
|
||||
/**
|
||||
* Finishes a form view for the type hierarchy.
|
||||
*
|
||||
* It is called after the children of the view have been built.
|
||||
*
|
||||
* @param FormView $view The form view to configure.
|
||||
* @param FormInterface $form The form corresponding to the view.
|
||||
* @param array $options The options used for the configuration.
|
||||
*/
|
||||
public function finishView(FormView $view, FormInterface $form, array $options);
|
||||
|
||||
/**
|
||||
* Returns the configured options resolver used for this type.
|
||||
*
|
||||
* @return \Symfony\Component\OptionsResolver\OptionsResolverInterface The options resolver.
|
||||
*/
|
||||
public function getOptionsResolver();
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Form\Tests;
|
||||
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\Tests\Fixtures\AlternatingRowType;
|
||||
|
||||
abstract class AbstractDivLayoutTest extends AbstractLayoutTest
|
||||
{
|
||||
@@ -38,13 +39,17 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
|
||||
public function testRowOverrideVariables()
|
||||
{
|
||||
$view = $this->factory->createNamed('name', 'text')->createView();
|
||||
$html = $this->renderRow($view, array('label' => 'foo&bar'));
|
||||
$html = $this->renderRow($view, array(
|
||||
'attr' => array('class' => 'my&class'),
|
||||
'label' => 'foo&bar',
|
||||
'label_attr' => array('class' => 'my&label&class'),
|
||||
));
|
||||
|
||||
$this->assertMatchesXpath($html,
|
||||
'/div
|
||||
[
|
||||
./label[@for="name"][.="[trans]foo&bar[/trans]"]
|
||||
/following-sibling::input[@id="name"]
|
||||
./label[@for="name"][@class="my&label&class required"][.="[trans]foo&bar[/trans]"]
|
||||
/following-sibling::input[@id="name"][@class="my&class"]
|
||||
]
|
||||
'
|
||||
);
|
||||
@@ -279,6 +284,29 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
|
||||
);
|
||||
}
|
||||
|
||||
// https://github.com/symfony/symfony/issues/5038
|
||||
public function testCollectionWithAlternatingRowTypes()
|
||||
{
|
||||
$data = array(
|
||||
array('title' => 'a'),
|
||||
array('title' => 'b'),
|
||||
);
|
||||
$form = $this->factory->createNamed('name', 'collection', $data, array(
|
||||
'type' => new AlternatingRowType(),
|
||||
));
|
||||
|
||||
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
||||
'/div
|
||||
[
|
||||
./div[./div/div/input[@type="text"][@value="a"]]
|
||||
/following-sibling::div[./div/div/textarea[.="b"]]
|
||||
]
|
||||
[count(./div[./div/div/input])=1]
|
||||
[count(./div[./div/div/textarea])=1]
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
public function testEmptyCollection()
|
||||
{
|
||||
$form = $this->factory->createNamed('name', 'collection', array(), array(
|
||||
@@ -437,7 +465,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
|
||||
public function testRepeatedWithCustomOptions()
|
||||
{
|
||||
$form = $this->factory->createNamed('name', 'repeated', null, array(
|
||||
// the global required value cannot be overriden
|
||||
// the global required value cannot be overridden
|
||||
'first_options' => array('label' => 'Test', 'required' => false),
|
||||
'second_options' => array('label' => 'Test2')
|
||||
));
|
||||
|
@@ -66,7 +66,7 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
||||
// the top level
|
||||
$dom->loadXml('<root>'.$html.'</root>');
|
||||
} catch (\Exception $e) {
|
||||
return $this->fail(sprintf(
|
||||
$this->fail(sprintf(
|
||||
"Failed loading HTML:\n\n%s\n\nError: %s",
|
||||
$html,
|
||||
$e->getMessage()
|
||||
@@ -225,7 +225,7 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testLabelWithCustomOptionsPassedDirectly()
|
||||
public function testLabelWithCustomAttributesPassedDirectly()
|
||||
{
|
||||
$form = $this->factory->createNamed('name', 'text');
|
||||
$html = $this->renderLabel($form->createView(), null, array(
|
||||
@@ -242,7 +242,7 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testLabelWithCustomTextAndCustomOptionsPassedDirectly()
|
||||
public function testLabelWithCustomTextAndCustomAttributesPassedDirectly()
|
||||
{
|
||||
$form = $this->factory->createNamed('name', 'text');
|
||||
$html = $this->renderLabel($form->createView(), 'Custom label', array(
|
||||
@@ -260,6 +260,27 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
||||
);
|
||||
}
|
||||
|
||||
// https://github.com/symfony/symfony/issues/5029
|
||||
public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly()
|
||||
{
|
||||
$form = $this->factory->createNamed('name', 'text', null, array(
|
||||
'label' => 'Custom label',
|
||||
));
|
||||
$html = $this->renderLabel($form->createView(), null, array(
|
||||
'label_attr' => array(
|
||||
'class' => 'my&class'
|
||||
),
|
||||
));
|
||||
|
||||
$this->assertMatchesXpath($html,
|
||||
'/label
|
||||
[@for="name"]
|
||||
[@class="my&class required"]
|
||||
[.="[trans]Custom label[/trans]"]
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
public function testErrors()
|
||||
{
|
||||
$form = $this->factory->createNamed('name', 'text');
|
||||
|
@@ -116,7 +116,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest
|
||||
->getForm()
|
||||
->createView();
|
||||
|
||||
// Render field2 row -> does not implicitely call renderWidget because
|
||||
// Render field2 row -> does not implicitly call renderWidget because
|
||||
// it is a repeated field!
|
||||
$this->renderRow($view['field2']);
|
||||
|
||||
|
@@ -14,7 +14,7 @@ namespace Symfony\Component\Form\Tests;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\Extension\Core\EventListener\BindRequestListener;
|
||||
use Symfony\Component\Form\Extension\HttpFoundation\EventListener\BindRequestListener;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
@@ -69,8 +69,40 @@ class ChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices());
|
||||
$this->assertSame(array('0', '1', '2', '3'), $this->list->getValues());
|
||||
$this->assertEquals(array(1 => new ChoiceView('1', 'B')), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView('0', 'A'), 2 => new ChoiceView('2', 'C'), 3 => new ChoiceView('3', 'D')), $this->list->getRemainingViews());
|
||||
$this->assertEquals(array(1 => new ChoiceView($this->obj2, '1', 'B')), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView($this->obj1, '0', 'A'), 2 => new ChoiceView($this->obj3, '2', 'C'), 3 => new ChoiceView($this->obj4, '3', 'D')), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
/**
|
||||
* Necessary for interoperability with MongoDB cursors or ORM relations as
|
||||
* choices parameter. A choice itself that is an object implementing \Traversable
|
||||
* is not treated as hierarchical structure, but as-is.
|
||||
*/
|
||||
public function testInitNestedTraversable()
|
||||
{
|
||||
$traversableChoice = new \ArrayIterator(array($this->obj3, $this->obj4));
|
||||
|
||||
$this->list = new ChoiceList(
|
||||
new \ArrayIterator(array(
|
||||
'Group' => array($this->obj1, $this->obj2),
|
||||
'Not a Group' => $traversableChoice
|
||||
)),
|
||||
array(
|
||||
'Group' => array('A', 'B'),
|
||||
'Not a Group' => 'C',
|
||||
),
|
||||
array($this->obj2)
|
||||
);
|
||||
|
||||
$this->assertSame(array($this->obj1, $this->obj2, $traversableChoice), $this->list->getChoices());
|
||||
$this->assertSame(array('0', '1', '2'), $this->list->getValues());
|
||||
$this->assertEquals(array(
|
||||
'Group' => array(1 => new ChoiceView($this->obj2, '1', 'B'))
|
||||
), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(
|
||||
'Group' => array(0 => new ChoiceView($this->obj1, '0', 'A')),
|
||||
2 => new ChoiceView($traversableChoice, '2', 'C')
|
||||
), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
public function testInitNestedArray()
|
||||
@@ -78,12 +110,12 @@ class ChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices());
|
||||
$this->assertSame(array('0', '1', '2', '3'), $this->list->getValues());
|
||||
$this->assertEquals(array(
|
||||
'Group 1' => array(1 => new ChoiceView('1', 'B')),
|
||||
'Group 2' => array(2 => new ChoiceView('2', 'C'))
|
||||
'Group 1' => array(1 => new ChoiceView($this->obj2, '1', 'B')),
|
||||
'Group 2' => array(2 => new ChoiceView($this->obj3, '2', 'C'))
|
||||
), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(
|
||||
'Group 1' => array(0 => new ChoiceView('0', 'A')),
|
||||
'Group 2' => array(3 => new ChoiceView('3', 'D'))
|
||||
'Group 1' => array(0 => new ChoiceView($this->obj1, '0', 'A')),
|
||||
'Group 2' => array(3 => new ChoiceView($this->obj4, '3', 'D'))
|
||||
), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
@@ -141,4 +173,15 @@ class ChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
$choices = array($this->obj2, $this->obj3, 'foobar');
|
||||
$this->assertSame(array('1', '2'), $this->list->getValuesForChoices($choices));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testNonMatchingLabels()
|
||||
{
|
||||
$this->list = new ChoiceList(
|
||||
array($this->obj1, $this->obj2),
|
||||
array('A')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -49,12 +49,12 @@ class LazyChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testGetPreferredViews()
|
||||
{
|
||||
$this->assertEquals(array(1 => new ChoiceView('b', 'B')), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(1 => new ChoiceView('b', 'b', 'B')), $this->list->getPreferredViews());
|
||||
}
|
||||
|
||||
public function testGetRemainingViews()
|
||||
{
|
||||
$this->assertEquals(array(0 => new ChoiceView('a', 'A'), 2 => new ChoiceView('c', 'C')), $this->list->getRemainingViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView('a', 'a', 'A'), 2 => new ChoiceView('c', 'c', 'C')), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
public function testGetIndicesForChoices()
|
||||
|
@@ -81,8 +81,8 @@ class ObjectChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices());
|
||||
$this->assertSame(array('0', '1', '2', '3'), $this->list->getValues());
|
||||
$this->assertEquals(array(1 => new ChoiceView('1', 'B')), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView('0', 'A'), 2 => new ChoiceView('2', 'C'), 3 => new ChoiceView('3', 'D')), $this->list->getRemainingViews());
|
||||
$this->assertEquals(array(1 => new ChoiceView($this->obj2, '1', 'B')), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView($this->obj1, '0', 'A'), 2 => new ChoiceView($this->obj3, '2', 'C'), 3 => new ChoiceView($this->obj4, '3', 'D')), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
public function testInitNestedArray()
|
||||
@@ -90,12 +90,12 @@ class ObjectChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices());
|
||||
$this->assertSame(array('0', '1', '2', '3'), $this->list->getValues());
|
||||
$this->assertEquals(array(
|
||||
'Group 1' => array(1 => new ChoiceView('1', 'B')),
|
||||
'Group 2' => array(2 => new ChoiceView('2', 'C'))
|
||||
'Group 1' => array(1 => new ChoiceView($this->obj2, '1', 'B')),
|
||||
'Group 2' => array(2 => new ChoiceView($this->obj3, '2', 'C'))
|
||||
), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(
|
||||
'Group 1' => array(0 => new ChoiceView('0', 'A')),
|
||||
'Group 2' => array(3 => new ChoiceView('3', 'D'))
|
||||
'Group 1' => array(0 => new ChoiceView($this->obj1, '0', 'A')),
|
||||
'Group 2' => array(3 => new ChoiceView($this->obj4, '3', 'D'))
|
||||
), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
@@ -123,14 +123,14 @@ class ObjectChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4, $obj5, $obj6), $this->list->getChoices());
|
||||
$this->assertSame(array('0', '1', '2', '3', '4', '5'), $this->list->getValues());
|
||||
$this->assertEquals(array(
|
||||
'Group 1' => array(1 => new ChoiceView('1', 'B')),
|
||||
'Group 2' => array(2 => new ChoiceView('2', 'C'))
|
||||
'Group 1' => array(1 => new ChoiceView($this->obj2, '1', 'B')),
|
||||
'Group 2' => array(2 => new ChoiceView($this->obj3, '2', 'C'))
|
||||
), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(
|
||||
'Group 1' => array(0 => new ChoiceView('0', 'A')),
|
||||
'Group 2' => array(3 => new ChoiceView('3', 'D')),
|
||||
4 => new ChoiceView('4', 'E'),
|
||||
5 => new ChoiceView('5', 'F'),
|
||||
'Group 1' => array(0 => new ChoiceView($this->obj1, '0', 'A')),
|
||||
'Group 2' => array(3 => new ChoiceView($this->obj4, '3', 'D')),
|
||||
4 => new ChoiceView($obj5, '4', 'E'),
|
||||
5 => new ChoiceView($obj6, '5', 'F'),
|
||||
), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
@@ -172,8 +172,8 @@ class ObjectChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices());
|
||||
$this->assertSame(array('10', '20', '30', '40'), $this->list->getValues());
|
||||
$this->assertEquals(array(1 => new ChoiceView('20', 'B'), 2 => new ChoiceView('30', 'C')), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView('10', 'A'), 3 => new ChoiceView('40', 'D')), $this->list->getRemainingViews());
|
||||
$this->assertEquals(array(1 => new ChoiceView($this->obj2, '20', 'B'), 2 => new ChoiceView($this->obj3, '30', 'C')), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView($this->obj1, '10', 'A'), 3 => new ChoiceView($this->obj4, '40', 'D')), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
public function testInitArrayUsesToString()
|
||||
@@ -189,7 +189,7 @@ class ObjectChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertSame(array($this->obj1, $this->obj2, $this->obj3, $this->obj4), $this->list->getChoices());
|
||||
$this->assertSame(array('0', '1', '2', '3'), $this->list->getValues());
|
||||
$this->assertEquals(array(0 => new ChoiceView('0', 'A'), 1 => new ChoiceView('1', 'B'), 2 => new ChoiceView('2', 'C'), 3 => new ChoiceView('3', 'D')), $this->list->getRemainingViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView($this->obj1, '0', 'A'), 1 => new ChoiceView($this->obj2, '1', 'B'), 2 => new ChoiceView($this->obj3, '2', 'C'), 3 => new ChoiceView($this->obj4, '3', 'D')), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -55,8 +55,8 @@ class SimpleChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c'), $this->list->getChoices());
|
||||
$this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c'), $this->list->getValues());
|
||||
$this->assertEquals(array(1 => new ChoiceView('b', 'B')), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView('a', 'A'), 2 => new ChoiceView('c', 'C')), $this->list->getRemainingViews());
|
||||
$this->assertEquals(array(1 => new ChoiceView('b', 'b', 'B')), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(0 => new ChoiceView('a', 'a', 'A'), 2 => new ChoiceView('c', 'c', 'C')), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
public function testInitNestedArray()
|
||||
@@ -64,12 +64,12 @@ class SimpleChoiceListTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd'), $this->list->getChoices());
|
||||
$this->assertSame(array(0 => 'a', 1 => 'b', 2 => 'c', 3 => 'd'), $this->list->getValues());
|
||||
$this->assertEquals(array(
|
||||
'Group 1' => array(1 => new ChoiceView('b', 'B')),
|
||||
'Group 2' => array(2 => new ChoiceView('c', 'C'))
|
||||
'Group 1' => array(1 => new ChoiceView('b', 'b', 'B')),
|
||||
'Group 2' => array(2 => new ChoiceView('c', 'c', 'C'))
|
||||
), $this->list->getPreferredViews());
|
||||
$this->assertEquals(array(
|
||||
'Group 1' => array(0 => new ChoiceView('a', 'A')),
|
||||
'Group 2' => array(3 => new ChoiceView('d', 'D'))
|
||||
'Group 1' => array(0 => new ChoiceView('a', 'a', 'A')),
|
||||
'Group 2' => array(3 => new ChoiceView('d', 'd', 'D'))
|
||||
), $this->list->getRemainingViews());
|
||||
}
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
namespace Symfony\Component\Form\Tests\Extension\Core\DataMapper;
|
||||
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormConfig;
|
||||
use Symfony\Component\Form\FormConfigBuilder;
|
||||
use Symfony\Component\Form\FormConfigInterface;
|
||||
use Symfony\Component\Form\Util\PropertyPath;
|
||||
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
|
||||
@@ -89,7 +89,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
->with($car)
|
||||
->will($this->returnValue($engine));
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$form = $this->getForm($config);
|
||||
@@ -112,7 +112,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
->with($car)
|
||||
->will($this->returnValue($engine));
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(false);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$form = $this->getForm($config);
|
||||
@@ -127,7 +127,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$car = new \stdClass();
|
||||
|
||||
$config = new FormConfig(null, '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder(null, '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$form = $this->getForm($config);
|
||||
|
||||
@@ -146,7 +146,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
$propertyPath->expects($this->never())
|
||||
->method('getValue');
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setMapped(false);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
@@ -164,7 +164,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
$propertyPath->expects($this->never())
|
||||
->method('getValue');
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$form = $this->getForm($config);
|
||||
@@ -185,14 +185,14 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
->with($car)
|
||||
->will($this->returnValue($engine));
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setVirtual(true);
|
||||
$config->setCompound(true);
|
||||
$config->setDataMapper($this->getDataMapper());
|
||||
$form = $this->getForm($config);
|
||||
|
||||
$config = new FormConfig('engine', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('engine', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$child = $this->getForm($config);
|
||||
@@ -215,7 +215,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
->method('setValue')
|
||||
->with($car, $engine);
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(false);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$config->setData($engine);
|
||||
@@ -234,7 +234,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
->method('setValue')
|
||||
->with($car, $engine);
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$config->setData($engine);
|
||||
@@ -258,7 +258,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
$propertyPath->expects($this->never())
|
||||
->method('setValue');
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$config->setData($engine);
|
||||
@@ -276,7 +276,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
$propertyPath->expects($this->never())
|
||||
->method('setValue');
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$config->setData($engine);
|
||||
@@ -294,7 +294,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
$propertyPath->expects($this->never())
|
||||
->method('setValue');
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$config->setData(null);
|
||||
@@ -312,7 +312,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
$propertyPath->expects($this->never())
|
||||
->method('setValue');
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$config->setData($engine);
|
||||
@@ -330,7 +330,7 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
$propertyPath->expects($this->never())
|
||||
->method('setValue');
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($propertyPath);
|
||||
$config->setData($engine);
|
||||
@@ -356,14 +356,14 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||
->method('setValue')
|
||||
->with($car, $engine);
|
||||
|
||||
$config = new FormConfig('name', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', '\stdClass', $this->dispatcher);
|
||||
$config->setPropertyPath($parentPath);
|
||||
$config->setVirtual(true);
|
||||
$config->setCompound(true);
|
||||
$config->setDataMapper($this->getDataMapper());
|
||||
$form = $this->getForm($config);
|
||||
|
||||
$config = new FormConfig('engine', '\stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('engine', '\stdClass', $this->dispatcher);
|
||||
$config->setByReference(true);
|
||||
$config->setPropertyPath($childPath);
|
||||
$config->setData($engine);
|
||||
|
@@ -654,10 +654,10 @@ class ChoiceTypeTest extends TypeTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('a', 'A'),
|
||||
new ChoiceView('b', 'B'),
|
||||
new ChoiceView('c', 'C'),
|
||||
new ChoiceView('d', 'D'),
|
||||
new ChoiceView('a', 'a', 'A'),
|
||||
new ChoiceView('b', 'b', 'B'),
|
||||
new ChoiceView('c', 'c', 'C'),
|
||||
new ChoiceView('d', 'd', 'D'),
|
||||
), $view->vars['choices']);
|
||||
}
|
||||
|
||||
@@ -671,12 +671,12 @@ class ChoiceTypeTest extends TypeTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
0 => new ChoiceView('a', 'A'),
|
||||
2 => new ChoiceView('c', 'C'),
|
||||
0 => new ChoiceView('a', 'a', 'A'),
|
||||
2 => new ChoiceView('c', 'c', 'C'),
|
||||
), $view->vars['choices']);
|
||||
$this->assertEquals(array(
|
||||
1 => new ChoiceView('b', 'B'),
|
||||
3 => new ChoiceView('d', 'D'),
|
||||
1 => new ChoiceView('b', 'b', 'B'),
|
||||
3 => new ChoiceView('d', 'd', 'D'),
|
||||
), $view->vars['preferred_choices']);
|
||||
}
|
||||
|
||||
@@ -690,23 +690,42 @@ class ChoiceTypeTest extends TypeTestCase
|
||||
|
||||
$this->assertEquals(array(
|
||||
'Symfony' => array(
|
||||
0 => new ChoiceView('a', 'Bernhard'),
|
||||
2 => new ChoiceView('c', 'Kris'),
|
||||
0 => new ChoiceView('a', 'a', 'Bernhard'),
|
||||
2 => new ChoiceView('c', 'c', 'Kris'),
|
||||
),
|
||||
'Doctrine' => array(
|
||||
4 => new ChoiceView('e', 'Roman'),
|
||||
4 => new ChoiceView('e', 'e', 'Roman'),
|
||||
),
|
||||
), $view->vars['choices']);
|
||||
$this->assertEquals(array(
|
||||
'Symfony' => array(
|
||||
1 => new ChoiceView('b', 'Fabien'),
|
||||
1 => new ChoiceView('b', 'b', 'Fabien'),
|
||||
),
|
||||
'Doctrine' => array(
|
||||
3 => new ChoiceView('d', 'Jon'),
|
||||
3 => new ChoiceView('d', 'd', 'Jon'),
|
||||
),
|
||||
), $view->vars['preferred_choices']);
|
||||
}
|
||||
|
||||
public function testPassChoiceDataToView()
|
||||
{
|
||||
$obj1 = (object) array('value' => 'a', 'label' => 'A');
|
||||
$obj2 = (object) array('value' => 'b', 'label' => 'B');
|
||||
$obj3 = (object) array('value' => 'c', 'label' => 'C');
|
||||
$obj4 = (object) array('value' => 'd', 'label' => 'D');
|
||||
$form = $this->factory->create('choice', null, array(
|
||||
'choice_list' => new ObjectChoiceList(array($obj1, $obj2, $obj3, $obj4), 'label', array(), null, 'value'),
|
||||
));
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView($obj1, 'a', 'A'),
|
||||
new ChoiceView($obj2, 'b', 'B'),
|
||||
new ChoiceView($obj3, 'c', 'C'),
|
||||
new ChoiceView($obj4, 'd', 'D'),
|
||||
), $view->vars['choices']);
|
||||
}
|
||||
|
||||
public function testAdjustFullNameForMultipleNonExpanded()
|
||||
{
|
||||
$form = $this->factory->createNamed('name', 'choice', null, array(
|
||||
|
@@ -24,11 +24,11 @@ class CountryTypeTest extends LocalizedTestCase
|
||||
$choices = $view->vars['choices'];
|
||||
|
||||
// Don't check objects for identity
|
||||
$this->assertContains(new ChoiceView('DE', 'Deutschland'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('GB', 'Vereinigtes Königreich'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('US', 'Vereinigte Staaten'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('FR', 'Frankreich'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('MY', 'Malaysia'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('DE', 'DE', 'Deutschland'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('GB', 'GB', 'Vereinigtes Königreich'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('US', 'US', 'Vereinigte Staaten'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('FR', 'FR', 'Frankreich'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('MY', 'MY', 'Malaysia'), $choices, '', false, false);
|
||||
}
|
||||
|
||||
public function testUnknownCountryIsNotIncluded()
|
||||
|
@@ -355,8 +355,8 @@ class DateTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('2010', '2010'),
|
||||
new ChoiceView('2011', '2011'),
|
||||
new ChoiceView('2010', '2010', '2010'),
|
||||
new ChoiceView('2011', '2011', '2011'),
|
||||
), $view['year']->vars['choices']);
|
||||
}
|
||||
|
||||
@@ -369,8 +369,8 @@ class DateTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('6', '06'),
|
||||
new ChoiceView('7', '07'),
|
||||
new ChoiceView('6', '6', '06'),
|
||||
new ChoiceView('7', '7', '07'),
|
||||
), $view['month']->vars['choices']);
|
||||
}
|
||||
|
||||
@@ -384,8 +384,8 @@ class DateTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('1', 'Jän'),
|
||||
new ChoiceView('4', 'Apr')
|
||||
new ChoiceView('1', '1', 'Jän'),
|
||||
new ChoiceView('4', '4', 'Apr')
|
||||
), $view['month']->vars['choices']);
|
||||
}
|
||||
|
||||
@@ -399,8 +399,8 @@ class DateTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('1', 'Jänner'),
|
||||
new ChoiceView('4', 'April'),
|
||||
new ChoiceView('1', '1', 'Jänner'),
|
||||
new ChoiceView('4', '4', 'April'),
|
||||
), $view['month']->vars['choices']);
|
||||
}
|
||||
|
||||
@@ -414,8 +414,8 @@ class DateTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('1', 'Jänner'),
|
||||
new ChoiceView('4', 'April'),
|
||||
new ChoiceView('1', '1', 'Jänner'),
|
||||
new ChoiceView('4', '4', 'April'),
|
||||
), $view['month']->vars['choices']);
|
||||
}
|
||||
|
||||
@@ -428,8 +428,8 @@ class DateTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('6', '06'),
|
||||
new ChoiceView('7', '07'),
|
||||
new ChoiceView('6', '6', '06'),
|
||||
new ChoiceView('7', '7', '07'),
|
||||
), $view['day']->vars['choices']);
|
||||
}
|
||||
|
||||
|
@@ -206,7 +206,7 @@ class FormTypeTest extends TypeTestCase
|
||||
$this->assertEquals('test', $view['child']->vars['translation_domain']);
|
||||
}
|
||||
|
||||
public function testNonTranlsationDomainFormWithNonTranslationDomainParentBeingTranslationDomainDefault()
|
||||
public function testNonTranslationDomainFormWithNonTranslationDomainParentBeingTranslationDomainDefault()
|
||||
{
|
||||
$parent = $this->factory->createNamed('parent', 'form');
|
||||
$child = $this->factory->createNamed('child', 'form');
|
||||
@@ -645,4 +645,18 @@ class FormTypeTest extends TypeTestCase
|
||||
|
||||
$this->assertSame('default', $form->getData());
|
||||
}
|
||||
|
||||
public function testNormDataIsPassedToView()
|
||||
{
|
||||
$view = $this->factory->createBuilder('form')
|
||||
->addViewTransformer(new FixedDataTransformer(array(
|
||||
'foo' => 'bar',
|
||||
)))
|
||||
->setData('foo')
|
||||
->getForm()
|
||||
->createView();
|
||||
|
||||
$this->assertSame('foo', $view->vars['data']);
|
||||
$this->assertSame('bar', $view->vars['value']);
|
||||
}
|
||||
}
|
||||
|
@@ -23,11 +23,11 @@ class LanguageTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
$choices = $view->vars['choices'];
|
||||
|
||||
$this->assertContains(new ChoiceView('en', 'Englisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('en_GB', 'Britisches Englisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('en_US', 'Amerikanisches Englisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('fr', 'Französisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('my', 'Birmanisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('en', 'en', 'Englisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('en_GB', 'en_GB', 'Britisches Englisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('en_US', 'en_US', 'Amerikanisches Englisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('fr', 'fr', 'Französisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('my', 'my', 'Birmanisch'), $choices, '', false, false);
|
||||
}
|
||||
|
||||
public function testMultipleLanguagesIsNotIncluded()
|
||||
@@ -36,6 +36,6 @@ class LanguageTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
$choices = $view->vars['choices'];
|
||||
|
||||
$this->assertNotContains(new ChoiceView('mul', 'Mehrsprachig'), $choices, '', false, false);
|
||||
$this->assertNotContains(new ChoiceView('mul', 'mul', 'Mehrsprachig'), $choices, '', false, false);
|
||||
}
|
||||
}
|
||||
|
@@ -23,8 +23,8 @@ class LocaleTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
$choices = $view->vars['choices'];
|
||||
|
||||
$this->assertContains(new ChoiceView('en', 'Englisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('en_GB', 'Englisch (Vereinigtes Königreich)'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('zh_Hant_MO', 'Chinesisch (traditionell, Sonderverwaltungszone Macao)'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('en', 'en', 'Englisch'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('en_GB', 'en_GB', 'Englisch (Vereinigtes Königreich)'), $choices, '', false, false);
|
||||
$this->assertContains(new ChoiceView('zh_Hant_MO', 'zh_Hant_MO', 'Chinesisch (traditionell, Sonderverwaltungszone Macao)'), $choices, '', false, false);
|
||||
}
|
||||
}
|
||||
|
@@ -49,7 +49,7 @@ class RepeatedTypeTest extends TypeTestCase
|
||||
public function testSetOptionsPerChild()
|
||||
{
|
||||
$form = $this->factory->create('repeated', null, array(
|
||||
// the global required value cannot be overriden
|
||||
// the global required value cannot be overridden
|
||||
'type' => 'text',
|
||||
'first_options' => array('label' => 'Test', 'required' => false),
|
||||
'second_options' => array('label' => 'Test2')
|
||||
|
@@ -244,8 +244,8 @@ class TimeTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('6', '06'),
|
||||
new ChoiceView('7', '07'),
|
||||
new ChoiceView('6', '6', '06'),
|
||||
new ChoiceView('7', '7', '07'),
|
||||
), $view['hour']->vars['choices']);
|
||||
}
|
||||
|
||||
@@ -258,8 +258,8 @@ class TimeTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('6', '06'),
|
||||
new ChoiceView('7', '07'),
|
||||
new ChoiceView('6', '6', '06'),
|
||||
new ChoiceView('7', '7', '07'),
|
||||
), $view['minute']->vars['choices']);
|
||||
}
|
||||
|
||||
@@ -273,8 +273,8 @@ class TimeTypeTest extends LocalizedTestCase
|
||||
$view = $form->createView();
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ChoiceView('6', '06'),
|
||||
new ChoiceView('7', '07'),
|
||||
new ChoiceView('6', '6', '06'),
|
||||
new ChoiceView('7', '7', '07'),
|
||||
), $view['second']->vars['choices']);
|
||||
}
|
||||
|
||||
|
@@ -22,9 +22,9 @@ class TimezoneTypeTest extends TypeTestCase
|
||||
$choices = $view->vars['choices'];
|
||||
|
||||
$this->assertArrayHasKey('Africa', $choices);
|
||||
$this->assertContains(new ChoiceView('Africa/Kinshasa', 'Kinshasa'), $choices['Africa'], '', false, false);
|
||||
$this->assertContains(new ChoiceView('Africa/Kinshasa', 'Africa/Kinshasa', 'Kinshasa'), $choices['Africa'], '', false, false);
|
||||
|
||||
$this->assertArrayHasKey('America', $choices);
|
||||
$this->assertContains(new ChoiceView('America/New_York', 'New York'), $choices['America'], '', false, false);
|
||||
$this->assertContains(new ChoiceView('America/New_York', 'America/New_York', 'New York'), $choices['America'], '', false, false);
|
||||
}
|
||||
}
|
||||
|
@@ -9,11 +9,11 @@
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form\Tests\Extension\Core\EventListener;
|
||||
namespace Symfony\Component\Form\Tests\Extension\HttpFoundation\EventListener;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\EventListener\BindRequestListener;
|
||||
use Symfony\Component\Form\Extension\HttpFoundation\EventListener\BindRequestListener;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormConfig;
|
||||
use Symfony\Component\Form\FormConfigBuilder;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
@@ -96,7 +96,7 @@ class BindRequestListenerTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$config = new FormConfig('author', null, $dispatcher);
|
||||
$config = new FormConfigBuilder('author', null, $dispatcher);
|
||||
$form = new Form($config);
|
||||
$event = new FormEvent($form, $request);
|
||||
|
||||
@@ -123,7 +123,7 @@ class BindRequestListenerTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$config = new FormConfig('', null, $dispatcher);
|
||||
$config = new FormConfigBuilder('', null, $dispatcher);
|
||||
$form = new Form($config);
|
||||
$event = new FormEvent($form, $request);
|
||||
|
||||
@@ -150,7 +150,7 @@ class BindRequestListenerTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$config = new FormConfig('author', null, $dispatcher);
|
||||
$config = new FormConfigBuilder('author', null, $dispatcher);
|
||||
$config->setCompound(true);
|
||||
$config->setDataMapper($this->getMock('Symfony\Component\Form\DataMapperInterface'));
|
||||
$form = new Form($config);
|
||||
@@ -177,7 +177,7 @@ class BindRequestListenerTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$config = new FormConfig('author', null, $dispatcher);
|
||||
$config = new FormConfigBuilder('author', null, $dispatcher);
|
||||
$config->setCompound(false);
|
||||
$form = new Form($config);
|
||||
$event = new FormEvent($form, $request);
|
||||
@@ -201,7 +201,7 @@ class BindRequestListenerTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$config = new FormConfig('author', null, $dispatcher);
|
||||
$config = new FormConfigBuilder('author', null, $dispatcher);
|
||||
$form = new Form($config);
|
||||
$event = new FormEvent($form, $request);
|
||||
|
||||
@@ -225,7 +225,7 @@ class BindRequestListenerTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$config = new FormConfig('', null, $dispatcher);
|
||||
$config = new FormConfigBuilder('', null, $dispatcher);
|
||||
$form = new Form($config);
|
||||
$event = new FormEvent($form, $request);
|
||||
|
||||
@@ -249,7 +249,7 @@ class BindRequestListenerTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$config = new FormConfig('author', null, $dispatcher);
|
||||
$config = new FormConfigBuilder('author', null, $dispatcher);
|
||||
$config->setCompound(true);
|
||||
$config->setDataMapper($this->getMock('Symfony\Component\Form\DataMapperInterface'));
|
||||
$form = new Form($config);
|
||||
@@ -272,7 +272,7 @@ class BindRequestListenerTest extends \PHPUnit_Framework_TestCase
|
||||
));
|
||||
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
$config = new FormConfig('author', null, $dispatcher);
|
||||
$config = new FormConfigBuilder('author', null, $dispatcher);
|
||||
$config->setCompound(false);
|
||||
$form = new Form($config);
|
||||
$event = new FormEvent($form, $request);
|
@@ -15,7 +15,7 @@ use Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapper;
|
||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||
use Symfony\Component\Form\CallbackTransformer;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormConfig;
|
||||
use Symfony\Component\Form\FormConfigBuilder;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\Util\PropertyPath;
|
||||
use Symfony\Component\Validator\ConstraintViolation;
|
||||
@@ -67,7 +67,7 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
protected function getForm($name = 'name', $propertyPath = null, $dataClass = null, $errorMapping = array(), $virtual = false, $synchronized = true)
|
||||
{
|
||||
$config = new FormConfig($name, $dataClass, $this->dispatcher, array(
|
||||
$config = new FormConfigBuilder($name, $dataClass, $this->dispatcher, array(
|
||||
'error_mapping' => $errorMapping,
|
||||
));
|
||||
$config->setMapped(true);
|
||||
|
27
vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/AlternatingRowType.php
vendored
Normal file
27
vendor/symfony/symfony/src/Symfony/Component/Form/Tests/Fixtures/AlternatingRowType.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\Form\Tests\Fixtures;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
|
||||
class AlternatingRowType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
$formFactory = $builder->getFormFactory();
|
||||
|
||||
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($formFactory) {
|
||||
$form = $event->getForm();
|
||||
$type = $form->getName() % 2 === 0 ? 'text' : 'textarea';
|
||||
$form->add($formFactory->createNamed('title', $type));
|
||||
});
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'alternating_row';
|
||||
}
|
||||
}
|
@@ -14,7 +14,7 @@ namespace Symfony\Component\Form\Tests;
|
||||
/**
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*/
|
||||
use Symfony\Component\Form\FormConfig;
|
||||
use Symfony\Component\Form\FormConfigBuilder;
|
||||
|
||||
class FormConfigTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
@@ -64,7 +64,7 @@ class FormConfigTest extends \PHPUnit_Framework_TestCase
|
||||
$dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||
|
||||
try {
|
||||
new FormConfig($name, null, $dispatcher);
|
||||
new FormConfigBuilder($name, null, $dispatcher);
|
||||
if (!$accepted) {
|
||||
$this->fail(sprintf('The value "%s" should not be accepted', $name));
|
||||
}
|
||||
|
@@ -44,6 +44,11 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
private $registry;
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $resolvedTypeFactory;
|
||||
|
||||
/**
|
||||
* @var FormFactory
|
||||
*/
|
||||
@@ -55,10 +60,11 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$this->markTestSkipped('The "EventDispatcher" component is not available');
|
||||
}
|
||||
|
||||
$this->resolvedTypeFactory = $this->getMock('Symfony\Component\Form\ResolvedFormTypeFactoryInterface');
|
||||
$this->guesser1 = $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
|
||||
$this->guesser2 = $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
|
||||
$this->registry = $this->getMock('Symfony\Component\Form\FormRegistryInterface');
|
||||
$this->factory = new FormFactory($this->registry);
|
||||
$this->factory = new FormFactory($this->registry, $this->resolvedTypeFactory);
|
||||
|
||||
$this->registry->expects($this->any())
|
||||
->method('getTypeGuesser')
|
||||
@@ -73,8 +79,8 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMockResolvedType();
|
||||
|
||||
$this->registry->expects($this->once())
|
||||
->method('resolveType')
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
@@ -136,16 +142,11 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$type = $this->getMockType();
|
||||
$resolvedType = $this->getMockResolvedType();
|
||||
|
||||
$this->registry->expects($this->once())
|
||||
->method('resolveType')
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
// The type is also implicitely added to the registry
|
||||
$this->registry->expects($this->once())
|
||||
->method('addType')
|
||||
->with($resolvedType);
|
||||
|
||||
$resolvedType->expects($this->once())
|
||||
->method('createBuilder')
|
||||
->with($this->factory, 'name', $options)
|
||||
@@ -159,11 +160,6 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
$options = array('a' => '1', 'b' => '2');
|
||||
$resolvedType = $this->getMockResolvedType();
|
||||
|
||||
// The type is also implicitely added to the registry
|
||||
$this->registry->expects($this->once())
|
||||
->method('addType')
|
||||
->with($resolvedType);
|
||||
|
||||
$resolvedType->expects($this->once())
|
||||
->method('createBuilder')
|
||||
->with($this->factory, 'name', $options)
|
||||
@@ -555,7 +551,7 @@ class FormFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
return $this->getMockBuilder('Symfony\Component\Form\FormFactory')
|
||||
->setMethods($methods)
|
||||
->setConstructorArgs(array($this->registry))
|
||||
->setConstructorArgs(array($this->registry, $this->resolvedTypeFactory))
|
||||
->getMock();
|
||||
}
|
||||
|
||||
|
@@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Form\Tests;
|
||||
|
||||
use Symfony\Component\Form\FormFactory;
|
||||
use Symfony\Component\Form\ResolvedFormTypeFactory;
|
||||
use Symfony\Component\Form\FormRegistry;
|
||||
use Symfony\Component\Form\Extension\Core\CoreExtension;
|
||||
|
||||
@@ -20,6 +21,11 @@ use Symfony\Component\Form\Extension\Core\CoreExtension;
|
||||
*/
|
||||
class FormIntegrationTestCase extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var ResolvedFormTypeFactory
|
||||
*/
|
||||
protected $resolvedTypeFactory;
|
||||
|
||||
/**
|
||||
* @var FormRegistry
|
||||
*/
|
||||
@@ -36,8 +42,9 @@ class FormIntegrationTestCase extends \PHPUnit_Framework_TestCase
|
||||
$this->markTestSkipped('The "EventDispatcher" component is not available');
|
||||
}
|
||||
|
||||
$this->registry = new FormRegistry($this->getExtensions());
|
||||
$this->factory = new FormFactory($this->registry);
|
||||
$this->resolvedTypeFactory = new ResolvedFormTypeFactory();
|
||||
$this->registry = new FormRegistry($this->getExtensions(), $this->resolvedTypeFactory);
|
||||
$this->factory = new FormFactory($this->registry, $this->resolvedTypeFactory);
|
||||
}
|
||||
|
||||
protected function getExtensions()
|
||||
|
@@ -27,6 +27,11 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
private $registry;
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
private $resolvedTypeFactory;
|
||||
|
||||
/**
|
||||
* @var \PHPUnit_Framework_MockObject_MockObject
|
||||
*/
|
||||
@@ -49,6 +54,7 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->resolvedTypeFactory = $this->getMock('Symfony\Component\Form\ResolvedFormTypeFactory');
|
||||
$this->guesser1 = $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
|
||||
$this->guesser2 = $this->getMock('Symfony\Component\Form\FormTypeGuesserInterface');
|
||||
$this->extension1 = new TestExtension($this->guesser1);
|
||||
@@ -56,53 +62,16 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
$this->registry = new FormRegistry(array(
|
||||
$this->extension1,
|
||||
$this->extension2,
|
||||
));
|
||||
}
|
||||
|
||||
public function testResolveType()
|
||||
{
|
||||
$type = new FooType();
|
||||
$ext1 = new FooTypeBarExtension();
|
||||
$ext2 = new FooTypeBazExtension();
|
||||
|
||||
$this->extension1->addTypeExtension($ext1);
|
||||
$this->extension2->addTypeExtension($ext2);
|
||||
|
||||
$resolvedType = $this->registry->resolveType($type);
|
||||
|
||||
$this->assertEquals($type, $resolvedType->getInnerType());
|
||||
$this->assertEquals(array($ext1, $ext2), $resolvedType->getTypeExtensions());
|
||||
}
|
||||
|
||||
public function testResolveTypeConnectsParent()
|
||||
{
|
||||
$parentType = new FooType();
|
||||
$type = new FooSubType();
|
||||
|
||||
$resolvedParentType = $this->registry->resolveType($parentType);
|
||||
|
||||
$this->registry->addType($resolvedParentType);
|
||||
|
||||
$resolvedType = $this->registry->resolveType($type);
|
||||
|
||||
$this->assertSame($resolvedParentType, $resolvedType->getParent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Symfony\Component\Form\Exception\FormException
|
||||
*/
|
||||
public function testResolveTypeThrowsExceptionIfParentNotFound()
|
||||
{
|
||||
$type = new FooSubType();
|
||||
|
||||
$this->registry->resolveType($type);
|
||||
), $this->resolvedTypeFactory);
|
||||
}
|
||||
|
||||
public function testGetTypeReturnsAddedType()
|
||||
{
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$resolvedType = $this->registry->resolveType($type);
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->registry->addType($resolvedType);
|
||||
|
||||
@@ -112,13 +81,88 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
public function testGetTypeFromExtension()
|
||||
{
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$this->extension2->addType($type);
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$resolvedType = $this->registry->getType('foo');
|
||||
|
||||
$this->assertInstanceOf('Symfony\Component\Form\ResolvedFormTypeInterface', $resolvedType);
|
||||
$this->assertSame($type, $resolvedType->getInnerType());
|
||||
$this->assertSame($resolvedType, $this->registry->getType('foo'));
|
||||
}
|
||||
|
||||
public function testGetTypeWithTypeExtensions()
|
||||
{
|
||||
$type = new FooType();
|
||||
$ext1 = new FooTypeBarExtension();
|
||||
$ext2 = new FooTypeBazExtension();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$this->extension2->addType($type);
|
||||
$this->extension1->addTypeExtension($ext1);
|
||||
$this->extension2->addTypeExtension($ext2);
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type, array($ext1, $ext2))
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->assertSame($resolvedType, $this->registry->getType('foo'));
|
||||
}
|
||||
|
||||
public function testGetTypeConnectsParent()
|
||||
{
|
||||
$parentType = new FooType();
|
||||
$type = new FooSubType();
|
||||
$parentResolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$this->extension1->addType($parentType);
|
||||
$this->extension2->addType($type);
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->at(0))
|
||||
->method('createResolvedType')
|
||||
->with($parentType)
|
||||
->will($this->returnValue($parentResolvedType));
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->at(1))
|
||||
->method('createResolvedType')
|
||||
->with($type, array(), $parentResolvedType)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
$parentResolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo_sub_type'));
|
||||
|
||||
$this->assertSame($resolvedType, $this->registry->getType('foo_sub_type'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Symfony\Component\Form\Exception\FormException
|
||||
*/
|
||||
public function testGetTypeThrowsExceptionIfParentNotFound()
|
||||
{
|
||||
$type = new FooSubType();
|
||||
|
||||
$this->extension1->addType($type);
|
||||
|
||||
$this->registry->getType($type);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,9 +183,11 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testHasTypeAfterAdding()
|
||||
{
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$resolvedType = $this->registry->resolveType($type);
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->assertFalse($this->registry->hasType('foo'));
|
||||
|
||||
@@ -153,6 +199,16 @@ class FormRegistryTest extends \PHPUnit_Framework_TestCase
|
||||
public function testHasTypeAfterLoadingFromExtension()
|
||||
{
|
||||
$type = new FooType();
|
||||
$resolvedType = $this->getMock('Symfony\Component\Form\ResolvedFormTypeInterface');
|
||||
|
||||
$this->resolvedTypeFactory->expects($this->once())
|
||||
->method('createResolvedType')
|
||||
->with($type)
|
||||
->will($this->returnValue($resolvedType));
|
||||
|
||||
$resolvedType->expects($this->any())
|
||||
->method('getName')
|
||||
->will($this->returnValue('foo'));
|
||||
|
||||
$this->assertFalse($this->registry->hasType('foo'));
|
||||
|
||||
|
@@ -14,7 +14,7 @@ namespace Symfony\Component\Form\Tests;
|
||||
use Symfony\Component\Form\ResolvedFormType;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\FormBuilder;
|
||||
use Symfony\Component\Form\FormConfig;
|
||||
use Symfony\Component\Form\FormConfigBuilder;
|
||||
use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
|
||||
|
||||
|
@@ -15,7 +15,7 @@ use Symfony\Component\Form\Form;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\Util\PropertyPath;
|
||||
use Symfony\Component\Form\FormConfig;
|
||||
use Symfony\Component\Form\FormConfigBuilder;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||
@@ -34,7 +34,7 @@ class SimpleFormTest extends AbstractFormTest
|
||||
'foo' => 'bar',
|
||||
));
|
||||
|
||||
$config = new FormConfig('name', null, $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', null, $this->dispatcher);
|
||||
$config->addViewTransformer($view);
|
||||
$config->addModelTransformer($model);
|
||||
$config->setData('default');
|
||||
@@ -45,6 +45,28 @@ class SimpleFormTest extends AbstractFormTest
|
||||
$this->assertSame('bar', $form->getViewData());
|
||||
}
|
||||
|
||||
// https://github.com/symfony/symfony/commit/d4f4038f6daf7cf88ca7c7ab089473cce5ebf7d8#commitcomment-1632879
|
||||
public function testDataIsInitializedFromBind()
|
||||
{
|
||||
$mock = $this->getMockBuilder('\stdClass')
|
||||
->setMethods(array('preSetData', 'preBind'))
|
||||
->getMock();
|
||||
$mock->expects($this->at(0))
|
||||
->method('preSetData');
|
||||
$mock->expects($this->at(1))
|
||||
->method('preBind');
|
||||
|
||||
$config = new FormConfigBuilder('name', null, $this->dispatcher);
|
||||
$config->addEventListener(FormEvents::PRE_SET_DATA, array($mock, 'preSetData'));
|
||||
$config->addEventListener(FormEvents::PRE_BIND, array($mock, 'preBind'));
|
||||
$form = new Form($config);
|
||||
|
||||
// no call to setData() or similar where the object would be
|
||||
// initialized otherwise
|
||||
|
||||
$form->bind('foobar');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Symfony\Component\Form\Exception\AlreadyBoundException
|
||||
*/
|
||||
@@ -694,7 +716,7 @@ class SimpleFormTest extends AbstractFormTest
|
||||
*/
|
||||
public function testViewDataMustNotBeObjectIfDataClassIsNull()
|
||||
{
|
||||
$config = new FormConfig('name', null, $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', null, $this->dispatcher);
|
||||
$config->addViewTransformer(new FixedDataTransformer(array(
|
||||
'' => '',
|
||||
'foo' => new \stdClass(),
|
||||
@@ -707,7 +729,7 @@ class SimpleFormTest extends AbstractFormTest
|
||||
public function testViewDataMayBeArrayAccessIfDataClassIsNull()
|
||||
{
|
||||
$arrayAccess = $this->getMock('\ArrayAccess');
|
||||
$config = new FormConfig('name', null, $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', null, $this->dispatcher);
|
||||
$config->addViewTransformer(new FixedDataTransformer(array(
|
||||
'' => '',
|
||||
'foo' => $arrayAccess,
|
||||
@@ -724,7 +746,7 @@ class SimpleFormTest extends AbstractFormTest
|
||||
*/
|
||||
public function testViewDataMustBeObjectIfDataClassIsSet()
|
||||
{
|
||||
$config = new FormConfig('name', 'stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', 'stdClass', $this->dispatcher);
|
||||
$config->addViewTransformer(new FixedDataTransformer(array(
|
||||
'' => '',
|
||||
'foo' => array('bar' => 'baz'),
|
||||
@@ -740,7 +762,7 @@ class SimpleFormTest extends AbstractFormTest
|
||||
public function testSetDataCannotInvokeItself()
|
||||
{
|
||||
// Cycle detection to prevent endless loops
|
||||
$config = new FormConfig('name', 'stdClass', $this->dispatcher);
|
||||
$config = new FormConfigBuilder('name', 'stdClass', $this->dispatcher);
|
||||
$config->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
|
||||
$event->getForm()->setData('bar');
|
||||
});
|
||||
|
@@ -587,9 +587,9 @@ class PropertyPath implements \IteratorAggregate, PropertyPathInterface
|
||||
* Searches for add and remove methods.
|
||||
*
|
||||
* @param \ReflectionClass $reflClass The reflection class for the given object
|
||||
* @param string|null $singular The singular form of the property name or null.
|
||||
* @param string|null $singulars The singular form of the property name or null.
|
||||
*
|
||||
* @return array|null An array containin the adder and remover when found, null otherwise.
|
||||
* @return array|null An array containing the adder and remover when found, null otherwise.
|
||||
*
|
||||
* @throws InvalidPropertyException If the property does not exist.
|
||||
*/
|
||||
|
@@ -39,24 +39,9 @@ class RedirectResponse extends Response
|
||||
throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
|
||||
}
|
||||
|
||||
$this->targetUrl = $url;
|
||||
parent::__construct('', $status, $headers);
|
||||
|
||||
parent::__construct(
|
||||
sprintf('<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="refresh" content="1;url=%1$s" />
|
||||
|
||||
<title>Redirecting to %1$s</title>
|
||||
</head>
|
||||
<body>
|
||||
Redirecting to <a href="%1$s">%1$s</a>.
|
||||
</body>
|
||||
</html>', htmlspecialchars($url, ENT_QUOTES, 'UTF-8')),
|
||||
$status,
|
||||
array_merge($headers, array('Location' => $url))
|
||||
);
|
||||
$this->setTargetUrl($url);
|
||||
|
||||
if (!$this->isRedirect()) {
|
||||
throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status));
|
||||
@@ -80,4 +65,38 @@ class RedirectResponse extends Response
|
||||
{
|
||||
return $this->targetUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the redirect target of this response.
|
||||
*
|
||||
* @param string $url The URL to redirect to
|
||||
*
|
||||
* @return RedirectResponse The current response.
|
||||
*/
|
||||
public function setTargetUrl($url)
|
||||
{
|
||||
if (empty($url)) {
|
||||
throw new \InvalidArgumentException('Cannot redirect to an empty URL.');
|
||||
}
|
||||
|
||||
$this->targetUrl = $url;
|
||||
|
||||
$this->setContent(
|
||||
sprintf('<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta http-equiv="refresh" content="1;url=%1$s" />
|
||||
|
||||
<title>Redirecting to %1$s</title>
|
||||
</head>
|
||||
<body>
|
||||
Redirecting to <a href="%1$s">%1$s</a>.
|
||||
</body>
|
||||
</html>', htmlspecialchars($url, ENT_QUOTES, 'UTF-8')));
|
||||
|
||||
$this->headers->set('Location', $url);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user