• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tarlepp / symfony-flex-backend / #5591

07 Feb 2025 11:34PM UTC coverage: 99.913% (-0.09%) from 100.0%
#5591

Pull #2932

php-coveralls

web-flow
Merge a8d42cc07 into 6b73943f5
Pull Request #2932: Feat - Added support to get request locale

0 of 2 new or added lines in 1 file covered. (0.0%)

2297 of 2299 relevant lines covered (99.91%)

92.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.33
/src/Service/Localization.php
1
<?php
2
declare(strict_types = 1);
3
/**
4
 * /src/Service/Localization.php
5
 *
6
 * @author TLe, Tarmo Leppänen <tarmo.leppanen@pinja.com>
7
 */
8

9
namespace App\Service;
10

11
use App\Enum\Language;
12
use App\Enum\Locale;
13
use Closure;
14
use DateTimeImmutable;
15
use DateTimeZone;
16
use Psr\Log\LoggerInterface;
17
use Symfony\Component\HttpFoundation\RequestStack;
18
use Symfony\Contracts\Cache\CacheInterface;
19
use Symfony\Contracts\Cache\ItemInterface;
20
use Throwable;
21
use function explode;
22
use function floor;
23
use function in_array;
24
use function str_replace;
25

26
/**
27
 * @package App\Service
28
 * @author TLe, Tarmo Leppänen <tarmo.leppanen@pinja.com>
29
 */
30
readonly class Localization
31
{
32
    final public const string DEFAULT_TIMEZONE = 'Europe/Helsinki';
33

34
    public function __construct(
35
        private CacheInterface $appCacheApcu,
36
        private LoggerInterface $logger,
37
        private RequestStack $requestStack,
38
    ) {
39
    }
53✔
40

41
    /**
42
     * @return array<int, string>
43
     */
44
    public function getLanguages(): array
45
    {
46
        return Language::getValues();
3✔
47
    }
48

49
    /**
50
     * @return array<int, string>
51
     */
52
    public function getLocales(): array
53
    {
54
        return Locale::getValues();
3✔
55
    }
56

57
    public function getRequestLocale(): string
58
    {
NEW
59
        $locale = $this->requestStack->getCurrentRequest()?->getLocale() ?? Locale::getDefault()->value;
×
60

NEW
61
        return in_array($locale, $this->getLocales(), true) ? $locale : Locale::getDefault()->value;
×
62
    }
63

64
    /**
65
     * @return array<int, array{timezone: string, identifier: string,  offset: string, value: string}>
66
     */
67
    public function getTimezones(): array
68
    {
69
        $output = [];
47✔
70

71
        try {
72
            /** @var array<int, array{timezone: string, identifier: string, offset: string, value: string}> $output */
73
            $output = $this->appCacheApcu->get('application_timezone', $this->getClosure());
47✔
74
        } catch (Throwable $exception) {
1✔
75
            $this->logger->error($exception->getMessage(), $exception->getTrace());
1✔
76
        }
77

78
        return $output;
47✔
79
    }
80

81
    /**
82
     * @throws Throwable
83
     *
84
     * @return array<int, array{timezone: string, identifier: non-empty-string,  offset: string, value: string}>
85
     */
86
    public function getFormattedTimezones(): array
87
    {
88
        $output = [];
46✔
89

90
        /** @var array<int, non-empty-string> $identifiers */
91
        $identifiers = DateTimeZone::listIdentifiers();
46✔
92

93
        foreach ($identifiers as $identifier) {
46✔
94
            $dateTimeZone = new DateTimeZone($identifier);
46✔
95

96
            $dateTime = new DateTimeImmutable(timezone: $dateTimeZone);
46✔
97

98
            $hours = floor($dateTimeZone->getOffset($dateTime) / 3600);
46✔
99
            $minutes = floor(($dateTimeZone->getOffset($dateTime) - ($hours * 3600)) / 60);
46✔
100

101
            $hours = 'GMT' . ($hours < 0 ? $hours : '+' . $hours);
46✔
102
            $minutes = ($minutes > 0 ? $minutes : '0' . $minutes);
46✔
103

104
            $output[] = [
46✔
105
                'timezone' => explode('/', $identifier)[0],
46✔
106
                'identifier' => $identifier,
46✔
107
                'offset' => $hours . ':' . $minutes,
46✔
108
                'value' => str_replace('_', ' ', $identifier),
46✔
109
            ];
46✔
110
        }
111

112
        return $output;
46✔
113
    }
114

115
    private function getClosure(): Closure
116
    {
117
        return function (ItemInterface $item): array {
47✔
118
            // One year
119
            $item->expiresAfter(31_536_000);
46✔
120

121
            return $this->getFormattedTimezones();
46✔
122
        };
47✔
123
    }
124
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc