diff --git a/src/View/Helper/CrudViewHelper.php b/src/View/Helper/CrudViewHelper.php index a7a7c59..b455940 100644 --- a/src/View/Helper/CrudViewHelper.php +++ b/src/View/Helper/CrudViewHelper.php @@ -4,10 +4,14 @@ namespace CrudView\View\Helper; use BackedEnum; +use Cake\Chronos\ChronosDate; +use Cake\Chronos\ChronosTime; use Cake\Core\Exception\CakeException; use Cake\Database\Type\EnumLabelInterface; use Cake\Datasource\EntityInterface; use Cake\Datasource\SchemaInterface; +use Cake\I18n\Date; +use Cake\I18n\Time; use Cake\Utility\Inflector; use Cake\Utility\Text; use Cake\View\Form\EntityContext; @@ -44,6 +48,9 @@ class CrudViewHelper extends Helper */ protected array $_defaultConfig = [ 'fieldFormatters' => null, + 'dateTimeFormat' => null, + 'dateFormat' => null, + 'timeFormat' => null, ]; /** @@ -152,12 +159,8 @@ public function introspect(string $field, mixed $value, array $options = []): ar return $this->formatBoolean($field, $value, $options); } - if (in_array($type, ['datetime', 'date', 'timestamp'])) { - return $this->formatDate($field, $value, $options); - } - - if ($type === 'time') { - return $this->formatTime($field, $value, $options); + if (in_array($type, ['datetime', 'date', 'time', 'timestamp'], true)) { + return $this->formatDateTime($field, $value, $options); } if ($type !== null && str_starts_with($type, 'enum-')) { @@ -207,33 +210,26 @@ public function formatBoolean(string $field, mixed $value, array $options): stri * @param array $options Options array. * @return string */ - public function formatDate(string $field, mixed $value, array $options): string + public function formatDateTime(string $field, mixed $value, array $options): string { if ($value === null) { return $this->Html->badge(__d('crud', 'N/A'), ['class' => 'info']); } - return $this->Time->timeAgoInWords($value, $options); - } + if ($value instanceof Date) { + return $value->i18nFormat($options['format'] ?? $this->getConfig('dateFormat')); + } - /** - * Format a time for display - * - * @param string $field Name of field. - * @param mixed $value Value of field. - * @param array $options Options array. - * @return string - */ - public function formatTime(string $field, mixed $value, array $options): string - { - $format = $options['format'] ?? 'KK:mm:ss a'; - /** @var string $value */ - $value = $this->Time->format($value, $format, ''); - if ($value === '') { - return $this->Html->badge(__d('crud', 'N/A'), ['class' => 'info']); + if ($value instanceof Time) { + return $value->i18nFormat($options['format'] ?? $this->getConfig('timeFormat')); } - return $value; + if ($value instanceof ChronosDate || $value instanceof ChronosTime) { + return (string)$value; + } + + return $this->Time->i18nFormat($value, $options['format'] ?? $this->getConfig('dateTimeFormat'), '') + ?: $this->Html->badge(__d('crud', 'N/A'), ['class' => 'info']); } /** diff --git a/tests/Fixture/UsersFixture.php b/tests/Fixture/UsersFixture.php index 9248a6e..6a0d379 100644 --- a/tests/Fixture/UsersFixture.php +++ b/tests/Fixture/UsersFixture.php @@ -8,6 +8,6 @@ class UsersFixture extends TestFixture { public array $records = [ - ['username' => 'ADmad', 'birth_date' => '2000-01-01'], + ['username' => 'ADmad', 'birth_date' => '2000-01-15'], ]; } diff --git a/tests/TestCase/View/CrudViewTest.php b/tests/TestCase/View/CrudViewTest.php index cee98ee..3f29216 100644 --- a/tests/TestCase/View/CrudViewTest.php +++ b/tests/TestCase/View/CrudViewTest.php @@ -30,6 +30,9 @@ public function testCreation() $expected = [ 'className' => 'CrudView.CrudView', 'fieldFormatters' => ['datetime' => 'formatTime'], + 'dateTimeFormat' => null, + 'dateFormat' => null, + 'timeFormat' => null, ]; $result = $CrudView->CrudView->getConfig(); $this->assertEquals($expected, $result); diff --git a/tests/TestCase/View/Helper/CrudViewHelperTest.php b/tests/TestCase/View/Helper/CrudViewHelperTest.php index 6acec89..9307a7e 100644 --- a/tests/TestCase/View/Helper/CrudViewHelperTest.php +++ b/tests/TestCase/View/Helper/CrudViewHelperTest.php @@ -4,6 +4,7 @@ namespace CrudView\Test\TestCase\View\Helper; use Cake\I18n\DateTime; +use Cake\I18n\Time; use Cake\TestSuite\TestCase; use Cake\View\View; use CrudView\View\Helper\CrudViewHelper; @@ -41,7 +42,7 @@ public function setUp(): void static::setAppNamespace(); } - public function testIntrospect() + public function testIntrospect(): void { $entity = $this->fetchTable('Blogs')->find()->first(); $entity->created = new DateTime(); @@ -50,13 +51,7 @@ public function testIntrospect() $value = $entity->created; $result = $this->CrudView->introspect('created', $value); - $this->assertEquals('just now', $result); - - $this->CrudView->setConfig('fieldFormatters', [ - 'datetime' => 'formatTime', - ]); - $result = $this->CrudView->introspect('created', $value); - $this->assertEquals($this->CrudView->Time->format($value, 'KK:mm:ss a'), $result); + $this->assertEquals($entity->created->i18nFormat(), $result); $result = $this->CrudView->introspect('created', 'invalid'); $this->assertEquals('N/A', $result); @@ -73,15 +68,31 @@ public function testIntrospect() $this->assertEquals('formatted time', $result); } - public function testProcess() + public function testProcess(): void { $entity = $this->fetchTable('Blogs')->find() ->contain('Users') ->first(); $this->assertSame( - 'on 1/1/00', + '1/15/00', $this->CrudView->process('user.birth_date', $entity) ); } + + public function testFormatDateTime(): void + { + $dateTime = new Time('14:00:00'); + + $result = $this->CrudView->formatDateTime('field', $dateTime, []); + $this->assertEquals('2:00 PM', $result); + + Time::setToStringFormat('KK:mm:ss a'); + $result = $this->CrudView->formatDateTime('field', $dateTime, []); + $this->assertEquals('02:00:00 PM', $result); + + $dateTime = new DateTime('2021-01-20 14:00:00'); + $result = $this->CrudView->formatDateTime('field', $dateTime, []); + $this->assertEquals('1/20/21, 2:00 PM', $result); + } }