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
@ -168,6 +168,9 @@ beta1 to beta2
|
||||
renamed to "single-text". "text" indicates to use separate text boxes now
|
||||
(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
|
||||
-------------
|
||||
|
||||
|
@ -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">
|
||||
<tag name="form.type" alias="repeated" />
|
||||
</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">
|
||||
<tag name="form.type" alias="textarea" />
|
||||
</service>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<input type="checkbox"
|
||||
<?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 ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||
<?php if ($required): ?>required="required"<?php endif ?>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<?php else: ?>
|
||||
<select
|
||||
<?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 ($multiple): ?> multiple="multiple"<?php endif ?>
|
||||
>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php if ($widget == 'single-text'): ?>
|
||||
<input type="text"
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_name) ?>"
|
||||
value="<?php echo $view->escape($value) ?>"
|
||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||
<?php if ($required): ?>required="required"<?php endif ?>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<input type="email"
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_name) ?>"
|
||||
value="<?php echo $view->escape($value) ?>"
|
||||
<?php if ($max_length): ?>maxlength="<?php echo $view->escape($max_length) ?>"<?php endif ?>
|
||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<input
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_name) ?>"
|
||||
value="<?php echo $view->escape($value) ?>"
|
||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||
<?php if ($required): ?>required="required"<?php endif ?>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<input type="hidden"
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_name) ?>"
|
||||
value="<?php echo $view->escape($value) ?>"
|
||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||
/>
|
@ -1,6 +1,6 @@
|
||||
<input type="number"
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_name) ?>"
|
||||
value="<?php echo $view->escape($value) ?>"
|
||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||
<?php if ($required): ?>required="required"<?php endif ?>
|
||||
|
@ -1,8 +1,9 @@
|
||||
<input type="text"
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_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 ?>
|
||||
<?php if ($pattern): ?>pattern="<?php echo $pattern ?>"<?php endif ?>
|
||||
/>
|
@ -1,8 +1,9 @@
|
||||
<input type="password"
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_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 ?>
|
||||
<?php if ($pattern): ?>pattern="<?php echo $pattern ?>"<?php endif ?>
|
||||
/>
|
@ -1,6 +1,6 @@
|
||||
<input type="radio"
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_name) ?>"
|
||||
value="<?php echo $view->escape($value) ?>"
|
||||
<?php if ($read_only): ?>disabled="disabled"<?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"
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_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 ?>
|
||||
<?php if ($pattern): ?>pattern="<?php echo $pattern ?>"<?php endif ?>
|
||||
/>
|
@ -1,6 +1,6 @@
|
||||
<textarea
|
||||
<?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 ($required): ?>required="required"<?php endif ?>
|
||||
><?php echo $view->escape($value) ?></textarea>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<input type="url"
|
||||
<?php echo $view['form']->attributes() ?>
|
||||
name="<?php echo $view->escape($name) ?>"
|
||||
name="<?php echo $view->escape($full_name) ?>"
|
||||
value="<?php echo $view->escape($value) ?>"
|
||||
<?php if ($read_only): ?>disabled="disabled"<?php endif ?>
|
||||
<?php if ($required): ?>required="required"<?php endif ?>
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
{% block attributes %}
|
||||
{% 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 %}
|
||||
{% endspaceless %}
|
||||
{% endblock attributes %}
|
||||
@ -208,6 +208,13 @@
|
||||
{% endspaceless %}
|
||||
{% endblock url_widget %}
|
||||
|
||||
{% block search_widget %}
|
||||
{% spaceless %}
|
||||
{% set type = type|default('search') %}
|
||||
{{ block('field_widget') }}
|
||||
{% endspaceless %}
|
||||
{% endblock search_widget %}
|
||||
|
||||
{% block percent_widget %}
|
||||
{% spaceless %}
|
||||
{% set type = type|default('text') %}
|
||||
|
@ -52,6 +52,7 @@ class CoreExtension extends AbstractExtension
|
||||
new Type\PercentType(),
|
||||
new Type\RadioType(),
|
||||
new Type\RepeatedType(),
|
||||
new Type\SearchType(),
|
||||
new Type\TextareaType(),
|
||||
new Type\TextType(),
|
||||
new Type\TimeType(),
|
||||
|
@ -35,6 +35,11 @@ class ResizeFormListener implements EventSubscriberInterface
|
||||
*/
|
||||
private $type;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Whether children could be added to the group
|
||||
* @var Boolean
|
||||
@ -47,12 +52,13 @@ class ResizeFormListener implements EventSubscriberInterface
|
||||
*/
|
||||
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->type = $type;
|
||||
$this->allowAdd = $allowAdd;
|
||||
$this->allowDelete = $allowDelete;
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
@ -86,9 +92,9 @@ class ResizeFormListener implements EventSubscriberInterface
|
||||
|
||||
// Then add all rows again in the correct order
|
||||
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.']',
|
||||
)));
|
||||
), $this->options)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,9 +124,9 @@ class ResizeFormListener implements EventSubscriberInterface
|
||||
if ($this->allowAdd) {
|
||||
foreach ($data as $name => $value) {
|
||||
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.']',
|
||||
)));
|
||||
), $this->options)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ class ChoiceType extends AbstractType
|
||||
// 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
|
||||
// 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,
|
||||
'choices' => array(),
|
||||
'preferred_choices' => array(),
|
||||
'csrf_protection' => false,
|
||||
'empty_data' => $multiple || $expanded ? array() : '',
|
||||
'error_bubbling' => false,
|
||||
);
|
||||
|
@ -22,15 +22,16 @@ class CollectionType extends AbstractType
|
||||
public function buildForm(FormBuilder $builder, array $options)
|
||||
{
|
||||
if ($options['allow_add'] && $options['prototype']) {
|
||||
$builder->add('$$name$$', $options['type'], array(
|
||||
$builder->add('$$name$$', $options['type'], array_replace(array(
|
||||
'property_path' => false,
|
||||
'required' => false,
|
||||
));
|
||||
'required' => false,
|
||||
), $options['options']));
|
||||
}
|
||||
|
||||
$listener = new ResizeFormListener(
|
||||
$builder->getFormFactory(),
|
||||
$options['type'],
|
||||
$options['options'],
|
||||
$options['allow_add'],
|
||||
$options['allow_delete']
|
||||
);
|
||||
@ -57,6 +58,7 @@ class CollectionType extends AbstractType
|
||||
'allow_delete' => false,
|
||||
'prototype' => true,
|
||||
'type' => 'text',
|
||||
'options' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -37,9 +37,6 @@ class DateTimeType extends AbstractType
|
||||
'with_seconds',
|
||||
)));
|
||||
|
||||
if (isset($options['date_pattern'])) {
|
||||
$dateOptions['pattern'] = $options['date_pattern'];
|
||||
}
|
||||
if (isset($options['date_widget'])) {
|
||||
$dateOptions['widget'] = $options['date_widget'];
|
||||
}
|
||||
@ -49,9 +46,6 @@ class DateTimeType extends AbstractType
|
||||
|
||||
$dateOptions['input'] = 'array';
|
||||
|
||||
if (isset($options['time_pattern'])) {
|
||||
$timeOptions['pattern'] = $options['time_pattern'];
|
||||
}
|
||||
if (isset($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
|
||||
// them like immutable value objects
|
||||
'by_reference' => false,
|
||||
'date_pattern' => null,
|
||||
'date_widget' => null,
|
||||
'date_format' => null,
|
||||
'time_pattern' => null,
|
||||
'time_widget' => null,
|
||||
/* Defaults for date field */
|
||||
'years' => range(date('Y') - 5, date('Y') + 5),
|
||||
|
@ -119,11 +119,9 @@ class DateType extends AbstractType
|
||||
'days' => range(1, 31),
|
||||
'widget' => 'choice',
|
||||
'input' => 'datetime',
|
||||
'pattern' => null,
|
||||
'format' => \IntlDateFormatter::MEDIUM,
|
||||
'data_timezone' => null,
|
||||
'user_timezone' => null,
|
||||
'csrf_protection' => false,
|
||||
// Don't modify \DateTime classes by reference, we treat
|
||||
// them like immutable value objects
|
||||
'by_reference' => false,
|
||||
|
@ -44,6 +44,7 @@ class FieldType extends AbstractType
|
||||
->setAttribute('property_path', $options['property_path'])
|
||||
->setAttribute('error_mapping', $options['error_mapping'])
|
||||
->setAttribute('max_length', $options['max_length'])
|
||||
->setAttribute('pattern', $options['pattern'])
|
||||
->setAttribute('label', $options['label'] ?: $this->humanize($builder->getName()))
|
||||
->setData($options['data'])
|
||||
->addValidator(new DefaultValidator())
|
||||
@ -58,7 +59,7 @@ class FieldType extends AbstractType
|
||||
{
|
||||
if ($view->hasParent()) {
|
||||
$parentId = $view->getParent()->get('id');
|
||||
$parentName = $view->getParent()->get('name');
|
||||
$parentName = $view->getParent()->get('full_name');
|
||||
$id = sprintf('%s_%s', $parentId, $form->getName());
|
||||
$name = sprintf('%s[%s]', $parentName, $form->getName());
|
||||
} else {
|
||||
@ -69,12 +70,14 @@ class FieldType extends AbstractType
|
||||
$view
|
||||
->set('form', $view)
|
||||
->set('id', $id)
|
||||
->set('name', $name)
|
||||
->set('name', $form->getName())
|
||||
->set('full_name', $name)
|
||||
->set('errors', $form->getErrors())
|
||||
->set('value', $form->getClientData())
|
||||
->set('read_only', $form->isReadOnly())
|
||||
->set('required', $form->isRequired())
|
||||
->set('max_length', $form->getAttribute('max_length'))
|
||||
->set('pattern', $form->getAttribute('pattern'))
|
||||
->set('size', null)
|
||||
->set('label', $form->getAttribute('label'))
|
||||
->set('multipart', false)
|
||||
@ -97,6 +100,7 @@ class FieldType extends AbstractType
|
||||
'required' => true,
|
||||
'read_only' => false,
|
||||
'max_length' => null,
|
||||
'pattern' => null,
|
||||
'property_path' => null,
|
||||
'by_reference' => true,
|
||||
'error_bubbling' => false,
|
||||
|
@ -52,13 +52,13 @@ class FileType extends AbstractType
|
||||
{
|
||||
$view->set('multipart', true);
|
||||
$view['file']->set('type', 'file');
|
||||
$view['file']->set('value', '');
|
||||
}
|
||||
|
||||
public function getDefaultOptions(array $options)
|
||||
{
|
||||
return array(
|
||||
'type' => 'string',
|
||||
'csrf_protection' => false,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ class RadioType extends AbstractType
|
||||
;
|
||||
|
||||
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(),
|
||||
'first_name' => 'first',
|
||||
'second_name' => 'second',
|
||||
'csrf_protection' => 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',
|
||||
'input' => 'datetime',
|
||||
'with_seconds' => false,
|
||||
'pattern' => null,
|
||||
'data_timezone' => null,
|
||||
'user_timezone' => null,
|
||||
'csrf_protection' => false,
|
||||
// Don't modify \DateTime classes by reference, we treat
|
||||
// them like immutable value objects
|
||||
'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\AbstractExtension;
|
||||
|
||||
/**
|
||||
* This extension protects forms by using a CSRF token
|
||||
*/
|
||||
class CsrfExtension extends AbstractExtension
|
||||
{
|
||||
private $csrfProvider;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param CsrfProviderInterface $csrfProvider The CSRF provider
|
||||
*/
|
||||
public function __construct(CsrfProviderInterface $csrfProvider)
|
||||
{
|
||||
$this->csrfProvider = $csrfProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function loadTypes()
|
||||
{
|
||||
return array(
|
||||
@ -31,10 +42,18 @@ class CsrfExtension extends AbstractExtension
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function loadTypeExtensions()
|
||||
{
|
||||
return array(
|
||||
new Type\ChoiceTypeCsrfExtension(),
|
||||
new Type\DateTypeCsrfExtension(),
|
||||
new Type\FileTypeCsrfExtension(),
|
||||
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;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param CsrfProviderInterface $csrfProvider The provider to use to generate the token
|
||||
*/
|
||||
public function __construct(CsrfProviderInterface $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)
|
||||
{
|
||||
$csrfProvider = $options['csrf_provider'];
|
||||
@ -47,20 +61,31 @@ class CsrfType extends AbstractType
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDefaultOptions(array $options)
|
||||
{
|
||||
return array(
|
||||
'csrf_provider' => $this->csrfProvider,
|
||||
'intention' => null,
|
||||
'intention' => null,
|
||||
'property_path' => false,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getParent(array $options)
|
||||
{
|
||||
return 'hidden';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this form.
|
||||
*
|
||||
* @return string 'csrf'
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if ($options['csrf_protection']) {
|
||||
@ -36,11 +42,19 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
|
||||
$csrfOptions['csrf_provider'] = $options['csrf_provider'];
|
||||
}
|
||||
|
||||
$builder->add($options['csrf_field_name'], 'csrf', $csrfOptions)
|
||||
->setAttribute('csrf_field_name', $options['csrf_field_name']);
|
||||
$builder
|
||||
->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)
|
||||
{
|
||||
if ($view->hasParent() && $form->hasAttribute('csrf_field_name')) {
|
||||
@ -52,16 +66,22 @@ class FormTypeCsrfExtension extends AbstractTypeExtension
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDefaultOptions(array $options)
|
||||
{
|
||||
return array(
|
||||
'csrf_protection' => $this->enabled,
|
||||
'csrf_field_name' => $this->fieldName,
|
||||
'csrf_provider' => null,
|
||||
'intention' => 'unknown',
|
||||
'csrf_protection' => $this->enabled,
|
||||
'csrf_field_name' => $this->fieldName,
|
||||
'csrf_provider' => null,
|
||||
'intention' => 'unknown',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getExtendedType()
|
||||
{
|
||||
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
|
||||
*
|
||||
@ -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
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
* of the data flow within a form field. A form field stores its data in three
|
||||
* different representations:
|
||||
@ -459,6 +452,8 @@ class Form implements \IteratorAggregate, FormInterface
|
||||
public function bind($clientData)
|
||||
{
|
||||
if ($this->readOnly) {
|
||||
$this->bound = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -305,6 +305,7 @@ class FormFactory implements FormFactoryInterface
|
||||
|
||||
$typeGuess = $this->guesser->guessType($class, $property);
|
||||
$maxLengthGuess = $this->guesser->guessMaxLength($class, $property);
|
||||
$minLengthGuess = $this->guesser->guessMinLength($class, $property);
|
||||
$requiredGuess = $this->guesser->guessRequired($class, $property);
|
||||
|
||||
$type = $typeGuess ? $typeGuess->getType() : 'text';
|
||||
@ -313,6 +314,14 @@ class FormFactory implements FormFactoryInterface
|
||||
$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) {
|
||||
$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
|
||||
* return values
|
||||
|
@ -42,4 +42,14 @@ interface FormTypeGuesserInterface
|
||||
* @return Guess A guess for the field's maximum length
|
||||
*/
|
||||
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)
|
||||
{
|
||||
return !$this->isIndex($index);
|
||||
return !$this->isIndex[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,7 +186,25 @@ class PropertyPath implements \IteratorAggregate
|
||||
*/
|
||||
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)
|
||||
{
|
||||
$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)) {
|
||||
$nestedObject = $this->readProperty($objectOrArray, $currentIndex);
|
||||
$nestedObject = $this->readProperty($objectOrArray, $i);
|
||||
// arrays need to be treated separately (due to PHP bug?)
|
||||
// http://bugs.php.net/bug.php?id=52133
|
||||
} else {
|
||||
} else if (is_array($objectOrArray)) {
|
||||
$property = $this->elements[$i];
|
||||
if (!array_key_exists($property, $objectOrArray)) {
|
||||
$objectOrArray[$property] = array();
|
||||
}
|
||||
|
||||
$nestedObject =& $objectOrArray[$property];
|
||||
} else {
|
||||
throw new UnexpectedTypeException($objectOrArray, 'object or array');
|
||||
}
|
||||
|
||||
$this->writePropertyPath($nestedObject, $currentIndex + 1, $value);
|
||||
} else {
|
||||
$this->writeProperty($objectOrArray, $currentIndex, $value);
|
||||
$objectOrArray =& $nestedObject;
|
||||
}
|
||||
|
||||
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];
|
||||
} else {
|
||||
$camelProp = $this->camelize($property);
|
||||
$reflClass = new \ReflectionClass($object);
|
||||
$getter = 'get'.$this->camelize($property);
|
||||
$isser = 'is'.$this->camelize($property);
|
||||
$getter = 'get'.$camelProp;
|
||||
$isser = 'is'.$camelProp;
|
||||
|
||||
if ($reflClass->hasMethod($getter)) {
|
||||
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;
|
||||
|
||||
use Symfony\Component\Locale\Exception\NotImplementedException;
|
||||
use Symfony\Component\Locale\Stub\StubIntl;
|
||||
use Symfony\Component\Locale\Stub\DateFormat\MonthTransformer;
|
||||
|
||||
/**
|
||||
@ -275,6 +276,8 @@ class FullTransformer
|
||||
|
||||
// If month is false, return immediately (intl behavior)
|
||||
if (false === $month) {
|
||||
StubIntl::setErrorCode(StubIntl::U_PARSE_ERROR);
|
||||
|
||||
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)
|
||||
{
|
||||
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');
|
||||
}
|
||||
|
||||
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());
|
||||
$formatted = $transformer->format($this->createDateTime($timestamp));
|
||||
|
||||
@ -311,6 +319,8 @@ class StubIntlDateFormatter
|
||||
throw new MethodArgumentNotImplementedException(__METHOD__, 'position');
|
||||
}
|
||||
|
||||
StubIntl::setErrorCode(StubIntl::U_ZERO_ERROR);
|
||||
|
||||
$dateTime = $this->createDateTime(0);
|
||||
$transformer = new FullTransformer($this->getPattern(), $this->getTimeZoneId());
|
||||
return $transformer->parse($dateTime, $value);
|
||||
|
@ -32,7 +32,7 @@ class TypeValidator extends ConstraintValidator
|
||||
}
|
||||
|
||||
$this->setMessage($constraint->message, array(
|
||||
'{{ value }}' => $value,
|
||||
'{{ value }}' => is_object($value) ? get_class($value) : (string)$value,
|
||||
'{{ 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()
|
||||
{
|
||||
$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))
|
||||
->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')));
|
||||
$this->factory->expects($this->at(1))
|
||||
->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')));
|
||||
|
||||
$data = array(1 => 'string', 2 => 'string');
|
||||
$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);
|
||||
|
||||
$this->assertFalse($this->form->has('0'));
|
||||
@ -73,7 +73,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$data = array();
|
||||
$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);
|
||||
|
||||
$this->assertFalse($this->form->has('$$name$$'));
|
||||
@ -85,7 +85,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$data = array();
|
||||
$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);
|
||||
|
||||
$this->assertTrue($this->form->has('$$name$$'));
|
||||
@ -98,7 +98,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$data = 'no array or traversable';
|
||||
$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);
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$data = null;
|
||||
$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);
|
||||
}
|
||||
|
||||
@ -118,12 +118,12 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$this->factory->expects($this->once())
|
||||
->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')));
|
||||
|
||||
$data = array(0 => 'string', 1 => 'string');
|
||||
$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);
|
||||
|
||||
$this->assertTrue($this->form->has('0'));
|
||||
@ -137,7 +137,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$data = array(0 => 'string');
|
||||
$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);
|
||||
|
||||
$this->assertTrue($this->form->has('0'));
|
||||
@ -151,7 +151,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$data = array();
|
||||
$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);
|
||||
|
||||
$this->assertFalse($this->form->has('0'));
|
||||
@ -164,7 +164,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$data = array(0 => 'string', 2 => 'string');
|
||||
$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);
|
||||
|
||||
$this->assertTrue($this->form->has('0'));
|
||||
@ -179,7 +179,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$data = 'no array or traversable';
|
||||
$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);
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$data = null;
|
||||
$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);
|
||||
|
||||
$this->assertFalse($this->form->has('1'));
|
||||
@ -202,7 +202,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$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);
|
||||
|
||||
$this->assertFalse($this->form->has('1'));
|
||||
@ -214,7 +214,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$data = array(0 => 'first', 1 => 'second', 2 => 'third');
|
||||
$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);
|
||||
|
||||
$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');
|
||||
$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);
|
||||
|
||||
$this->assertEquals($data, $event->getData());
|
||||
@ -239,7 +239,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$data = 'no array or traversable';
|
||||
$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);
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$data = null;
|
||||
$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);
|
||||
|
||||
$this->assertEquals(array(), $event->getData());
|
||||
|
@ -312,7 +312,7 @@ class ChoiceTypeTest extends TypeTestCase
|
||||
$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(
|
||||
'multiple' => true,
|
||||
@ -321,6 +321,6 @@ class ChoiceTypeTest extends TypeTestCase
|
||||
));
|
||||
$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(
|
||||
'type' => 'field',
|
||||
'options' => array(
|
||||
'max_length' => 20,
|
||||
),
|
||||
));
|
||||
$form->setData(array('foo@foo.com', 'foo@bar.com'));
|
||||
|
||||
@ -37,18 +40,24 @@ class CollectionFormTest extends TypeTestCase
|
||||
$this->assertEquals(2, count($form));
|
||||
$this->assertEquals('foo@foo.com', $form[0]->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'));
|
||||
$this->assertTrue($form[0] instanceof Form);
|
||||
$this->assertFalse(isset($form[1]));
|
||||
$this->assertEquals(1, count($form));
|
||||
$this->assertEquals('foo@baz.com', $form[0]->getData());
|
||||
$this->assertEquals(20, $form[0]->getAttribute('max_length'));
|
||||
}
|
||||
|
||||
public function testSetDataAddsPrototypeIfAllowAdd()
|
||||
{
|
||||
$form = $this->factory->create('collection', null, array(
|
||||
'type' => 'field',
|
||||
'options' => array(
|
||||
'max_length' => 20,
|
||||
),
|
||||
'allow_add' => true,
|
||||
'prototype' => true,
|
||||
));
|
||||
@ -57,12 +66,14 @@ class CollectionFormTest extends TypeTestCase
|
||||
$this->assertTrue($form[0] instanceof Form);
|
||||
$this->assertTrue($form[1] instanceof Form);
|
||||
$this->assertTrue($form['$$name$$'] instanceof Form);
|
||||
$this->assertEquals(20, $form['$$name$$']->getAttribute('max_length'));
|
||||
$this->assertEquals(3, count($form));
|
||||
|
||||
$form->setData(array('foo@baz.com'));
|
||||
$this->assertTrue($form[0] instanceof Form);
|
||||
$this->assertFalse(isset($form[1]));
|
||||
$this->assertTrue($form['$$name$$'] instanceof Form);
|
||||
$this->assertEquals(20, $form['$$name$$']->getAttribute('max_length'));
|
||||
$this->assertEquals(2, count($form));
|
||||
}
|
||||
|
||||
|
@ -117,6 +117,7 @@ class FieldTypeTest extends TypeTestCase
|
||||
|
||||
$this->assertEquals('name', $view->get('id'));
|
||||
$this->assertEquals('name', $view->get('name'));
|
||||
$this->assertEquals('name', $view->get('full_name'));
|
||||
}
|
||||
|
||||
public function testPassIdAndNameToViewWithParent()
|
||||
@ -126,7 +127,8 @@ class FieldTypeTest extends TypeTestCase
|
||||
$view = $parent->createView();
|
||||
|
||||
$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()
|
||||
@ -137,7 +139,8 @@ class FieldTypeTest extends TypeTestCase
|
||||
$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('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()
|
||||
|
@ -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'));
|
||||
}
|
||||
|
||||
public function testPassParentNameToView()
|
||||
public function testPassParentFullNameToView()
|
||||
{
|
||||
$parent = $this->factory->createNamed('field', 'parent');
|
||||
$parent->add($this->factory->createNamed('radio', 'child'));
|
||||
$view = $parent->createView();
|
||||
|
||||
$this->assertEquals('parent', $view['child']->get('name'));
|
||||
$this->assertEquals('parent', $view['child']->get('full_name'));
|
||||
}
|
||||
|
||||
public function testCheckedIfDataTrue()
|
||||
|
@ -159,6 +159,7 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
$form->bind('new');
|
||||
|
||||
$this->assertEquals('initial', $form->getData());
|
||||
$this->assertTrue($form->isBound());
|
||||
}
|
||||
|
||||
public function testNeverRequiredIfParentNotRequired()
|
||||
@ -297,6 +298,14 @@ class FormTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($this->form->isValid());
|
||||
}
|
||||
|
||||
public function testValidIfBoundAndReadOnly()
|
||||
{
|
||||
$form = $this->getBuilder()->setReadOnly(true)->getForm();
|
||||
$form->bind('foobar');
|
||||
|
||||
$this->assertTrue($form->isValid());
|
||||
}
|
||||
|
||||
public function testNotValidIfNotBound()
|
||||
{
|
||||
$this->assertFalse($this->form->isValid());
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Tests\Component\Locale\Stub;
|
||||
require_once __DIR__.'/../TestCase.php';
|
||||
|
||||
use Symfony\Component\Locale\Locale;
|
||||
use Symfony\Component\Locale\Stub\StubIntl;
|
||||
use Symfony\Component\Locale\Stub\StubIntlDateFormatter;
|
||||
use Symfony\Tests\Component\Locale\TestCase as LocaleTestCase;
|
||||
|
||||
@ -55,21 +56,27 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
||||
/**
|
||||
* @dataProvider formatProvider
|
||||
*/
|
||||
public function testFormatStub($pattern, $timestamp, $expected)
|
||||
public function testFormatStub($pattern, $timestamp, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
|
||||
{
|
||||
$formatter = $this->createStubFormatter($pattern);
|
||||
$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
|
||||
*/
|
||||
public function testFormatIntl($pattern, $timestamp, $expected)
|
||||
public function testFormatIntl($pattern, $timestamp, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
|
||||
{
|
||||
$this->skipIfIntlExtensionIsNotLoaded();
|
||||
$this->skipIfICUVersionIsTooOld();
|
||||
$formatter = $this->createIntlFormatter($pattern);
|
||||
$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()
|
||||
@ -248,6 +255,10 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
||||
array('zzz', 0, 'GMT+00:00'),
|
||||
array('zzzz', 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;
|
||||
@ -481,20 +492,26 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
||||
/**
|
||||
* @dataProvider parseProvider
|
||||
*/
|
||||
public function testParseIntl($pattern, $value, $expected)
|
||||
public function testParseIntl($pattern, $value, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
|
||||
{
|
||||
$this->skipIfIntlExtensionIsNotLoaded();
|
||||
$formatter = $this->createIntlFormatter($pattern);
|
||||
$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
|
||||
*/
|
||||
public function testParseStub($pattern, $value, $expected)
|
||||
public function testParseStub($pattern, $value, $expected, $errorCode = 0, $errorMessage = 'U_ZERO_ERROR')
|
||||
{
|
||||
$formatter = $this->createStubFormatter($pattern);
|
||||
$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()
|
||||
@ -511,8 +528,8 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
||||
array('y-MMMM-d', '1970-January-1', 0),
|
||||
|
||||
// 1 char month
|
||||
array('y-MMMMM-d', '1970-J-1', false),
|
||||
array('y-MMMMM-d', '1970-S-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, 9, 'Date parsing failed: U_PARSE_ERROR'),
|
||||
|
||||
// standalone months
|
||||
array('y-L-d', '1970-1-1', 0),
|
||||
@ -520,8 +537,8 @@ class StubIntlDateFormatterTest extends LocaleTestCase
|
||||
array('y-LLLL-d', '1970-January-1', 0),
|
||||
|
||||
// standalone 1 char month
|
||||
array('y-LLLLL-d', '1970-J-1', false),
|
||||
array('y-LLLLL-d', '1970-S-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, 9, 'Date parsing failed: U_PARSE_ERROR'),
|
||||
|
||||
// days
|
||||
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\TypeValidator;
|
||||
use Symfony\Component\Validator\ConstraintViolation;
|
||||
|
||||
class TypeValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
@ -84,6 +85,22 @@ class TypeValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$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()
|
||||
{
|
||||
$object = new \stdClass();
|
||||
|
Reference in New Issue
Block a user