Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
9 / 9
CRAP
100.00% covered (success)
100.00%
1 / 1
Verba
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
9 / 9
11
100.00% covered (success)
100.00%
1 / 1
 activate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 deactivate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 translator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 translate
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 translatePlural
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 translateDomain
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 translateDomainPlural
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 args
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 current
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Celemas\Verba;
6
7/**
8 * Process-wide holder and facade for the active translator.
9 *
10 * The global `__`, `__n`, `__d`, and `__dn` functions delegate here. With no
11 * translator active, lookups return the message id (with interpolation), which
12 * keeps translation calls safe in tests, CLI, and early boot.
13 *
14 * @api
15 */
16final class Verba
17{
18    private static ?Translator $translator = null;
19
20    private static ?Translator $fallback = null;
21
22    public static function activate(Translator $translator): void
23    {
24        self::$translator = $translator;
25    }
26
27    public static function deactivate(): void
28    {
29        self::$translator = null;
30    }
31
32    public static function translator(): ?Translator
33    {
34        return self::$translator;
35    }
36
37    /**
38     * @param array<array-key, string|int|float> $args
39     */
40    public static function translate(string $id, array $args = []): string
41    {
42        return self::current()->translate($id, $args);
43    }
44
45    /**
46     * @param array<array-key, string|int|float> $args
47     */
48    public static function translatePlural(string $one, string $many, int $n, array $args = []): string
49    {
50        return self::current()->translatePlural($one, $many, $n, $args);
51    }
52
53    /**
54     * @param array<array-key, string|int|float> $args
55     */
56    public static function translateDomain(string $domain, string $id, array $args = []): string
57    {
58        return self::current()->translateDomain($domain, $id, $args);
59    }
60
61    /**
62     * @param array<array-key, string|int|float> $args
63     */
64    public static function translateDomainPlural(
65        string $domain,
66        string $one,
67        string $many,
68        int $n,
69        array $args = [],
70    ): string {
71        return self::current()->translateDomainPlural($domain, $one, $many, $n, $args);
72    }
73
74    /**
75     * Normalizes variadic message arguments into a single args array. A lone
76     * array argument is a named-placeholder map; anything else is a positional
77     * (sprintf) list.
78     *
79     * @param array<array-key, string|int|float|array<array-key, string|int|float>> $args
80     * @return array<array-key, string|int|float>
81     */
82    public static function args(array $args): array
83    {
84        if (count($args) === 1) {
85            $first = reset($args);
86
87            if (is_array($first)) {
88                return $first;
89            }
90        }
91
92        /** @var array<array-key, string|int|float> $args */
93        return $args;
94    }
95
96    private static function current(): Translator
97    {
98        return self::$translator ?? (self::$fallback ??= new Translator('en', []));
99    }
100}