Release 2.16 (#4780)
This commit is contained in:
@@ -15,6 +15,7 @@ use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Validator\Constraints\GreaterThan;
|
||||
|
||||
final class AccessTokenForm extends AbstractType
|
||||
{
|
||||
@@ -27,6 +28,11 @@ final class AccessTokenForm extends AbstractType
|
||||
->add('expiresAt', DatePickerType::class, [
|
||||
'label' => 'expires',
|
||||
'required' => false,
|
||||
'force_time' => 'end',
|
||||
'min_day' => $options['min_date'],
|
||||
'constraints' => [
|
||||
new GreaterThan($options['min_date'])
|
||||
],
|
||||
])
|
||||
;
|
||||
}
|
||||
@@ -41,6 +47,8 @@ final class AccessTokenForm extends AbstractType
|
||||
'attr' => [
|
||||
'data-form-event' => 'kimai.accessToken'
|
||||
],
|
||||
'min_date' => new \DateTimeImmutable('today 00:00:00'),
|
||||
]);
|
||||
$resolver->setAllowedTypes('min_date', [\DateTimeInterface::class]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,12 +61,12 @@ class DatePickerType extends AbstractType
|
||||
{
|
||||
if ($options['min_day'] !== null) {
|
||||
$view->vars['attr'] = array_merge($view->vars['attr'], [
|
||||
'min' => $options['min_day'],
|
||||
'min' => (\is_string($options['min_day']) ? $options['min_day'] : $options['min_day']->format('Y-m-d')), // @phpstan-ignore-line
|
||||
]);
|
||||
}
|
||||
if ($options['max_day'] !== null) {
|
||||
$view->vars['attr'] = array_merge($view->vars['attr'], [
|
||||
'max' => $options['max_day'],
|
||||
'max' => (\is_string($options['max_day']) ? $options['max_day'] : $options['max_day']->format('Y-m-d')), // @phpstan-ignore-line
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -84,10 +84,13 @@ class DatePickerType extends AbstractType
|
||||
'format' => $formFormat,
|
||||
'model_timezone' => date_default_timezone_get(),
|
||||
'view_timezone' => date_default_timezone_get(),
|
||||
'force_time' => null, // one of: string (start, end) or a string to as argument for DateTime->modify() or null
|
||||
'force_time' => null, // one of: null, string (start, end) or a string working as argument for DateTime->modify() or null
|
||||
'min_day' => null,
|
||||
'max_day' => null,
|
||||
]);
|
||||
|
||||
$resolver->addAllowedTypes('min_day', ['null', 'string', \DateTimeInterface::class]);
|
||||
$resolver->addAllowedTypes('max_day', ['null', 'string', \DateTimeInterface::class]);
|
||||
}
|
||||
|
||||
public function getParent(): string
|
||||
|
||||
@@ -49,6 +49,9 @@ final class DateRangeType extends AbstractType
|
||||
'max_day' => null,
|
||||
'locale' => \Locale::getDefault(),
|
||||
]);
|
||||
$resolver->addAllowedTypes('timezone', ['string']);
|
||||
$resolver->addAllowedTypes('min_day', ['null', 'string', \DateTimeInterface::class]);
|
||||
$resolver->addAllowedTypes('max_day', ['null', 'string', \DateTimeInterface::class]);
|
||||
|
||||
$resolver->setDefault('format', function (Options $options): string {
|
||||
$format = $this->localeService->getDateFormat($options['locale']);
|
||||
@@ -101,13 +104,13 @@ final class DateRangeType extends AbstractType
|
||||
|
||||
if ($options['min_day'] !== null) {
|
||||
$view->vars['attr'] = array_merge($view->vars['attr'], [
|
||||
'min' => $options['min_day'],
|
||||
'min' => (\is_string($options['min_day']) ? $options['min_day'] : $options['min_day']->format('Y-m-d')), // @phpstan-ignore-line
|
||||
]);
|
||||
}
|
||||
|
||||
if ($options['max_day'] !== null) {
|
||||
$view->vars['attr'] = array_merge($view->vars['attr'], [
|
||||
'max' => $options['max_day'],
|
||||
'max' => (\is_string($options['max_day']) ? $options['max_day'] : $options['max_day']->format('Y-m-d')), // @phpstan-ignore-line
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -160,6 +163,18 @@ final class DateRangeType extends AbstractType
|
||||
$formatDate
|
||||
);
|
||||
|
||||
$fallbackFormat = 'yyyy-MM-dd';
|
||||
$fallbackPattern = (new FormFormatConverter())->convertToPattern($fallbackFormat . $separator . $fallbackFormat, false);
|
||||
|
||||
$fallbackTransformer = new DateTimeToLocalizedStringTransformer(
|
||||
$timezone,
|
||||
$timezone,
|
||||
IntlDateFormatter::MEDIUM,
|
||||
IntlDateFormatter::MEDIUM,
|
||||
IntlDateFormatter::GREGORIAN,
|
||||
$fallbackFormat
|
||||
);
|
||||
|
||||
$range = new DateRange();
|
||||
|
||||
if (empty($dates) && $allowEmpty) {
|
||||
@@ -170,7 +185,7 @@ final class DateRangeType extends AbstractType
|
||||
throw new TransformationFailedException('Date range missing');
|
||||
}
|
||||
|
||||
if (preg_match($pattern, $dates) !== 1) {
|
||||
if (preg_match($pattern, $dates) !== 1 && preg_match($fallbackPattern, $dates) !== 1) {
|
||||
throw new TransformationFailedException('Invalid date range given');
|
||||
}
|
||||
$values = explode($separator, $dates);
|
||||
@@ -179,13 +194,23 @@ final class DateRangeType extends AbstractType
|
||||
throw new TransformationFailedException('Invalid date range given');
|
||||
}
|
||||
|
||||
$begin = $transformer->reverseTransform($values[0]);
|
||||
try {
|
||||
$begin = $transformer->reverseTransform($values[0]);
|
||||
} catch (TransformationFailedException $e) {
|
||||
// we always allow english format to simplify cross-linking
|
||||
$begin = $fallbackTransformer->reverseTransform($values[0]);
|
||||
}
|
||||
if ($begin === null) {
|
||||
throw new TransformationFailedException('Invalid begin date given');
|
||||
}
|
||||
$range->setBegin($begin);
|
||||
|
||||
$end = $transformer->reverseTransform($values[1]);
|
||||
try {
|
||||
$end = $transformer->reverseTransform($values[1]);
|
||||
} catch (TransformationFailedException $e) {
|
||||
// we always allow english format to simplify cross-linking
|
||||
$end = $fallbackTransformer->reverseTransform($values[1]);
|
||||
}
|
||||
if ($end === null) {
|
||||
throw new TransformationFailedException('Invalid end date given');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user