Skip to content

Commit

Permalink
UI: Fix datetime-local Value in Wrong Format
Browse files Browse the repository at this point in the history
  • Loading branch information
kergomard authored and klees committed Oct 23, 2023
1 parent 33e14e0 commit 8130072
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ public function toFormInput(

if (!is_null($this->getEventTime())) {
$event_time = $event_time->withValue(
$this->getEventTime()->format($date_format->toString() . ' HH:mm')
$this->getEventTime()
);
}

Expand Down
27 changes: 21 additions & 6 deletions src/UI/Implementation/Component/Input/Field/DateTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,9 @@ public function withValue($value): self
// TODO: It would be a lot nicer if the value would be held as DateTimeImmutable
// internally, but currently this is just to much. Added to the roadmap.
if ($value instanceof \DateTimeImmutable) {
$value = $this->format->applyTo($value);
$value = $value->format(Renderer::HTML5_NATIVE_DATETIME_FORMAT);
}

$clone = clone $this;
$clone->value = $value;
return $clone;
return parent::withValue($value);
}

public function withFormat(DateFormat $format): self
Expand Down Expand Up @@ -176,7 +173,25 @@ public function getTimeOnly(): bool

public function isClientSideValueOk($value): bool
{
return is_string($value);
if ($value instanceof \DateTimeImmutable || is_null($value)) {
return true;
}

if (!is_string($value)) {
return false;
}

try {
new \DateTimeImmutable($value);
return true;
}
// We should mostly not catch generic Throwables because we will be masking
// a lot of error conditions in this way... But, unfortunately, I cannot
// currently see a better way to check if \DateTimeImmutable would accept
// the supplied $value, so here we go...
catch (\Throwable $e) {
return false;
}
}

protected function getConstraintForRequirement(): ?Constraint
Expand Down
15 changes: 14 additions & 1 deletion src/UI/Implementation/Component/Input/Field/Renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class Renderer extends AbstractComponentRenderer
public const TYPE_DATE = 'date';
public const TYPE_DATETIME = 'datetime-local';
public const TYPE_TIME = 'time';
public const HTML5_NATIVE_DATETIME_FORMAT = 'Y-m-d H:i';
public const HTML5_NATIVE_DATE_FORMAT = 'Y-m-d';
public const HTML5_NATIVE_TIME_FORMAT = 'H:i';

public const DATEPICKER_FORMAT_MAPPING = [
'd' => 'DD',
Expand Down Expand Up @@ -671,7 +674,17 @@ protected function renderDateTimeField(F\DateTime $component, RendererInterface

$tpl->setVariable("PLACEHOLDER", $format);

$this->applyValue($component, $tpl, $this->escapeSpecialChars());
$this->applyValue($component, $tpl, function (?string $value) use ($dt_type) {
if ($value !== null) {
$value = new \DateTimeImmutable($value);
return $value->format(match ($dt_type) {
self::TYPE_DATETIME => self::HTML5_NATIVE_DATETIME_FORMAT,
self::TYPE_DATE => self::HTML5_NATIVE_DATE_FORMAT,
self::TYPE_TIME => self::HTML5_NATIVE_TIME_FORMAT,
});
}
return null;
});
$this->maybeDisable($component, $tpl);
$id = $this->bindJSandApplyId($component, $tpl);
return $this->wrapInFormContext($component, $tpl->get(), $id);
Expand Down
9 changes: 8 additions & 1 deletion tests/UI/Component/Input/Field/DateTimeInputTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ public function testWithInvalidTimeZone(): void

public function testWithValueThatIsDateTimeImmutable(): void
{
$string_value = "1985-05-04";
$string_value = "1985-05-04 00:00";
$value = new \DateTimeImmutable($string_value);
$datetime = $this->factory->datetime('label', 'byline')
->withValue($value);
Expand All @@ -159,4 +159,11 @@ public function testWithValueThatIsDateTimeImmutable(): void
$datetime->getValue()
);
}

public function testWithInvalidValue(): void
{
$this->expectException(InvalidArgumentException::class);
$datetime = $this->factory->datetime('label', 'byline')
->withValue("this is no datetime...");
}
}

0 comments on commit 8130072

Please sign in to comment.