Skip to content

Commit

Permalink
Merge pull request #98 from cakephp/fix-97
Browse files Browse the repository at this point in the history
Add shim for date filter
  • Loading branch information
markstory authored Jul 2, 2024
2 parents 8b543dd + c6dd2d1 commit 2bda8f7
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 1 deletion.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"cakephp/cakephp": "^5.0.0",
"jasny/twig-extensions": "^1.3",
"twig/markdown-extra": "^3.0",
"twig/twig": "^3.4"
"twig/twig": "^3.10.3"
},
"require-dev": {
"cakephp/cakephp-codesniffer": "^5.0",
Expand Down
49 changes: 49 additions & 0 deletions src/Twig/Extension/TimeExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,34 @@

namespace Cake\TwigView\Twig\Extension;

use Cake\Chronos\Chronos;
use Cake\Chronos\ChronosDate;
use Cake\I18n\DateTime;
use DateTimeZone;
use Twig\Extension\AbstractExtension;
use Twig\Extension\CoreExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

/**
* Class TimeExtension.
*/
class TimeExtension extends AbstractExtension
{
private ?CoreExtension $coreExt;

/**
* Get declared filters.
*
* @return array<\Twig\TwigFilter>
*/
public function getFilters(): array
{
return [
new TwigFilter('date', [$this, 'formatDate']),
];
}

/**
* Get declared functions.
*
Expand All @@ -35,10 +54,40 @@ class TimeExtension extends AbstractExtension
public function getFunctions(): array
{
return [
new TwigFunction('date', function ($time = null, $timezone = null) {
return new DateTime($time, $timezone);
}),
new TwigFunction('time', function ($time = null, $timezone = null) {
return new DateTime($time, $timezone);
}),
new TwigFunction('timezones', 'Cake\I18n\DateTime::listTimezones'),
];
}

/**
* Format a date/datetime value
*
* Includes shims for \Chronos\ChronosDate as Twig doesn't.
*
* @param mixed $date The date to format.
* @param ?string $format The format to use, null to use the default.
* @param \DateTimeZone|string|false|null $timezone The target timezone, null to use system.
*/
public function formatDate(
mixed $date,
?string $format = null,
DateTimeZone|string|false|null $timezone = null
): string {
if (!isset($this->coreExt)) {
$this->coreExt = new CoreExtension();
}
if ($date instanceof ChronosDate) {
$date = $date->toDateString();
}
if ($date instanceof Chronos) {
$date = $date->toIso8601String();
}

return $this->coreExt->formatDate($date, $format, $timezone);
}
}
24 changes: 24 additions & 0 deletions tests/TestCase/View/TwigViewTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
namespace Cake\TwigView\Test\TestCase\View;

use Cake\Core\Configure;
use Cake\I18n\Date;
use Cake\I18n\DateTime;
use Cake\I18n\I18n;
use Cake\TestSuite\TestCase;
use TestApp\View\AppView;
use Twig\Error\RuntimeError;
Expand Down Expand Up @@ -136,6 +139,27 @@ public function testCellsShareTwig()
$this->assertSame($this->view->getTwig(), $cell->createView(AppView::class)->getTwig());
}

/**
* Test that Cake date/time objects are formatted correctly
*/
public function testTwigDateFormat()
{
$restore = I18n::getLocale();
I18n::setLocale('fr');

$this->view->set('date', new Date('2024-06-24'));
$this->view->set('datetime', new DateTime('2024-06-24 12:13:14'));

$output = $this->view->render('date_format', false);
I18n::setLocale($restore);

$expected = <<<TEXT
Date: 2024/06/24
Datetime: 2024/06/24 12:13:14
TEXT;
$this->assertSame($expected, $output);
}

/**
* Tests rendering with markdown.
*
Expand Down
2 changes: 2 additions & 0 deletions tests/test_app/templates/date_format.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Date: {{ date|date('Y/m/d') }}
Datetime: {{ datetime|date('Y/m/d H:i:s') }}

0 comments on commit 2bda8f7

Please sign in to comment.