Merge remote branch 'bschussek/form'
* bschussek/form: (22 commits) Fix merge error (function "guess" was in there twice) [Form] Added test case forbf2f9d2a02
[Form] Form::isBound() and Form::isValid() work correctly now for read-only forms [Locale] Improved error reporting and added stubs for intl_is_failure(), intl_get_error_code() and intl_get_error_message() [Form] Implemented fix for361c67f54f
[Form] Add test for the handling of array values in the constraint violation [Form] Further simplified PropertyPath code [Form] Added test for6c337d1cc0
[Form] Removed unused option "pattern" of date and time type [Form] Renamed view variable "name" to "full_name" [Form] Renamed collection option "type_options" to "options" to be consistent with the repeated type [Form] CSRF documentation and a few CS changes [Form] Move CSRF options from types to the CSRF extension [Form] Added a search form field type [Form] Optimization of PropertyPath [Form] replace assertEquals by assertFalse, assertTrue, assertNull [Form] fix file permissions to 644 again ;) [Form] add tests for type_options in collectionType fix file permissions to 644 [Form] add type_options for CollectionType to be abble to set options to type ...
This commit is contained in:
commit
9fe1c3ae0e
@ -167,6 +167,9 @@ beta1 to beta2
|
|||||||
* Form: Renamed option value "text" of "widget" option of the "date" type was
|
* Form: Renamed option value "text" of "widget" option of the "date" type was
|
||||||
renamed to "single-text". "text" indicates to use separate text boxes now
|
renamed to "single-text". "text" indicates to use separate text boxes now
|
||||||
(like for the "time" type).
|
(like for the "time" type).
|
||||||
|
|
||||||
|
* Form: Renamed view variable "name" to "full_name". The variable "name" now
|
||||||
|
contains the local, short name (equivalent to $form->getName()).
|
||||||
|
|
||||||
PR12 to beta1
|
PR12 to beta1
|
||||||
-------------
|
-------------
|
||||||
|
@ -180,4 +180,12 @@ class DoctrineOrmTypeGuesser implements FormTypeGuesserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function guessMinLength($class, $property)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,9 @@
|
|||||||
<service id="form.type.repeated" class="Symfony\Component\Form\Extension\Core\Type\RepeatedType">
|
<service id="form.type.repeated" class="Symfony\Component\Form\Extension\Core\Type\RepeatedType">
|
||||||
<tag name="form.type" alias="repeated" />
|
<tag name="form.type" alias="repeated" />
|
||||||
</service>
|
</service>
|
||||||
|
<service id="form.type.search" class="Symfony\Component\Form\Extension\Core\Type\SearchType">
|
||||||
|
<tag name="form.type" alias="search" />
|
||||||
|
</service>
|
||||||
<service id="form.type.textarea" class="Symfony\Component\Form\Extension\Core\Type\TextareaType">
|
<service id="form.type.textarea" class="Symfony\Component\Form\Extension\Core\Type\TextareaType">
|
||||||
<tag name="form.type" alias="textarea" />
|
<tag name="form.type" alias="textarea" />
|
||||||
</service>
|
</service>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
<?php if ($value): ?>value="<?php echo $view->escape($value) ?>"<?php endif ?>
|
<?php if ($value): ?>value="<?php echo $view->escape($value) ?>"<?php endif ?>
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<select
|
<select
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
<?php if ($read_only): ?> disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?> disabled="disabled"<?php endif ?>
|
||||||
<?php if ($multiple): ?> multiple="multiple"<?php endif ?>
|
<?php if ($multiple): ?> multiple="multiple"<?php endif ?>
|
||||||
>
|
>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?php if ($widget == 'single-text'): ?>
|
<?php if ($widget == 'single-text'): ?>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<input type="email"
|
<input type="email"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($max_length): ?>maxlength="<?php echo $view->escape($max_length) ?>"<?php endif ?>
|
<?php if ($max_length): ?>maxlength="<?php echo $view->escape($max_length) ?>"<?php endif ?>
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<input
|
<input
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<input type="hidden"
|
<input type="hidden"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
/>
|
/>
|
@ -1,6 +1,6 @@
|
|||||||
<input type="number"
|
<input type="number"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
<input type="text"
|
<input type="text"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
<?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
|
<?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
|
||||||
|
<?php if ($pattern): ?>pattern="<?php echo $pattern ?>"<?php endif ?>
|
||||||
/>
|
/>
|
@ -1,8 +1,9 @@
|
|||||||
<input type="password"
|
<input type="password"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
<?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
|
<?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
|
||||||
|
<?php if ($pattern): ?>pattern="<?php echo $pattern ?>"<?php endif ?>
|
||||||
/>
|
/>
|
@ -1,6 +1,6 @@
|
|||||||
<input type="radio"
|
<input type="radio"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
<input type="search"
|
||||||
|
<?php echo $view['form']->attributes() ?>
|
||||||
|
name="<?php echo $view->escape($name) ?>"
|
||||||
|
value="<?php echo $view->escape($value) ?>"
|
||||||
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
|
<?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
|
||||||
|
/>
|
@ -1,8 +1,9 @@
|
|||||||
<input type="text"
|
<input type="text"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
<?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
|
<?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
|
||||||
|
<?php if ($pattern): ?>pattern="<?php echo $pattern ?>"<?php endif ?>
|
||||||
/>
|
/>
|
@ -1,6 +1,6 @@
|
|||||||
<textarea
|
<textarea
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
><?php echo $view->escape($value) ?></textarea>
|
><?php echo $view->escape($value) ?></textarea>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<input type="url"
|
<input type="url"
|
||||||
<?php echo $view['form']->attributes() ?>
|
<?php echo $view['form']->attributes() ?>
|
||||||
name="<?php echo $view->escape($name) ?>"
|
name="<?php echo $view->escape($full_name) ?>"
|
||||||
value="<?php echo $view->escape($value) ?>"
|
value="<?php echo $view->escape($value) ?>"
|
||||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||||
<?php if ($required): ?>required="required"<?php endif ?>
|
<?php if ($required): ?>required="required"<?php endif ?>
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
{% block attributes %}
|
{% block attributes %}
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
id="{{ id }}" name="{{ name }}"{% if read_only %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}
|
id="{{ id }}" name="{{ full_name }}"{% if read_only %} disabled="disabled"{% endif %}{% if required %} required="required"{% endif %}{% if max_length %} maxlength="{{ max_length }}"{% endif %}{% if pattern %} pattern="{{ pattern }}"{% endif %}
|
||||||
{% for attrname,attrvalue in attr %}{{attrname}}="{{attrvalue}}" {% endfor %}
|
{% for attrname,attrvalue in attr %}{{attrname}}="{{attrvalue}}" {% endfor %}
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endblock attributes %}
|
{% endblock attributes %}
|
||||||
@ -208,6 +208,13 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endblock url_widget %}
|
{% endblock url_widget %}
|
||||||
|
|
||||||
|
{% block search_widget %}
|
||||||
|
{% spaceless %}
|
||||||
|
{% set type = type|default('search') %}
|
||||||
|
{{ block('field_widget') }}
|
||||||
|
{% endspaceless %}
|
||||||
|
{% endblock search_widget %}
|
||||||
|
|
||||||
{% block percent_widget %}
|
{% block percent_widget %}
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
{% set type = type|default('text') %}
|
{% set type = type|default('text') %}
|
||||||
|
@ -52,6 +52,7 @@ class CoreExtension extends AbstractExtension
|
|||||||
new Type\PercentType(),
|
new Type\PercentType(),
|
||||||
new Type\RadioType(),
|
new Type\RadioType(),
|
||||||
new Type\RepeatedType(),
|
new Type\RepeatedType(),
|
||||||
|
new Type\SearchType(),
|
||||||
new Type\TextareaType(),
|
new Type\TextareaType(),
|
||||||
new Type\TextType(),
|
new Type\TextType(),
|
||||||
new Type\TimeType(),
|
new Type\TimeType(),
|
||||||
|
@ -35,6 +35,11 @@ class ResizeFormListener implements EventSubscriberInterface
|
|||||||
*/
|
*/
|
||||||
private $type;
|
private $type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private $options;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether children could be added to the group
|
* Whether children could be added to the group
|
||||||
* @var Boolean
|
* @var Boolean
|
||||||
@ -47,12 +52,13 @@ class ResizeFormListener implements EventSubscriberInterface
|
|||||||
*/
|
*/
|
||||||
private $allowDelete;
|
private $allowDelete;
|
||||||
|
|
||||||
public function __construct(FormFactoryInterface $factory, $type, $allowAdd = false, $allowDelete = false)
|
public function __construct(FormFactoryInterface $factory, $type, array $options = array(), $allowAdd = false, $allowDelete = false)
|
||||||
{
|
{
|
||||||
$this->factory = $factory;
|
$this->factory = $factory;
|
||||||
$this->type = $type;
|
$this->type = $type;
|
||||||
$this->allowAdd = $allowAdd;
|
$this->allowAdd = $allowAdd;
|
||||||
$this->allowDelete = $allowDelete;
|
$this->allowDelete = $allowDelete;
|
||||||
|
$this->options = $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getSubscribedEvents()
|
public static function getSubscribedEvents()
|
||||||
@ -86,9 +92,9 @@ class ResizeFormListener implements EventSubscriberInterface
|
|||||||
|
|
||||||
// Then add all rows again in the correct order
|
// Then add all rows again in the correct order
|
||||||
foreach ($data as $name => $value) {
|
foreach ($data as $name => $value) {
|
||||||
$form->add($this->factory->createNamed($this->type, $name, null, array(
|
$form->add($this->factory->createNamed($this->type, $name, null, array_replace(array(
|
||||||
'property_path' => '['.$name.']',
|
'property_path' => '['.$name.']',
|
||||||
)));
|
), $this->options)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,9 +124,9 @@ class ResizeFormListener implements EventSubscriberInterface
|
|||||||
if ($this->allowAdd) {
|
if ($this->allowAdd) {
|
||||||
foreach ($data as $name => $value) {
|
foreach ($data as $name => $value) {
|
||||||
if (!$form->has($name)) {
|
if (!$form->has($name)) {
|
||||||
$form->add($this->factory->createNamed($this->type, $name, null, array(
|
$form->add($this->factory->createNamed($this->type, $name, null, array_replace(array(
|
||||||
'property_path' => '['.$name.']',
|
'property_path' => '['.$name.']',
|
||||||
)));
|
), $this->options)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,4 +155,4 @@ class ResizeFormListener implements EventSubscriberInterface
|
|||||||
|
|
||||||
$event->setData($data);
|
$event->setData($data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ class ChoiceType extends AbstractType
|
|||||||
// Add "[]" to the name in case a select tag with multiple options is
|
// Add "[]" to the name in case a select tag with multiple options is
|
||||||
// displayed. Otherwise only one of the selected options is sent in the
|
// displayed. Otherwise only one of the selected options is sent in the
|
||||||
// POST request.
|
// POST request.
|
||||||
$view->set('name', $view->get('name').'[]');
|
$view->set('full_name', $view->get('full_name').'[]');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +121,6 @@ class ChoiceType extends AbstractType
|
|||||||
'choice_list' => null,
|
'choice_list' => null,
|
||||||
'choices' => array(),
|
'choices' => array(),
|
||||||
'preferred_choices' => array(),
|
'preferred_choices' => array(),
|
||||||
'csrf_protection' => false,
|
|
||||||
'empty_data' => $multiple || $expanded ? array() : '',
|
'empty_data' => $multiple || $expanded ? array() : '',
|
||||||
'error_bubbling' => false,
|
'error_bubbling' => false,
|
||||||
);
|
);
|
||||||
|
@ -22,15 +22,16 @@ class CollectionType extends AbstractType
|
|||||||
public function buildForm(FormBuilder $builder, array $options)
|
public function buildForm(FormBuilder $builder, array $options)
|
||||||
{
|
{
|
||||||
if ($options['allow_add'] && $options['prototype']) {
|
if ($options['allow_add'] && $options['prototype']) {
|
||||||
$builder->add('$$name$$', $options['type'], array(
|
$builder->add('$$name$$', $options['type'], array_replace(array(
|
||||||
'property_path' => false,
|
'property_path' => false,
|
||||||
'required' => false,
|
'required' => false,
|
||||||
));
|
), $options['options']));
|
||||||
}
|
}
|
||||||
|
|
||||||
$listener = new ResizeFormListener(
|
$listener = new ResizeFormListener(
|
||||||
$builder->getFormFactory(),
|
$builder->getFormFactory(),
|
||||||
$options['type'],
|
$options['type'],
|
||||||
|
$options['options'],
|
||||||
$options['allow_add'],
|
$options['allow_add'],
|
||||||
$options['allow_delete']
|
$options['allow_delete']
|
||||||
);
|
);
|
||||||
@ -57,6 +58,7 @@ class CollectionType extends AbstractType
|
|||||||
'allow_delete' => false,
|
'allow_delete' => false,
|
||||||
'prototype' => true,
|
'prototype' => true,
|
||||||
'type' => 'text',
|
'type' => 'text',
|
||||||
|
'options' => array(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,9 +37,6 @@ class DateTimeType extends AbstractType
|
|||||||
'with_seconds',
|
'with_seconds',
|
||||||
)));
|
)));
|
||||||
|
|
||||||
if (isset($options['date_pattern'])) {
|
|
||||||
$dateOptions['pattern'] = $options['date_pattern'];
|
|
||||||
}
|
|
||||||
if (isset($options['date_widget'])) {
|
if (isset($options['date_widget'])) {
|
||||||
$dateOptions['widget'] = $options['date_widget'];
|
$dateOptions['widget'] = $options['date_widget'];
|
||||||
}
|
}
|
||||||
@ -49,9 +46,6 @@ class DateTimeType extends AbstractType
|
|||||||
|
|
||||||
$dateOptions['input'] = 'array';
|
$dateOptions['input'] = 'array';
|
||||||
|
|
||||||
if (isset($options['time_pattern'])) {
|
|
||||||
$timeOptions['pattern'] = $options['time_pattern'];
|
|
||||||
}
|
|
||||||
if (isset($options['time_widget'])) {
|
if (isset($options['time_widget'])) {
|
||||||
$timeOptions['widget'] = $options['time_widget'];
|
$timeOptions['widget'] = $options['time_widget'];
|
||||||
}
|
}
|
||||||
@ -103,10 +97,8 @@ class DateTimeType extends AbstractType
|
|||||||
// Don't modify \DateTime classes by reference, we treat
|
// Don't modify \DateTime classes by reference, we treat
|
||||||
// them like immutable value objects
|
// them like immutable value objects
|
||||||
'by_reference' => false,
|
'by_reference' => false,
|
||||||
'date_pattern' => null,
|
|
||||||
'date_widget' => null,
|
'date_widget' => null,
|
||||||
'date_format' => null,
|
'date_format' => null,
|
||||||
'time_pattern' => null,
|
|
||||||
'time_widget' => null,
|
'time_widget' => null,
|
||||||
/* Defaults for date field */
|
/* Defaults for date field */
|
||||||
'years' => range(date('Y') - 5, date('Y') + 5),
|
'years' => range(date('Y') - 5, date('Y') + 5),
|
||||||
|
@ -119,11 +119,9 @@ class DateType extends AbstractType
|
|||||||
'days' => range(1, 31),
|
'days' => range(1, 31),
|
||||||
'widget' => 'choice',
|
'widget' => 'choice',
|
||||||
'input' => 'datetime',
|
'input' => 'datetime',
|
||||||
'pattern' => null,
|
|
||||||
'format' => \IntlDateFormatter::MEDIUM,
|
'format' => \IntlDateFormatter::MEDIUM,
|
||||||
'data_timezone' => null,
|
'data_timezone' => null,
|
||||||
'user_timezone' => null,
|
'user_timezone' => null,
|
||||||
'csrf_protection' => false,
|
|
||||||
// Don't modify \DateTime classes by reference, we treat
|
// Don't modify \DateTime classes by reference, we treat
|
||||||
// them like immutable value objects
|
// them like immutable value objects
|
||||||
'by_reference' => false,
|
'by_reference' => false,
|
||||||
|
@ -44,6 +44,7 @@ class FieldType extends AbstractType
|
|||||||
->setAttribute('property_path', $options['property_path'])
|
->setAttribute('property_path', $options['property_path'])
|
||||||
->setAttribute('error_mapping', $options['error_mapping'])
|
->setAttribute('error_mapping', $options['error_mapping'])
|
||||||
->setAttribute('max_length', $options['max_length'])
|
->setAttribute('max_length', $options['max_length'])
|
||||||
|
->setAttribute('pattern', $options['pattern'])
|
||||||
->setAttribute('label', $options['label'] ?: $this->humanize($builder->getName()))
|
->setAttribute('label', $options['label'] ?: $this->humanize($builder->getName()))
|
||||||
->setData($options['data'])
|
->setData($options['data'])
|
||||||
->addValidator(new DefaultValidator())
|
->addValidator(new DefaultValidator())
|
||||||
@ -58,7 +59,7 @@ class FieldType extends AbstractType
|
|||||||
{
|
{
|
||||||
if ($view->hasParent()) {
|
if ($view->hasParent()) {
|
||||||
$parentId = $view->getParent()->get('id');
|
$parentId = $view->getParent()->get('id');
|
||||||
$parentName = $view->getParent()->get('name');
|
$parentName = $view->getParent()->get('full_name');
|
||||||
$id = sprintf('%s_%s', $parentId, $form->getName());
|
$id = sprintf('%s_%s', $parentId, $form->getName());
|
||||||
$name = sprintf('%s[%s]', $parentName, $form->getName());
|
$name = sprintf('%s[%s]', $parentName, $form->getName());
|
||||||
} else {
|
} else {
|
||||||
@ -69,12 +70,14 @@ class FieldType extends AbstractType
|
|||||||
$view
|
$view
|
||||||
->set('form', $view)
|
->set('form', $view)
|
||||||
->set('id', $id)
|
->set('id', $id)
|
||||||
->set('name', $name)
|
->set('name', $form->getName())
|
||||||
|
->set('full_name', $name)
|
||||||
->set('errors', $form->getErrors())
|
->set('errors', $form->getErrors())
|
||||||
->set('value', $form->getClientData())
|
->set('value', $form->getClientData())
|
||||||
->set('read_only', $form->isReadOnly())
|
->set('read_only', $form->isReadOnly())
|
||||||
->set('required', $form->isRequired())
|
->set('required', $form->isRequired())
|
||||||
->set('max_length', $form->getAttribute('max_length'))
|
->set('max_length', $form->getAttribute('max_length'))
|
||||||
|
->set('pattern', $form->getAttribute('pattern'))
|
||||||
->set('size', null)
|
->set('size', null)
|
||||||
->set('label', $form->getAttribute('label'))
|
->set('label', $form->getAttribute('label'))
|
||||||
->set('multipart', false)
|
->set('multipart', false)
|
||||||
@ -97,6 +100,7 @@ class FieldType extends AbstractType
|
|||||||
'required' => true,
|
'required' => true,
|
||||||
'read_only' => false,
|
'read_only' => false,
|
||||||
'max_length' => null,
|
'max_length' => null,
|
||||||
|
'pattern' => null,
|
||||||
'property_path' => null,
|
'property_path' => null,
|
||||||
'by_reference' => true,
|
'by_reference' => true,
|
||||||
'error_bubbling' => false,
|
'error_bubbling' => false,
|
||||||
|
@ -52,13 +52,13 @@ class FileType extends AbstractType
|
|||||||
{
|
{
|
||||||
$view->set('multipart', true);
|
$view->set('multipart', true);
|
||||||
$view['file']->set('type', 'file');
|
$view['file']->set('type', 'file');
|
||||||
|
$view['file']->set('value', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultOptions(array $options)
|
public function getDefaultOptions(array $options)
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'csrf_protection' => false,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class RadioType extends AbstractType
|
|||||||
;
|
;
|
||||||
|
|
||||||
if ($view->hasParent()) {
|
if ($view->hasParent()) {
|
||||||
$view->set('name', $view->getParent()->get('name'));
|
$view->set('full_name', $view->getParent()->get('full_name'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ class RepeatedType extends AbstractType
|
|||||||
'options' => array(),
|
'options' => array(),
|
||||||
'first_name' => 'first',
|
'first_name' => 'first',
|
||||||
'second_name' => 'second',
|
'second_name' => 'second',
|
||||||
'csrf_protection' => false,
|
|
||||||
'error_bubbling' => false,
|
'error_bubbling' => false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Core\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
|
||||||
|
class SearchType extends AbstractType
|
||||||
|
{
|
||||||
|
public function getParent(array $options)
|
||||||
|
{
|
||||||
|
return 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return 'search';
|
||||||
|
}
|
||||||
|
}
|
@ -94,10 +94,8 @@ class TimeType extends AbstractType
|
|||||||
'widget' => 'choice',
|
'widget' => 'choice',
|
||||||
'input' => 'datetime',
|
'input' => 'datetime',
|
||||||
'with_seconds' => false,
|
'with_seconds' => false,
|
||||||
'pattern' => null,
|
|
||||||
'data_timezone' => null,
|
'data_timezone' => null,
|
||||||
'user_timezone' => null,
|
'user_timezone' => null,
|
||||||
'csrf_protection' => false,
|
|
||||||
// Don't modify \DateTime classes by reference, we treat
|
// Don't modify \DateTime classes by reference, we treat
|
||||||
// them like immutable value objects
|
// them like immutable value objects
|
||||||
'by_reference' => false,
|
'by_reference' => false,
|
||||||
|
@ -15,15 +15,26 @@ use Symfony\Component\Form\Extension\Csrf\Type;
|
|||||||
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
|
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
|
||||||
use Symfony\Component\Form\AbstractExtension;
|
use Symfony\Component\Form\AbstractExtension;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This extension protects forms by using a CSRF token
|
||||||
|
*/
|
||||||
class CsrfExtension extends AbstractExtension
|
class CsrfExtension extends AbstractExtension
|
||||||
{
|
{
|
||||||
private $csrfProvider;
|
private $csrfProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param CsrfProviderInterface $csrfProvider The CSRF provider
|
||||||
|
*/
|
||||||
public function __construct(CsrfProviderInterface $csrfProvider)
|
public function __construct(CsrfProviderInterface $csrfProvider)
|
||||||
{
|
{
|
||||||
$this->csrfProvider = $csrfProvider;
|
$this->csrfProvider = $csrfProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected function loadTypes()
|
protected function loadTypes()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
@ -31,10 +42,18 @@ class CsrfExtension extends AbstractExtension
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected function loadTypeExtensions()
|
protected function loadTypeExtensions()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
new Type\ChoiceTypeCsrfExtension(),
|
||||||
|
new Type\DateTypeCsrfExtension(),
|
||||||
|
new Type\FileTypeCsrfExtension(),
|
||||||
new Type\FormTypeCsrfExtension(),
|
new Type\FormTypeCsrfExtension(),
|
||||||
|
new Type\RepeatedTypeCsrfExtension(),
|
||||||
|
new Type\TimeTypeCsrfExtension(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Csrf\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
|
||||||
|
class ChoiceTypeCsrfExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
public function getDefaultOptions(array $options)
|
||||||
|
{
|
||||||
|
return array('csrf_protection' => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExtendedType()
|
||||||
|
{
|
||||||
|
return 'choice';
|
||||||
|
}
|
||||||
|
}
|
@ -22,11 +22,25 @@ class CsrfType extends AbstractType
|
|||||||
{
|
{
|
||||||
private $csrfProvider;
|
private $csrfProvider;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param CsrfProviderInterface $csrfProvider The provider to use to generate the token
|
||||||
|
*/
|
||||||
public function __construct(CsrfProviderInterface $csrfProvider)
|
public function __construct(CsrfProviderInterface $csrfProvider)
|
||||||
{
|
{
|
||||||
$this->csrfProvider = $csrfProvider;
|
$this->csrfProvider = $csrfProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the CSRF field.
|
||||||
|
*
|
||||||
|
* A validator is added to check the token value when the CSRF field is added to
|
||||||
|
* a root form
|
||||||
|
*
|
||||||
|
* @param FormBuilder $builder The form builder
|
||||||
|
* @param array $options The options
|
||||||
|
*/
|
||||||
public function buildForm(FormBuilder $builder, array $options)
|
public function buildForm(FormBuilder $builder, array $options)
|
||||||
{
|
{
|
||||||
$csrfProvider = $options['csrf_provider'];
|
$csrfProvider = $options['csrf_provider'];
|
||||||
@ -47,20 +61,31 @@ class CsrfType extends AbstractType
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public function getDefaultOptions(array $options)
|
public function getDefaultOptions(array $options)
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'csrf_provider' => $this->csrfProvider,
|
'csrf_provider' => $this->csrfProvider,
|
||||||
'intention' => null,
|
'intention' => null,
|
||||||
'property_path' => false,
|
'property_path' => false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public function getParent(array $options)
|
public function getParent(array $options)
|
||||||
{
|
{
|
||||||
return 'hidden';
|
return 'hidden';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of this form.
|
||||||
|
*
|
||||||
|
* @return string 'csrf'
|
||||||
|
*/
|
||||||
public function getName()
|
public function getName()
|
||||||
{
|
{
|
||||||
return 'csrf';
|
return 'csrf';
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Csrf\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
|
||||||
|
class DateTypeCsrfExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
public function getDefaultOptions(array $options)
|
||||||
|
{
|
||||||
|
return array('csrf_protection' => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExtendedType()
|
||||||
|
{
|
||||||
|
return 'date';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Csrf\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
|
||||||
|
class FileTypeCsrfExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
public function getDefaultOptions(array $options)
|
||||||
|
{
|
||||||
|
return array('csrf_protection' => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExtendedType()
|
||||||
|
{
|
||||||
|
return 'file';
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,12 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
|
|||||||
$this->fieldName = $fieldName;
|
$this->fieldName = $fieldName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a CSRF field to the form when the CSRF protection is enabled.
|
||||||
|
*
|
||||||
|
* @param FormBuilder $builder The form builder
|
||||||
|
* @param array $options The options
|
||||||
|
*/
|
||||||
public function buildForm(FormBuilder $builder, array $options)
|
public function buildForm(FormBuilder $builder, array $options)
|
||||||
{
|
{
|
||||||
if ($options['csrf_protection']) {
|
if ($options['csrf_protection']) {
|
||||||
@ -36,11 +42,19 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
|
|||||||
$csrfOptions['csrf_provider'] = $options['csrf_provider'];
|
$csrfOptions['csrf_provider'] = $options['csrf_provider'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$builder->add($options['csrf_field_name'], 'csrf', $csrfOptions)
|
$builder
|
||||||
->setAttribute('csrf_field_name', $options['csrf_field_name']);
|
->add($options['csrf_field_name'], 'csrf', $csrfOptions)
|
||||||
|
->setAttribute('csrf_field_name', $options['csrf_field_name'])
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes CSRF fields from all the form views except the root one.
|
||||||
|
*
|
||||||
|
* @param FormView $view The form view
|
||||||
|
* @param FormInterface $form The form
|
||||||
|
*/
|
||||||
public function buildViewBottomUp(FormView $view, FormInterface $form)
|
public function buildViewBottomUp(FormView $view, FormInterface $form)
|
||||||
{
|
{
|
||||||
if ($view->hasParent() && $form->hasAttribute('csrf_field_name')) {
|
if ($view->hasParent() && $form->hasAttribute('csrf_field_name')) {
|
||||||
@ -52,16 +66,22 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public function getDefaultOptions(array $options)
|
public function getDefaultOptions(array $options)
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'csrf_protection' => $this->enabled,
|
'csrf_protection' => $this->enabled,
|
||||||
'csrf_field_name' => $this->fieldName,
|
'csrf_field_name' => $this->fieldName,
|
||||||
'csrf_provider' => null,
|
'csrf_provider' => null,
|
||||||
'intention' => 'unknown',
|
'intention' => 'unknown',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public function getExtendedType()
|
public function getExtendedType()
|
||||||
{
|
{
|
||||||
return 'form';
|
return 'form';
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Csrf\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
|
||||||
|
class RepeatedTypeCsrfExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
public function getDefaultOptions(array $options)
|
||||||
|
{
|
||||||
|
return array('csrf_protection' => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExtendedType()
|
||||||
|
{
|
||||||
|
return 'repeated';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Form\Extension\Csrf\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractTypeExtension;
|
||||||
|
|
||||||
|
class TimeTypeCsrfExtension extends AbstractTypeExtension
|
||||||
|
{
|
||||||
|
public function getDefaultOptions(array $options)
|
||||||
|
{
|
||||||
|
return array('csrf_protection' => false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExtendedType()
|
||||||
|
{
|
||||||
|
return 'time';
|
||||||
|
}
|
||||||
|
}
|
@ -63,6 +63,18 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function guessMinLength($class, $property)
|
||||||
|
{
|
||||||
|
$guesser = $this;
|
||||||
|
|
||||||
|
return $this->guess($class, $property, function (Constraint $constraint) use ($guesser) {
|
||||||
|
return $guesser->guessMinLengthForConstraint($constraint);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Guesses a field class name for a given constraint
|
* Guesses a field class name for a given constraint
|
||||||
*
|
*
|
||||||
@ -266,6 +278,28 @@ class ValidatorTypeGuesser implements FormTypeGuesserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guesses a field's minimum length based on the given constraint
|
||||||
|
*
|
||||||
|
* @param Constraint $constraint The constraint to guess for
|
||||||
|
* @return Guess The guess for the minimum length
|
||||||
|
*/
|
||||||
|
public function guessMinLengthForConstraint(Constraint $constraint)
|
||||||
|
{
|
||||||
|
switch (get_class($constraint)) {
|
||||||
|
case 'Symfony\Component\Validator\Constraints\MinLength':
|
||||||
|
return new ValueGuess(
|
||||||
|
$constraint->limit,
|
||||||
|
Guess::HIGH_CONFIDENCE
|
||||||
|
);
|
||||||
|
case 'Symfony\Component\Validator\Constraints\Min':
|
||||||
|
return new ValueGuess(
|
||||||
|
strlen((string)$constraint->limit),
|
||||||
|
Guess::HIGH_CONFIDENCE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterates over the constraints of a property, executes a constraints on
|
* Iterates over the constraints of a property, executes a constraints on
|
||||||
* them and returns the best guess
|
* them and returns the best guess
|
||||||
|
@ -24,13 +24,6 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|||||||
*
|
*
|
||||||
* A form is composed of a validator schema and a widget form schema.
|
* A form is composed of a validator schema and a widget form schema.
|
||||||
*
|
*
|
||||||
* Form also takes care of CSRF protection by default.
|
|
||||||
*
|
|
||||||
* A CSRF secret can be any random string. If set to false, it disables the
|
|
||||||
* CSRF protection, and if set to null, it forces the form to use the global
|
|
||||||
* CSRF secret. If the global CSRF secret is also null, then a random one
|
|
||||||
* is generated on the fly.
|
|
||||||
*
|
|
||||||
* To implement your own form fields, you need to have a thorough understanding
|
* To implement your own form fields, you need to have a thorough understanding
|
||||||
* of the data flow within a form field. A form field stores its data in three
|
* of the data flow within a form field. A form field stores its data in three
|
||||||
* different representations:
|
* different representations:
|
||||||
@ -459,6 +452,8 @@ class Form implements \IteratorAggregate, FormInterface
|
|||||||
public function bind($clientData)
|
public function bind($clientData)
|
||||||
{
|
{
|
||||||
if ($this->readOnly) {
|
if ($this->readOnly) {
|
||||||
|
$this->bound = true;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,6 +305,7 @@ class FormFactory implements FormFactoryInterface
|
|||||||
|
|
||||||
$typeGuess = $this->guesser->guessType($class, $property);
|
$typeGuess = $this->guesser->guessType($class, $property);
|
||||||
$maxLengthGuess = $this->guesser->guessMaxLength($class, $property);
|
$maxLengthGuess = $this->guesser->guessMaxLength($class, $property);
|
||||||
|
$minLengthGuess = $this->guesser->guessMinLength($class, $property);
|
||||||
$requiredGuess = $this->guesser->guessRequired($class, $property);
|
$requiredGuess = $this->guesser->guessRequired($class, $property);
|
||||||
|
|
||||||
$type = $typeGuess ? $typeGuess->getType() : 'text';
|
$type = $typeGuess ? $typeGuess->getType() : 'text';
|
||||||
@ -313,6 +314,14 @@ class FormFactory implements FormFactoryInterface
|
|||||||
$options = array_merge(array('max_length' => $maxLengthGuess->getValue()), $options);
|
$options = array_merge(array('max_length' => $maxLengthGuess->getValue()), $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($minLengthGuess) {
|
||||||
|
if ($maxLengthGuess) {
|
||||||
|
$options = array_merge(array('pattern' => '.{'.$minLengthGuess->getValue().','.$maxLengthGuess->getValue().'}'), $options);
|
||||||
|
} else {
|
||||||
|
$options = array_merge(array('pattern' => '.{'.$minLengthGuess->getValue().',}'), $options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($requiredGuess) {
|
if ($requiredGuess) {
|
||||||
$options = array_merge(array('required' => $requiredGuess->getValue()), $options);
|
$options = array_merge(array('required' => $requiredGuess->getValue()), $options);
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,13 @@ class FormTypeGuesserChain implements FormTypeGuesserInterface
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function guessMinLength($class, $property)
|
||||||
|
{
|
||||||
|
return $this->guess(function ($guesser) use ($class, $property) {
|
||||||
|
return $guesser->guessMinLength($class, $property);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a closure for each guesser and returns the best guess from the
|
* Executes a closure for each guesser and returns the best guess from the
|
||||||
* return values
|
* return values
|
||||||
|
@ -42,4 +42,14 @@ interface FormTypeGuesserInterface
|
|||||||
* @return Guess A guess for the field's maximum length
|
* @return Guess A guess for the field's maximum length
|
||||||
*/
|
*/
|
||||||
function guessMaxLength($class, $property);
|
function guessMaxLength($class, $property);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a guess about the field's minimum length
|
||||||
|
*
|
||||||
|
* @param string $class The fully qualified class name
|
||||||
|
* @param string $property The name of the property to guess for
|
||||||
|
* @return Guess A guess for the field's minimum length
|
||||||
|
*/
|
||||||
|
function guessMinLength($class, $property);
|
||||||
|
|
||||||
}
|
}
|
@ -142,7 +142,7 @@ class PropertyPath implements \IteratorAggregate
|
|||||||
*/
|
*/
|
||||||
public function isProperty($index)
|
public function isProperty($index)
|
||||||
{
|
{
|
||||||
return !$this->isIndex($index);
|
return !$this->isIndex[$index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -186,7 +186,25 @@ class PropertyPath implements \IteratorAggregate
|
|||||||
*/
|
*/
|
||||||
public function getValue($objectOrArray)
|
public function getValue($objectOrArray)
|
||||||
{
|
{
|
||||||
return $this->readPropertyPath($objectOrArray, 0);
|
for ($i = 0; $i < $this->length; ++$i) {
|
||||||
|
if (is_object($objectOrArray)) {
|
||||||
|
$value = $this->readProperty($objectOrArray, $i);
|
||||||
|
// arrays need to be treated separately (due to PHP bug?)
|
||||||
|
// http://bugs.php.net/bug.php?id=52133
|
||||||
|
} else if (is_array($objectOrArray)){
|
||||||
|
$property = $this->elements[$i];
|
||||||
|
if (!array_key_exists($property, $objectOrArray)) {
|
||||||
|
$objectOrArray[$property] = $i + 1 < $this->length ? array() : null;
|
||||||
|
}
|
||||||
|
$value =& $objectOrArray[$property];
|
||||||
|
} else {
|
||||||
|
throw new UnexpectedTypeException($objectOrArray, 'object or array');
|
||||||
|
}
|
||||||
|
|
||||||
|
$objectOrArray =& $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,78 +237,30 @@ class PropertyPath implements \IteratorAggregate
|
|||||||
*/
|
*/
|
||||||
public function setValue(&$objectOrArray, $value)
|
public function setValue(&$objectOrArray, $value)
|
||||||
{
|
{
|
||||||
$this->writePropertyPath($objectOrArray, 0, $value);
|
for ($i = 0, $l = $this->length - 1; $i < $l; ++$i) {
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursive implementation of getValue()
|
|
||||||
*
|
|
||||||
* @param object|array $objectOrArray The object or array to traverse
|
|
||||||
* @param integer $currentIndex The current index in the property path
|
|
||||||
* @return mixed The value at the end of the path
|
|
||||||
*/
|
|
||||||
protected function readPropertyPath(&$objectOrArray, $currentIndex)
|
|
||||||
{
|
|
||||||
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
|
|
||||||
throw new UnexpectedTypeException($objectOrArray, 'object or array');
|
|
||||||
}
|
|
||||||
|
|
||||||
$property = $this->elements[$currentIndex];
|
|
||||||
|
|
||||||
if (is_object($objectOrArray)) {
|
|
||||||
$value = $this->readProperty($objectOrArray, $currentIndex);
|
|
||||||
// arrays need to be treated separately (due to PHP bug?)
|
|
||||||
// http://bugs.php.net/bug.php?id=52133
|
|
||||||
} else {
|
|
||||||
if (!array_key_exists($property, $objectOrArray)) {
|
|
||||||
$objectOrArray[$property] = $currentIndex + 1 < $this->length ? array() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$value =& $objectOrArray[$property];
|
|
||||||
}
|
|
||||||
|
|
||||||
++$currentIndex;
|
|
||||||
|
|
||||||
if ($currentIndex < $this->length) {
|
|
||||||
return $this->readPropertyPath($value, $currentIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursive implementation of setValue()
|
|
||||||
*
|
|
||||||
* @param object|array $objectOrArray The object or array to traverse
|
|
||||||
* @param integer $currentIndex The current index in the property path
|
|
||||||
* @param mixed $value The value to set at the end of the
|
|
||||||
* property path
|
|
||||||
*/
|
|
||||||
protected function writePropertyPath(&$objectOrArray, $currentIndex, $value)
|
|
||||||
{
|
|
||||||
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
|
|
||||||
throw new UnexpectedTypeException($objectOrArray, 'object or array');
|
|
||||||
}
|
|
||||||
|
|
||||||
$property = $this->elements[$currentIndex];
|
|
||||||
|
|
||||||
if ($currentIndex + 1 < $this->length) {
|
|
||||||
if (is_object($objectOrArray)) {
|
if (is_object($objectOrArray)) {
|
||||||
$nestedObject = $this->readProperty($objectOrArray, $currentIndex);
|
$nestedObject = $this->readProperty($objectOrArray, $i);
|
||||||
// arrays need to be treated separately (due to PHP bug?)
|
// arrays need to be treated separately (due to PHP bug?)
|
||||||
// http://bugs.php.net/bug.php?id=52133
|
// http://bugs.php.net/bug.php?id=52133
|
||||||
} else {
|
} else if (is_array($objectOrArray)) {
|
||||||
|
$property = $this->elements[$i];
|
||||||
if (!array_key_exists($property, $objectOrArray)) {
|
if (!array_key_exists($property, $objectOrArray)) {
|
||||||
$objectOrArray[$property] = array();
|
$objectOrArray[$property] = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$nestedObject =& $objectOrArray[$property];
|
$nestedObject =& $objectOrArray[$property];
|
||||||
|
} else {
|
||||||
|
throw new UnexpectedTypeException($objectOrArray, 'object or array');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->writePropertyPath($nestedObject, $currentIndex + 1, $value);
|
$objectOrArray =& $nestedObject;
|
||||||
} else {
|
|
||||||
$this->writeProperty($objectOrArray, $currentIndex, $value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_object($objectOrArray) && !is_array($objectOrArray)) {
|
||||||
|
throw new UnexpectedTypeException($objectOrArray, 'object or array');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->writeProperty($objectOrArray, $i, $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -311,9 +281,10 @@ class PropertyPath implements \IteratorAggregate
|
|||||||
|
|
||||||
return $object[$property];
|
return $object[$property];
|
||||||
} else {
|
} else {
|
||||||
|
$camelProp = $this->camelize($property);
|
||||||
$reflClass = new \ReflectionClass($object);
|
$reflClass = new \ReflectionClass($object);
|
||||||
$getter = 'get'.$this->camelize($property);
|
$getter = 'get'.$camelProp;
|
||||||
$isser = 'is'.$this->camelize($property);
|
$isser = 'is'.$camelProp;
|
||||||
|
|
||||||
if ($reflClass->hasMethod($getter)) {
|
if ($reflClass->hasMethod($getter)) {
|
||||||
if (!$reflClass->getMethod($getter)->isPublic()) {
|
if (!$reflClass->getMethod($getter)->isPublic()) {
|
||||||
|
45
src/Symfony/Component/Locale/Resources/stubs/functions.php
Normal file
45
src/Symfony/Component/Locale/Resources/stubs/functions.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stub implementation for the intl_is_failure function of the intl extension
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
||||||
|
* @param integer $errorCode The error code returned by intl_get_error_code()
|
||||||
|
* @return Boolean Whether the error code indicates an error
|
||||||
|
* @see Symfony\Component\Locale\Stub\StubIntl::isFailure
|
||||||
|
*/
|
||||||
|
function intl_is_failure($errorCode) {
|
||||||
|
return \Symfony\Component\Locale\Stub\StubIntl::isFailure($errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stub implementation for the intl_get_error_code function of the intl extension
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
||||||
|
* @return Boolean The error code of the last intl function call or
|
||||||
|
* StubIntl::U_ZERO_ERROR if no error occurred
|
||||||
|
* @see Symfony\Component\Locale\Stub\StubIntl::getErrorCode
|
||||||
|
*/
|
||||||
|
function intl_get_error_code() {
|
||||||
|
return \Symfony\Component\Locale\Stub\StubIntl::getErrorCode();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Stub implementation for the intl_get_error_code function of the intl extension
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
||||||
|
* @return Boolean The error message of the last intl function call or
|
||||||
|
* "U_ZERO_ERROR" if no error occurred
|
||||||
|
* @see Symfony\Component\Locale\Stub\StubIntl::getErrorMessage
|
||||||
|
*/
|
||||||
|
function intl_get_error_message() {
|
||||||
|
return \Symfony\Component\Locale\Stub\StubIntl::getErrorMessage();
|
||||||
|
}
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Locale\Stub\DateFormat;
|
namespace Symfony\Component\Locale\Stub\DateFormat;
|
||||||
|
|
||||||
use Symfony\Component\Locale\Exception\NotImplementedException;
|
use Symfony\Component\Locale\Exception\NotImplementedException;
|
||||||
|
use Symfony\Component\Locale\Stub\StubIntl;
|
||||||
use Symfony\Component\Locale\Stub\DateFormat\MonthTransformer;
|
use Symfony\Component\Locale\Stub\DateFormat\MonthTransformer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -275,6 +276,8 @@ class FullTransformer
|
|||||||
|
|
||||||
// If month is false, return immediately (intl behavior)
|
// If month is false, return immediately (intl behavior)
|
||||||
if (false === $month) {
|
if (false === $month) {
|
||||||
|
StubIntl::setErrorCode(StubIntl::U_PARSE_ERROR);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
112
src/Symfony/Component/Locale/Stub/StubIntl.php
Normal file
112
src/Symfony/Component/Locale/Stub/StubIntl.php
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
<?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\Locale\Stub;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides fake static versions of the global functions in the intl extension
|
||||||
|
*
|
||||||
|
* @author Bernhard Schussek <bernhard.schussek@symfony.com>
|
||||||
|
*/
|
||||||
|
abstract class StubIntl
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Indicates that no error occurred
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
const U_ZERO_ERROR = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that an invalid argument was passed
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
const U_ILLEGAL_ARGUMENT_ERROR = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that the parse() operation failed
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
const U_PARSE_ERROR = 9;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All known error codes
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $errorCodes = array(
|
||||||
|
self::U_ZERO_ERROR,
|
||||||
|
self::U_ILLEGAL_ARGUMENT_ERROR,
|
||||||
|
self::U_PARSE_ERROR,
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error messages of all known error codes
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $errorMessages = array(
|
||||||
|
self::U_ZERO_ERROR => 'U_ZERO_ERROR',
|
||||||
|
self::U_ILLEGAL_ARGUMENT_ERROR => 'datefmt_format: takes either an array or an integer timestamp value : U_ILLEGAL_ARGUMENT_ERROR',
|
||||||
|
self::U_PARSE_ERROR => 'Date parsing failed: U_PARSE_ERROR',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The error code of the last operation
|
||||||
|
* @var integer
|
||||||
|
*/
|
||||||
|
private static $errorCode = self::U_ZERO_ERROR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the error code indicates a failure
|
||||||
|
*
|
||||||
|
* @param integer $errorCode The error code returned by StubIntl::getErrorCode()
|
||||||
|
* @return Boolean
|
||||||
|
*/
|
||||||
|
public static function isFailure($errorCode) {
|
||||||
|
return in_array($errorCode, static::$errorCodes, true)
|
||||||
|
&& $errorCode !== self::U_ZERO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the error code of the last operation
|
||||||
|
*
|
||||||
|
* Returns StubIntl::U_ZERO_ERROR if no error occurred.
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public static function getErrorCode() {
|
||||||
|
return static::$errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the error message of the last operation
|
||||||
|
*
|
||||||
|
* Returns "U_ZERO_ERROR" if no error occurred.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getErrorMessage() {
|
||||||
|
return static::$errorMessages[static::$errorCode];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current error code
|
||||||
|
*
|
||||||
|
* @param integer $code One of the error constants in this class
|
||||||
|
* @throws \InvalidArgumentException If the code is not one of the error
|
||||||
|
* constants in this class
|
||||||
|
*/
|
||||||
|
public static function setErrorCode($code) {
|
||||||
|
if (!isset(static::$errorMessages[$code])) {
|
||||||
|
throw new \InvalidArgumentException(sprintf('No such error code: "%s"', $code));
|
||||||
|
}
|
||||||
|
|
||||||
|
static::$errorCode = $code;
|
||||||
|
}
|
||||||
|
}
|
@ -160,10 +160,18 @@ class StubIntlDateFormatter
|
|||||||
*/
|
*/
|
||||||
public function format($timestamp)
|
public function format($timestamp)
|
||||||
{
|
{
|
||||||
if (!is_int($timestamp)) {
|
// intl allows timestamps to be passed as arrays - we don't
|
||||||
|
if (is_array($timestamp)) {
|
||||||
throw new MethodArgumentValueNotImplementedException(__METHOD__, 'timestamp', $timestamp, 'Only integer unix timestamps are supported');
|
throw new MethodArgumentValueNotImplementedException(__METHOD__, 'timestamp', $timestamp, 'Only integer unix timestamps are supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_int($timestamp)) {
|
||||||
|
// behave like the intl extension
|
||||||
|
StubIntl::setErrorCode(StubIntl::U_ILLEGAL_ARGUMENT_ERROR);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$transformer = new FullTransformer($this->getPattern(), $this->getTimeZoneId());
|
$transformer = new FullTransformer($this->getPattern(), $this->getTimeZoneId());
|
||||||
$formatted = $transformer->format($this->createDateTime($timestamp));
|
$formatted = $transformer->format($this->createDateTime($timestamp));
|
||||||
|
|
||||||
@ -311,6 +319,8 @@ class StubIntlDateFormatter
|
|||||||
throw new MethodArgumentNotImplementedException(__METHOD__, 'position');
|
throw new MethodArgumentNotImplementedException(__METHOD__, 'position');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StubIntl::setErrorCode(StubIntl::U_ZERO_ERROR);
|
||||||
|
|
||||||
$dateTime = $this->createDateTime(0);
|
$dateTime = $this->createDateTime(0);
|
||||||
$transformer = new FullTransformer($this->getPattern(), $this->getTimeZoneId());
|
$transformer = new FullTransformer($this->getPattern(), $this->getTimeZoneId());
|
||||||
return $transformer->parse($dateTime, $value);
|
return $transformer->parse($dateTime, $value);
|
||||||
|
@ -32,7 +32,7 @@ class TypeValidator extends ConstraintValidator
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->setMessage($constraint->message, array(
|
$this->setMessage($constraint->message, array(
|
||||||
'{{ value }}' => $value,
|
'{{ value }}' => is_object($value) ? get_class($value) : (string)$value,
|
||||||
'{{ type }}' => $constraint->type,
|
'{{ type }}' => $constraint->type,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -939,6 +939,22 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSearch()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('search', 'na&me', 'foo&bar', array(
|
||||||
|
'property_path' => 'name',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath($form->createView(), array(),
|
||||||
|
'/input
|
||||||
|
[@type="search"]
|
||||||
|
[@name="na&me"]
|
||||||
|
[@value="foo&bar"]
|
||||||
|
[not(@maxlength)]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testTime()
|
public function testTime()
|
||||||
{
|
{
|
||||||
$form = $this->factory->createNamed('time', 'na&me', '04:05:06', array(
|
$form = $this->factory->createNamed('time', 'na&me', '04:05:06', array(
|
||||||
|
@ -50,16 +50,16 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->factory->expects($this->at(0))
|
$this->factory->expects($this->at(0))
|
||||||
->method('createNamed')
|
->method('createNamed')
|
||||||
->with('text', 1, null, array('property_path' => '[1]'))
|
->with('text', 1, null, array('property_path' => '[1]', 'max_length' => 10))
|
||||||
->will($this->returnValue($this->getForm('1')));
|
->will($this->returnValue($this->getForm('1')));
|
||||||
$this->factory->expects($this->at(1))
|
$this->factory->expects($this->at(1))
|
||||||
->method('createNamed')
|
->method('createNamed')
|
||||||
->with('text', 2, null, array('property_path' => '[2]'))
|
->with('text', 2, null, array('property_path' => '[2]', 'max_length' => 10))
|
||||||
->will($this->returnValue($this->getForm('2')));
|
->will($this->returnValue($this->getForm('2')));
|
||||||
|
|
||||||
$data = array(1 => 'string', 2 => 'string');
|
$data = array(1 => 'string', 2 => 'string');
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array('max_length' => '10'), false, false);
|
||||||
$listener->preSetData($event);
|
$listener->preSetData($event);
|
||||||
|
|
||||||
$this->assertFalse($this->form->has('0'));
|
$this->assertFalse($this->form->has('0'));
|
||||||
@ -73,7 +73,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = array();
|
$data = array();
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, false);
|
||||||
$listener->preSetData($event);
|
$listener->preSetData($event);
|
||||||
|
|
||||||
$this->assertFalse($this->form->has('$$name$$'));
|
$this->assertFalse($this->form->has('$$name$$'));
|
||||||
@ -85,7 +85,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = array();
|
$data = array();
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', true, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), true, false);
|
||||||
$listener->preSetData($event);
|
$listener->preSetData($event);
|
||||||
|
|
||||||
$this->assertTrue($this->form->has('$$name$$'));
|
$this->assertTrue($this->form->has('$$name$$'));
|
||||||
@ -98,7 +98,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$data = 'no array or traversable';
|
$data = 'no array or traversable';
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, false);
|
||||||
$listener->preSetData($event);
|
$listener->preSetData($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +108,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = null;
|
$data = null;
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, false);
|
||||||
$listener->preSetData($event);
|
$listener->preSetData($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,12 +118,12 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->factory->expects($this->once())
|
$this->factory->expects($this->once())
|
||||||
->method('createNamed')
|
->method('createNamed')
|
||||||
->with('text', 1, null, array('property_path' => '[1]'))
|
->with('text', 1, null, array('property_path' => '[1]', 'max_length' => 10))
|
||||||
->will($this->returnValue($this->getForm('1')));
|
->will($this->returnValue($this->getForm('1')));
|
||||||
|
|
||||||
$data = array(0 => 'string', 1 => 'string');
|
$data = array(0 => 'string', 1 => 'string');
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', true, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array('max_length' => 10), true, false);
|
||||||
$listener->preBind($event);
|
$listener->preBind($event);
|
||||||
|
|
||||||
$this->assertTrue($this->form->has('0'));
|
$this->assertTrue($this->form->has('0'));
|
||||||
@ -137,7 +137,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = array(0 => 'string');
|
$data = array(0 => 'string');
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, true);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, true);
|
||||||
$listener->preBind($event);
|
$listener->preBind($event);
|
||||||
|
|
||||||
$this->assertTrue($this->form->has('0'));
|
$this->assertTrue($this->form->has('0'));
|
||||||
@ -151,7 +151,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = array();
|
$data = array();
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, true);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, true);
|
||||||
$listener->preBind($event);
|
$listener->preBind($event);
|
||||||
|
|
||||||
$this->assertFalse($this->form->has('0'));
|
$this->assertFalse($this->form->has('0'));
|
||||||
@ -164,7 +164,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = array(0 => 'string', 2 => 'string');
|
$data = array(0 => 'string', 2 => 'string');
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, false);
|
||||||
$listener->preBind($event);
|
$listener->preBind($event);
|
||||||
|
|
||||||
$this->assertTrue($this->form->has('0'));
|
$this->assertTrue($this->form->has('0'));
|
||||||
@ -179,7 +179,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$data = 'no array or traversable';
|
$data = 'no array or traversable';
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, false);
|
||||||
$listener->preBind($event);
|
$listener->preBind($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +189,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = null;
|
$data = null;
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, true);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, true);
|
||||||
$listener->preBind($event);
|
$listener->preBind($event);
|
||||||
|
|
||||||
$this->assertFalse($this->form->has('1'));
|
$this->assertFalse($this->form->has('1'));
|
||||||
@ -202,7 +202,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = '';
|
$data = '';
|
||||||
$event = new DataEvent($this->form, $data);
|
$event = new DataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, true);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, true);
|
||||||
$listener->preBind($event);
|
$listener->preBind($event);
|
||||||
|
|
||||||
$this->assertFalse($this->form->has('1'));
|
$this->assertFalse($this->form->has('1'));
|
||||||
@ -214,7 +214,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = array(0 => 'first', 1 => 'second', 2 => 'third');
|
$data = array(0 => 'first', 1 => 'second', 2 => 'third');
|
||||||
$event = new FilterDataEvent($this->form, $data);
|
$event = new FilterDataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, true);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, true);
|
||||||
$listener->onBindNormData($event);
|
$listener->onBindNormData($event);
|
||||||
|
|
||||||
$this->assertEquals(array(1 => 'second'), $event->getData());
|
$this->assertEquals(array(1 => 'second'), $event->getData());
|
||||||
@ -226,7 +226,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = array(0 => 'first', 1 => 'second', 2 => 'third');
|
$data = array(0 => 'first', 1 => 'second', 2 => 'third');
|
||||||
$event = new FilterDataEvent($this->form, $data);
|
$event = new FilterDataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, false);
|
||||||
$listener->onBindNormData($event);
|
$listener->onBindNormData($event);
|
||||||
|
|
||||||
$this->assertEquals($data, $event->getData());
|
$this->assertEquals($data, $event->getData());
|
||||||
@ -239,7 +239,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$data = 'no array or traversable';
|
$data = 'no array or traversable';
|
||||||
$event = new FilterDataEvent($this->form, $data);
|
$event = new FilterDataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, false);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, false);
|
||||||
$listener->onBindNormData($event);
|
$listener->onBindNormData($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$data = null;
|
$data = null;
|
||||||
$event = new FilterDataEvent($this->form, $data);
|
$event = new FilterDataEvent($this->form, $data);
|
||||||
$listener = new ResizeFormListener($this->factory, 'text', false, true);
|
$listener = new ResizeFormListener($this->factory, 'text', array(), false, true);
|
||||||
$listener->onBindNormData($event);
|
$listener->onBindNormData($event);
|
||||||
|
|
||||||
$this->assertEquals(array(), $event->getData());
|
$this->assertEquals(array(), $event->getData());
|
||||||
|
@ -312,7 +312,7 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
$this->assertSame(array('b' => 'B', 'd' => 'D'), $view->get('preferred_choices'));
|
$this->assertSame(array('b' => 'B', 'd' => 'D'), $view->get('preferred_choices'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAdjustNameForMultipleNonExpanded()
|
public function testAdjustFullNameForMultipleNonExpanded()
|
||||||
{
|
{
|
||||||
$form = $this->factory->createNamed('choice', 'name', null, array(
|
$form = $this->factory->createNamed('choice', 'name', null, array(
|
||||||
'multiple' => true,
|
'multiple' => true,
|
||||||
@ -321,6 +321,6 @@ class ChoiceTypeTest extends TypeTestCase
|
|||||||
));
|
));
|
||||||
$view = $form->createView();
|
$view = $form->createView();
|
||||||
|
|
||||||
$this->assertSame('name[]', $view->get('name'));
|
$this->assertSame('name[]', $view->get('full_name'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,9 @@ class CollectionFormTest extends TypeTestCase
|
|||||||
{
|
{
|
||||||
$form = $this->factory->create('collection', null, array(
|
$form = $this->factory->create('collection', null, array(
|
||||||
'type' => 'field',
|
'type' => 'field',
|
||||||
|
'options' => array(
|
||||||
|
'max_length' => 20,
|
||||||
|
),
|
||||||
));
|
));
|
||||||
$form->setData(array('foo@foo.com', 'foo@bar.com'));
|
$form->setData(array('foo@foo.com', 'foo@bar.com'));
|
||||||
|
|
||||||
@ -37,18 +40,24 @@ class CollectionFormTest extends TypeTestCase
|
|||||||
$this->assertEquals(2, count($form));
|
$this->assertEquals(2, count($form));
|
||||||
$this->assertEquals('foo@foo.com', $form[0]->getData());
|
$this->assertEquals('foo@foo.com', $form[0]->getData());
|
||||||
$this->assertEquals('foo@bar.com', $form[1]->getData());
|
$this->assertEquals('foo@bar.com', $form[1]->getData());
|
||||||
|
$this->assertEquals(20, $form[0]->getAttribute('max_length'));
|
||||||
|
$this->assertEquals(20, $form[1]->getAttribute('max_length'));
|
||||||
|
|
||||||
$form->setData(array('foo@baz.com'));
|
$form->setData(array('foo@baz.com'));
|
||||||
$this->assertTrue($form[0] instanceof Form);
|
$this->assertTrue($form[0] instanceof Form);
|
||||||
$this->assertFalse(isset($form[1]));
|
$this->assertFalse(isset($form[1]));
|
||||||
$this->assertEquals(1, count($form));
|
$this->assertEquals(1, count($form));
|
||||||
$this->assertEquals('foo@baz.com', $form[0]->getData());
|
$this->assertEquals('foo@baz.com', $form[0]->getData());
|
||||||
|
$this->assertEquals(20, $form[0]->getAttribute('max_length'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSetDataAddsPrototypeIfAllowAdd()
|
public function testSetDataAddsPrototypeIfAllowAdd()
|
||||||
{
|
{
|
||||||
$form = $this->factory->create('collection', null, array(
|
$form = $this->factory->create('collection', null, array(
|
||||||
'type' => 'field',
|
'type' => 'field',
|
||||||
|
'options' => array(
|
||||||
|
'max_length' => 20,
|
||||||
|
),
|
||||||
'allow_add' => true,
|
'allow_add' => true,
|
||||||
'prototype' => true,
|
'prototype' => true,
|
||||||
));
|
));
|
||||||
@ -57,12 +66,14 @@ class CollectionFormTest extends TypeTestCase
|
|||||||
$this->assertTrue($form[0] instanceof Form);
|
$this->assertTrue($form[0] instanceof Form);
|
||||||
$this->assertTrue($form[1] instanceof Form);
|
$this->assertTrue($form[1] instanceof Form);
|
||||||
$this->assertTrue($form['$$name$$'] instanceof Form);
|
$this->assertTrue($form['$$name$$'] instanceof Form);
|
||||||
|
$this->assertEquals(20, $form['$$name$$']->getAttribute('max_length'));
|
||||||
$this->assertEquals(3, count($form));
|
$this->assertEquals(3, count($form));
|
||||||
|
|
||||||
$form->setData(array('foo@baz.com'));
|
$form->setData(array('foo@baz.com'));
|
||||||
$this->assertTrue($form[0] instanceof Form);
|
$this->assertTrue($form[0] instanceof Form);
|
||||||
$this->assertFalse(isset($form[1]));
|
$this->assertFalse(isset($form[1]));
|
||||||
$this->assertTrue($form['$$name$$'] instanceof Form);
|
$this->assertTrue($form['$$name$$'] instanceof Form);
|
||||||
|
$this->assertEquals(20, $form['$$name$$']->getAttribute('max_length'));
|
||||||
$this->assertEquals(2, count($form));
|
$this->assertEquals(2, count($form));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +117,7 @@ class FieldTypeTest extends TypeTestCase
|
|||||||
|
|
||||||
$this->assertEquals('name', $view->get('id'));
|
$this->assertEquals('name', $view->get('id'));
|
||||||
$this->assertEquals('name', $view->get('name'));
|
$this->assertEquals('name', $view->get('name'));
|
||||||
|
$this->assertEquals('name', $view->get('full_name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPassIdAndNameToViewWithParent()
|
public function testPassIdAndNameToViewWithParent()
|
||||||
@ -126,7 +127,8 @@ class FieldTypeTest extends TypeTestCase
|
|||||||
$view = $parent->createView();
|
$view = $parent->createView();
|
||||||
|
|
||||||
$this->assertEquals('parent_child', $view['child']->get('id'));
|
$this->assertEquals('parent_child', $view['child']->get('id'));
|
||||||
$this->assertEquals('parent[child]', $view['child']->get('name'));
|
$this->assertEquals('child', $view['child']->get('name'));
|
||||||
|
$this->assertEquals('parent[child]', $view['child']->get('full_name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPassIdAndNameToViewWithGrandParent()
|
public function testPassIdAndNameToViewWithGrandParent()
|
||||||
@ -137,7 +139,8 @@ class FieldTypeTest extends TypeTestCase
|
|||||||
$view = $parent->createView();
|
$view = $parent->createView();
|
||||||
|
|
||||||
$this->assertEquals('parent_child_grand_child', $view['child']['grand_child']->get('id'));
|
$this->assertEquals('parent_child_grand_child', $view['child']['grand_child']->get('id'));
|
||||||
$this->assertEquals('parent[child][grand_child]', $view['child']['grand_child']->get('name'));
|
$this->assertEquals('grand_child', $view['child']['grand_child']->get('name'));
|
||||||
|
$this->assertEquals('parent[child][grand_child]', $view['child']['grand_child']->get('full_name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPassMaxLengthToView()
|
public function testPassMaxLengthToView()
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
<?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\Tests\Component\Form\Extension\Core\Type;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/TypeTestCase.php';
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
|
|
||||||
|
class FileTypeTest extends TypeTestCase
|
||||||
|
{
|
||||||
|
public function testDontPassValueToView()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('file');
|
||||||
|
$form->bind(array(
|
||||||
|
'file' => $this->createUploadedFileMock('abcdef', 'original.jpg', true),
|
||||||
|
));
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertEquals('', $view['file']->get('value'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createUploadedFileMock($name, $originalName, $valid)
|
||||||
|
{
|
||||||
|
$file = $this->getMockBuilder('Symfony\Component\HttpFoundation\File\UploadedFile')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
$file->expects($this->any())
|
||||||
|
->method('getName')
|
||||||
|
->will($this->returnValue($name));
|
||||||
|
$file->expects($this->any())
|
||||||
|
->method('getOriginalName')
|
||||||
|
->will($this->returnValue($originalName));
|
||||||
|
$file->expects($this->any())
|
||||||
|
->method('isValid')
|
||||||
|
->will($this->returnValue($valid));
|
||||||
|
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
@ -21,13 +21,13 @@ class RadioTypeTest extends TypeTestCase
|
|||||||
$this->assertEquals('foobar', $view->get('value'));
|
$this->assertEquals('foobar', $view->get('value'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testPassParentNameToView()
|
public function testPassParentFullNameToView()
|
||||||
{
|
{
|
||||||
$parent = $this->factory->createNamed('field', 'parent');
|
$parent = $this->factory->createNamed('field', 'parent');
|
||||||
$parent->add($this->factory->createNamed('radio', 'child'));
|
$parent->add($this->factory->createNamed('radio', 'child'));
|
||||||
$view = $parent->createView();
|
$view = $parent->createView();
|
||||||
|
|
||||||
$this->assertEquals('parent', $view['child']->get('name'));
|
$this->assertEquals('parent', $view['child']->get('full_name'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCheckedIfDataTrue()
|
public function testCheckedIfDataTrue()
|
||||||
|
@ -159,6 +159,7 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
|||||||
$form->bind('new');
|
$form->bind('new');
|
||||||
|
|
||||||
$this->assertEquals('initial', $form->getData());
|
$this->assertEquals('initial', $form->getData());
|
||||||
|
$this->assertTrue($form->isBound());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testNeverRequiredIfParentNotRequired()
|
public function testNeverRequiredIfParentNotRequired()
|
||||||
@ -297,6 +298,14 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertTrue($this->form->isValid());
|
$this->assertTrue($this->form->isValid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testValidIfBoundAndReadOnly()
|
||||||
|
{
|
||||||
|
$form = $this->getBuilder()->setReadOnly(true)->getForm();
|
||||||
|
$form->bind('foobar');
|
||||||
|
|
||||||
|
$this->assertTrue($form->isValid());
|
||||||
|
}
|
||||||
|
|
||||||
public function testNotValidIfNotBound()
|
public function testNotValidIfNotBound()
|
||||||
{
|
{
|
||||||
$this->assertFalse($this->form->isValid());
|
$this->assertFalse($this->form->isValid());
|
||||||
|
@ -14,6 +14,7 @@ namespace Symfony\Tests\Component\Locale\Stub;
|
|||||||
require_once __DIR__.'/../TestCase.php';
|
require_once __DIR__.'/../TestCase.php';
|
||||||
|
|
||||||
use Symfony\Component\Locale\Locale;
|
use Symfony\Component\Locale\Locale;
|
||||||
|
use Symfony\Component\Locale\Stub\StubIntl;
|
||||||
use Symfony\Component\Locale\Stub\StubIntlDateFormatter;
|
use Symfony\Component\Locale\Stub\StubIntlDateFormatter;
|
||||||
use Symfony\Tests\Component\Locale\TestCase as LocaleTestCase;
|
use Symfony\Tests\Component\Locale\TestCase as LocaleTestCase;
|
||||||
|
|
||||||
@ -55,21 +56,27 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider formatProvider
|
* @dataProvider formatProvider
|
||||||
*/
|
*/
|
||||||
public function testFormatStub($pattern, $timestamp, $expected)
|
public function testFormatStub($pattern, $timestamp, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
|
||||||
{
|
{
|
||||||
$formatter = $this->createStubFormatter($pattern);
|
$formatter = $this->createStubFormatter($pattern);
|
||||||
$this->assertSame($expected, $formatter->format($timestamp));
|
$this->assertSame($expected, $formatter->format($timestamp));
|
||||||
|
$this->assertSame($errorMessage, StubIntl::getErrorMessage());
|
||||||
|
$this->assertSame($errorCode, StubIntl::getErrorCode());
|
||||||
|
$this->assertSame($errorCode != 0, StubIntl::isFailure(StubIntl::getErrorCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider formatProvider
|
* @dataProvider formatProvider
|
||||||
*/
|
*/
|
||||||
public function testFormatIntl($pattern, $timestamp, $expected)
|
public function testFormatIntl($pattern, $timestamp, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
|
||||||
{
|
{
|
||||||
$this->skipIfIntlExtensionIsNotLoaded();
|
$this->skipIfIntlExtensionIsNotLoaded();
|
||||||
$this->skipIfICUVersionIsTooOld();
|
$this->skipIfICUVersionIsTooOld();
|
||||||
$formatter = $this->createIntlFormatter($pattern);
|
$formatter = $this->createIntlFormatter($pattern);
|
||||||
$this->assertSame($expected, $formatter->format($timestamp));
|
$this->assertSame($expected, $formatter->format($timestamp));
|
||||||
|
$this->assertSame($errorMessage, intl_get_error_message());
|
||||||
|
$this->assertSame($errorCode, intl_get_error_code());
|
||||||
|
$this->assertSame($errorCode != 0, intl_is_failure(intl_get_error_code()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function formatProvider()
|
public function formatProvider()
|
||||||
@ -248,6 +255,10 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
|||||||
array('zzz', 0, 'GMT+00:00'),
|
array('zzz', 0, 'GMT+00:00'),
|
||||||
array('zzzz', 0, 'GMT+00:00'),
|
array('zzzz', 0, 'GMT+00:00'),
|
||||||
array('zzzzz', 0, 'GMT+00:00'),
|
array('zzzzz', 0, 'GMT+00:00'),
|
||||||
|
|
||||||
|
/* errors */
|
||||||
|
array('y-M-d', '0', false, 1, 'datefmt_format: takes either an array or an integer timestamp value : U_ILLEGAL_ARGUMENT_ERROR'),
|
||||||
|
array('y-M-d', 'foobar', false, 1, 'datefmt_format: takes either an array or an integer timestamp value : U_ILLEGAL_ARGUMENT_ERROR'),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $formatData;
|
return $formatData;
|
||||||
@ -481,20 +492,26 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
|||||||
/**
|
/**
|
||||||
* @dataProvider parseProvider
|
* @dataProvider parseProvider
|
||||||
*/
|
*/
|
||||||
public function testParseIntl($pattern, $value, $expected)
|
public function testParseIntl($pattern, $value, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
|
||||||
{
|
{
|
||||||
$this->skipIfIntlExtensionIsNotLoaded();
|
$this->skipIfIntlExtensionIsNotLoaded();
|
||||||
$formatter = $this->createIntlFormatter($pattern);
|
$formatter = $this->createIntlFormatter($pattern);
|
||||||
$this->assertSame($expected, $formatter->parse($value));
|
$this->assertSame($expected, $formatter->parse($value));
|
||||||
|
$this->assertSame($errorMessage, intl_get_error_message());
|
||||||
|
$this->assertSame($errorCode, intl_get_error_code());
|
||||||
|
$this->assertSame($errorCode != 0, intl_is_failure(intl_get_error_code()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider parseProvider
|
* @dataProvider parseProvider
|
||||||
*/
|
*/
|
||||||
public function testParseStub($pattern, $value, $expected)
|
public function testParseStub($pattern, $value, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
|
||||||
{
|
{
|
||||||
$formatter = $this->createStubFormatter($pattern);
|
$formatter = $this->createStubFormatter($pattern);
|
||||||
$this->assertSame($expected, $formatter->parse($value));
|
$this->assertSame($expected, $formatter->parse($value));
|
||||||
|
$this->assertSame($errorMessage, StubIntl::getErrorMessage());
|
||||||
|
$this->assertSame($errorCode, StubIntl::getErrorCode());
|
||||||
|
$this->assertSame($errorCode != 0, StubIntl::isFailure(StubIntl::getErrorCode()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function parseProvider()
|
public function parseProvider()
|
||||||
@ -511,8 +528,8 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
|||||||
array('y-MMMM-d', '1970-January-1', 0),
|
array('y-MMMM-d', '1970-January-1', 0),
|
||||||
|
|
||||||
// 1 char month
|
// 1 char month
|
||||||
array('y-MMMMM-d', '1970-J-1', false),
|
array('y-MMMMM-d', '1970-J-1', false, 9, 'Date parsing failed: U_PARSE_ERROR'),
|
||||||
array('y-MMMMM-d', '1970-S-1', false),
|
array('y-MMMMM-d', '1970-S-1', false, 9, 'Date parsing failed: U_PARSE_ERROR'),
|
||||||
|
|
||||||
// standalone months
|
// standalone months
|
||||||
array('y-L-d', '1970-1-1', 0),
|
array('y-L-d', '1970-1-1', 0),
|
||||||
@ -520,8 +537,8 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
|||||||
array('y-LLLL-d', '1970-January-1', 0),
|
array('y-LLLL-d', '1970-January-1', 0),
|
||||||
|
|
||||||
// standalone 1 char month
|
// standalone 1 char month
|
||||||
array('y-LLLLL-d', '1970-J-1', false),
|
array('y-LLLLL-d', '1970-J-1', false, 9, 'Date parsing failed: U_PARSE_ERROR'),
|
||||||
array('y-LLLLL-d', '1970-S-1', false),
|
array('y-LLLLL-d', '1970-S-1', false, 9, 'Date parsing failed: U_PARSE_ERROR'),
|
||||||
|
|
||||||
// days
|
// days
|
||||||
array('y-M-d', '1970-1-1', 0),
|
array('y-M-d', '1970-1-1', 0),
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Tests\Component\Validator\Constraints;
|
|||||||
|
|
||||||
use Symfony\Component\Validator\Constraints\Type;
|
use Symfony\Component\Validator\Constraints\Type;
|
||||||
use Symfony\Component\Validator\Constraints\TypeValidator;
|
use Symfony\Component\Validator\Constraints\TypeValidator;
|
||||||
|
use Symfony\Component\Validator\ConstraintViolation;
|
||||||
|
|
||||||
class TypeValidatorTest extends \PHPUnit_Framework_TestCase
|
class TypeValidatorTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
@ -83,6 +84,22 @@ class TypeValidatorTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
$this->assertFalse($this->validator->isValid($value, $constraint));
|
$this->assertFalse($this->validator->isValid($value, $constraint));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testConstraintViolationCanHandleArrayValue()
|
||||||
|
{
|
||||||
|
$constraint = new Type(array('type' => 'string'));
|
||||||
|
$this->validator->isValid(array(0 => "Test"), $constraint);
|
||||||
|
|
||||||
|
$violation = new ConstraintViolation(
|
||||||
|
'{{ value }}',
|
||||||
|
$this->validator->getMessageParameters(),
|
||||||
|
'',
|
||||||
|
'',
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertEquals('Array', $violation->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
public function getInvalidValues()
|
public function getInvalidValues()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user