Skip to content

Commit f0a1b14

Browse files
committed
Add BC localizeddate twig filter
1 parent d10ad3c commit f0a1b14

File tree

4 files changed

+130
-1
lines changed

4 files changed

+130
-1
lines changed

ci/qa/phpstan-baseline.neon

+5
Original file line numberDiff line numberDiff line change
@@ -3435,6 +3435,11 @@ parameters:
34353435
count: 1
34363436
path: ../../src/Surfnet/StepupMiddleware/CommandHandlingBundle/Tests/SensitiveData/SensitiveDataTest.php
34373437

3438+
-
3439+
message: "#^Method Surfnet\\\\StepupMiddleware\\\\CommandHandlingBundle\\\\Tests\\\\Twig\\\\BackwardsCompatibleExtensionTest\\:\\:templateProvider\\(\\) return type has no value type specified in iterable type array\\.$#"
3440+
count: 1
3441+
path: ../../src/Surfnet/StepupMiddleware/CommandHandlingBundle/Tests/Twig/BackwardsCompatibleExtensionTest.php
3442+
34383443
-
34393444
message: "#^Method Surfnet\\\\StepupMiddleware\\\\CommandHandlingBundle\\\\Tests\\\\Value\\\\InstitutionTest\\:\\:nonStringOrNonEmptyStringProvider\\(\\) return type has no value type specified in iterable type array\\.$#"
34403445
count: 1

config/services.yaml

+5-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ services:
1414
- "@surfnet_stepup.service.second_factor_type"
1515
- '%skip_prove_possession_second_factors%'
1616

17+
Surfnet\StepupMiddleware\CommandHandlingBundle\Twig\BackwardsCompatibleExtension:
18+
arguments: [ "@twig.extension.intl"]
19+
tags: [{ name: twig.extension }]
20+
1721
twig.extension.stringloader:
1822
class: Twig\Extension\StringLoaderExtension
1923
tags: [{ name: twig.extension }]
@@ -27,7 +31,7 @@ services:
2731
class: Twig\Sandbox\SecurityPolicy
2832
arguments:
2933
- [ if, else, elseif, for ] # Allowed tags
30-
- [ escape, format_datetime ] # Allowed filters
34+
- [ escape, localizeddate ] # Allowed filters
3135
- # Allowed methods
3236
Surfnet\Stepup\Identity\Value\CommonName:
3337
- __toString
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2024 SURFnet bv
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
namespace Surfnet\StepupMiddleware\CommandHandlingBundle\Tests\Twig;
20+
21+
use DateTime;
22+
use PHPUnit\Framework\TestCase;
23+
use Surfnet\StepupMiddleware\CommandHandlingBundle\Twig\BackwardsCompatibleExtension;
24+
use Twig\Environment;
25+
use Twig\Extra\Intl\IntlExtension;
26+
use Twig\Loader\ArrayLoader;
27+
28+
/**
29+
* @requires extension intl
30+
*/
31+
class BackwardsCompatibleExtensionTest extends TestCase
32+
{
33+
/**
34+
* @dataProvider templateProvider
35+
*/
36+
public function testLocalizedData(string $template, string $expected, string $locale): void
37+
{
38+
$dateString = "2024-12-05 13:12:10";
39+
$date = new DateTime($dateString);
40+
$twig = new Environment(new ArrayLoader(['template' => $template]), ['debug' => true, 'cache' => false, 'autoescape' => 'html', 'optimizations' => 0]);
41+
$twig->addExtension( new BackwardsCompatibleExtension(new IntlExtension()));
42+
43+
$output = $twig->render('template', ['date' => $date, 'locale' => $locale]);
44+
$this->assertEquals($expected, $output);
45+
46+
$output = $twig->render('template', ['date' => $dateString, 'locale' => $locale]);
47+
$this->assertEquals($expected, $output);
48+
}
49+
50+
public function templateProvider(): array
51+
{
52+
return [
53+
'date en' => ["{{ date | localizeddate('full', 'none', locale) }}", 'Thursday, 5 December 2024', 'en_GB'],
54+
'date nl' => ["{{ date | localizeddate('full', 'none', locale) }}", 'donderdag 5 december 2024', 'nl_NL'],
55+
'date and time nl' => ["{{ date | localizeddate('full', 'medium', locale) }}", 'Thursday, 5 December 2024 at 13:12:10', 'en_GB'],
56+
'date and time en' => ["{{ date | localizeddate('full', 'medium', locale) }}", 'donderdag 5 december 2024 om 13:12:10', 'nl_NL'],
57+
'time nl' => ["{{ date | localizeddate('none', 'medium', locale) }}", '13:12:10', 'en_GB'],
58+
'time en' => ["{{ date | localizeddate('none', 'medium', locale) }}", '13:12:10', 'nl_NL'],
59+
];
60+
}
61+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2024 SURFnet bv
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
namespace Surfnet\StepupMiddleware\CommandHandlingBundle\Twig;
20+
21+
use DateTimeInterface;
22+
use Twig\Environment;
23+
use Twig\Extension\AbstractExtension;
24+
use Twig\Extra\Intl\IntlExtension;
25+
use Twig\TwigFilter;
26+
27+
/**
28+
* This class is introduced to handle BC twig changes in email templates used in the institution configuration.
29+
* * We need to support both versions to support two versions of the codebase to support rolling updates.
30+
* * An idea was to move the email templates to disk but that would cost too much time and we still should support
31+
* * all historical events due to the nature of event sourcing.
32+
*/
33+
class BackwardsCompatibleExtension extends AbstractExtension
34+
{
35+
private IntlExtension $intlExtension;
36+
37+
public function __construct(IntlExtension $intlExtension)
38+
{
39+
$this->intlExtension = $intlExtension;
40+
}
41+
42+
public function getFilters(): array
43+
{
44+
return [
45+
new TwigFilter('localizeddate', [$this, 'localizedDate'], ['needs_environment' => true]),
46+
];
47+
}
48+
49+
// localizeddate('full', 'none', locale)
50+
public function localizedDate(
51+
Environment $env,
52+
DateTimeInterface|string|null $date,
53+
?string $dateFormat = 'medium',
54+
?string $timeFormat = 'medium',
55+
string $locale = null
56+
): string {
57+
return $this->intlExtension->formatDateTime($env, $date, $dateFormat, $timeFormat, locale: $locale);
58+
}
59+
}

0 commit comments

Comments
 (0)