|
@@ -12,8 +12,11 @@
|
|
namespace Symfony\Component\Form\Extension\Core\Type;
|
|
namespace Symfony\Component\Form\Extension\Core\Type;
|
|
|
|
|
|
use Symfony\Component\Form\AbstractType;
|
|
use Symfony\Component\Form\AbstractType;
|
|
|
|
+use Symfony\Component\Form\FormInterface;
|
|
use Symfony\Component\Form\FormBuilder;
|
|
use Symfony\Component\Form\FormBuilder;
|
|
|
|
+use Symfony\Component\Form\FormView;
|
|
use Symfony\Component\Form\ReversedTransformer;
|
|
use Symfony\Component\Form\ReversedTransformer;
|
|
|
|
+use Symfony\Component\Form\Exception\FormException;
|
|
use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain;
|
|
use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain;
|
|
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
|
|
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
|
|
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
|
|
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToStringTransformer;
|
|
@@ -27,38 +30,6 @@ class DateTimeType extends AbstractType
|
|
*/
|
|
*/
|
|
public function buildForm(FormBuilder $builder, array $options)
|
|
public function buildForm(FormBuilder $builder, array $options)
|
|
{
|
|
{
|
|
- // Only pass a subset of the options to children
|
|
|
|
- $dateOptions = array_intersect_key($options, array_flip(array(
|
|
|
|
- 'years',
|
|
|
|
- 'months',
|
|
|
|
- 'days',
|
|
|
|
- 'empty_value',
|
|
|
|
- 'required',
|
|
|
|
- )));
|
|
|
|
- $timeOptions = array_intersect_key($options, array_flip(array(
|
|
|
|
- 'hours',
|
|
|
|
- 'minutes',
|
|
|
|
- 'seconds',
|
|
|
|
- 'with_seconds',
|
|
|
|
- 'empty_value',
|
|
|
|
- 'required',
|
|
|
|
- )));
|
|
|
|
-
|
|
|
|
- if (isset($options['date_widget'])) {
|
|
|
|
- $dateOptions['widget'] = $options['date_widget'];
|
|
|
|
- }
|
|
|
|
- if (isset($options['date_format'])) {
|
|
|
|
- $dateOptions['format'] = $options['date_format'];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- $dateOptions['input'] = 'array';
|
|
|
|
-
|
|
|
|
- if (isset($options['time_widget'])) {
|
|
|
|
- $timeOptions['widget'] = $options['time_widget'];
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- $timeOptions['input'] = 'array';
|
|
|
|
-
|
|
|
|
$parts = array('year', 'month', 'day', 'hour', 'minute');
|
|
$parts = array('year', 'month', 'day', 'hour', 'minute');
|
|
$timeParts = array('hour', 'minute');
|
|
$timeParts = array('hour', 'minute');
|
|
|
|
|
|
@@ -67,17 +38,63 @@ class DateTimeType extends AbstractType
|
|
$timeParts[] = 'second';
|
|
$timeParts[] = 'second';
|
|
}
|
|
}
|
|
|
|
|
|
- $builder
|
|
|
|
- ->appendClientTransformer(new DataTransformerChain(array(
|
|
|
|
- new DateTimeToArrayTransformer($options['data_timezone'], $options['user_timezone'], $parts),
|
|
|
|
- new ArrayToPartsTransformer(array(
|
|
|
|
- 'date' => array('year', 'month', 'day'),
|
|
|
|
- 'time' => $timeParts,
|
|
|
|
- )),
|
|
|
|
- )))
|
|
|
|
- ->add('date', 'date', $dateOptions)
|
|
|
|
- ->add('time', 'time', $timeOptions)
|
|
|
|
- ;
|
|
|
|
|
|
+ if ($options['date_widget'] !== $options['time_widget']) {
|
|
|
|
+ throw new FormException(sprintf('Options "date_widget" and "time_widget" need to be identical. Used: "date_widget" = "%s" and "time_widget" = "%s".', $options['date_widget'] ?: 'choice', $options['time_widget'] ?: 'choice'));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ($options['widget'] === 'single_text') {
|
|
|
|
+ $builder->appendClientTransformer(new DateTimeToStringTransformer($options['data_timezone'], $options['user_timezone'], 'Y-m-d H:i:s'));
|
|
|
|
+ } else {
|
|
|
|
+ // Only pass a subset of the options to children
|
|
|
|
+ $dateOptions = array_intersect_key($options, array_flip(array(
|
|
|
|
+ 'years',
|
|
|
|
+ 'months',
|
|
|
|
+ 'days',
|
|
|
|
+ 'empty_value',
|
|
|
|
+ 'required',
|
|
|
|
+ )));
|
|
|
|
+ $timeOptions = array_intersect_key($options, array_flip(array(
|
|
|
|
+ 'hours',
|
|
|
|
+ 'minutes',
|
|
|
|
+ 'seconds',
|
|
|
|
+ 'with_seconds',
|
|
|
|
+ 'empty_value',
|
|
|
|
+ 'required',
|
|
|
|
+ )));
|
|
|
|
+
|
|
|
|
+ // If `widget` is set, overwrite widget options from `date` and `time`
|
|
|
|
+ if (isset($options['widget'])) {
|
|
|
|
+ $dateOptions['widget'] = $options['widget'];
|
|
|
|
+ $timeOptions['widget'] = $options['widget'];
|
|
|
|
+ } else {
|
|
|
|
+ if (isset($options['date_widget'])) {
|
|
|
|
+ $dateOptions['widget'] = $options['date_widget'];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (isset($options['time_widget'])) {
|
|
|
|
+ $timeOptions['widget'] = $options['time_widget'];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (isset($options['date_format'])) {
|
|
|
|
+ $dateOptions['format'] = $options['date_format'];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ $dateOptions['input'] = 'array';
|
|
|
|
+ $timeOptions['input'] = 'array';
|
|
|
|
+
|
|
|
|
+ $builder
|
|
|
|
+ ->appendClientTransformer(new DataTransformerChain(array(
|
|
|
|
+ new DateTimeToArrayTransformer($options['data_timezone'], $options['user_timezone'], $parts),
|
|
|
|
+ new ArrayToPartsTransformer(array(
|
|
|
|
+ 'date' => array('year', 'month', 'day'),
|
|
|
|
+ 'time' => $timeParts,
|
|
|
|
+ )),
|
|
|
|
+ )))
|
|
|
|
+ ->add('date', 'date', $dateOptions)
|
|
|
|
+ ->add('time', 'time', $timeOptions)
|
|
|
|
+ ;
|
|
|
|
+ }
|
|
|
|
|
|
if ($options['input'] === 'string') {
|
|
if ($options['input'] === 'string') {
|
|
$builder->appendNormTransformer(new ReversedTransformer(
|
|
$builder->appendNormTransformer(new ReversedTransformer(
|
|
@@ -92,6 +109,16 @@ class DateTimeType extends AbstractType
|
|
new DateTimeToArrayTransformer($options['data_timezone'], $options['data_timezone'], $parts)
|
|
new DateTimeToArrayTransformer($options['data_timezone'], $options['data_timezone'], $parts)
|
|
));
|
|
));
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ $builder->setAttribute('widget', $options['widget']);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * {@inheritdoc}
|
|
|
|
+ */
|
|
|
|
+ public function buildView(FormView $view, FormInterface $form)
|
|
|
|
+ {
|
|
|
|
+ $view->set('widget', $form->getAttribute('widget'));
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -103,10 +130,6 @@ class DateTimeType extends AbstractType
|
|
'input' => 'datetime',
|
|
'input' => 'datetime',
|
|
'data_timezone' => null,
|
|
'data_timezone' => null,
|
|
'user_timezone' => null,
|
|
'user_timezone' => null,
|
|
- 'empty_value' => null,
|
|
|
|
- // Don't modify \DateTime classes by reference, we treat
|
|
|
|
- // them like immutable value objects
|
|
|
|
- 'by_reference' => false,
|
|
|
|
'date_widget' => null,
|
|
'date_widget' => null,
|
|
'date_format' => null,
|
|
'date_format' => null,
|
|
'time_widget' => null,
|
|
'time_widget' => null,
|
|
@@ -119,6 +142,13 @@ class DateTimeType extends AbstractType
|
|
'minutes' => range(0, 59),
|
|
'minutes' => range(0, 59),
|
|
'seconds' => range(0, 59),
|
|
'seconds' => range(0, 59),
|
|
'with_seconds' => false,
|
|
'with_seconds' => false,
|
|
|
|
+ // Don't modify \DateTime classes by reference, we treat
|
|
|
|
+ // them like immutable value objects
|
|
|
|
+ 'by_reference' => false,
|
|
|
|
+ // This will overwrite "widget" child options
|
|
|
|
+ 'widget' => null,
|
|
|
|
+ // This will overwrite "empty_value" child options
|
|
|
|
+ 'empty_value' => null,
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -128,34 +158,49 @@ class DateTimeType extends AbstractType
|
|
public function getAllowedOptionValues(array $options)
|
|
public function getAllowedOptionValues(array $options)
|
|
{
|
|
{
|
|
return array(
|
|
return array(
|
|
- 'input' => array(
|
|
|
|
|
|
+ 'input' => array(
|
|
'datetime',
|
|
'datetime',
|
|
'string',
|
|
'string',
|
|
'timestamp',
|
|
'timestamp',
|
|
'array',
|
|
'array',
|
|
),
|
|
),
|
|
- 'date_widget' => array(
|
|
|
|
|
|
+ 'date_widget' => array(
|
|
null, // inherit default from DateType
|
|
null, // inherit default from DateType
|
|
'single_text',
|
|
'single_text',
|
|
'text',
|
|
'text',
|
|
'choice',
|
|
'choice',
|
|
),
|
|
),
|
|
- 'date_format' => array(
|
|
|
|
|
|
+ 'date_format' => array(
|
|
null, // inherit default from DateType
|
|
null, // inherit default from DateType
|
|
\IntlDateFormatter::FULL,
|
|
\IntlDateFormatter::FULL,
|
|
\IntlDateFormatter::LONG,
|
|
\IntlDateFormatter::LONG,
|
|
\IntlDateFormatter::MEDIUM,
|
|
\IntlDateFormatter::MEDIUM,
|
|
\IntlDateFormatter::SHORT,
|
|
\IntlDateFormatter::SHORT,
|
|
),
|
|
),
|
|
- 'time_widget' => array(
|
|
|
|
|
|
+ 'time_widget' => array(
|
|
null, // inherit default from TimeType
|
|
null, // inherit default from TimeType
|
|
'single_text',
|
|
'single_text',
|
|
'text',
|
|
'text',
|
|
'choice',
|
|
'choice',
|
|
),
|
|
),
|
|
|
|
+ // This option will overwrite "date_widget" and "time_widget" options
|
|
|
|
+ 'widget' => array(
|
|
|
|
+ null, // default, don't overwrite options
|
|
|
|
+ 'single_text',
|
|
|
|
+ 'text',
|
|
|
|
+ 'choice',
|
|
|
|
+ ),
|
|
);
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * {@inheritdoc}
|
|
|
|
+ */
|
|
|
|
+ public function getParent(array $options)
|
|
|
|
+ {
|
|
|
|
+ return $options['widget'] === 'single_text' ? 'field' : 'form';
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* {@inheritdoc}
|
|
* {@inheritdoc}
|
|
*/
|
|
*/
|