Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
13 / 13
CRAP
100.00% covered (success)
100.00%
1 / 1
Verba
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
13 / 13
15
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
 translateContext
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
 translateContextPlural
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
 translateDomainContext
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
 translateDomainContextPlural
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 Celema\Verba;
6
7/**
8 * Process-wide holder and facade for the active translator.
9 *
10 * The eight global translation functions delegate here. With no translator
11 * 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 translateContext(string $context, string $id, array $args = []): string
49    {
50        return self::current()->translateContext($context, $id, $args);
51    }
52
53    /**
54     * @param array<array-key, string|int|float> $args
55     */
56    public static function translatePlural(string $one, string $many, int $n, array $args = []): string
57    {
58        return self::current()->translatePlural($one, $many, $n, $args);
59    }
60
61    /**
62     * @param array<array-key, string|int|float> $args
63     */
64    public static function translateContextPlural(
65        string $context,
66        string $one,
67        string $many,
68        int $n,
69        array $args = [],
70    ): string {
71        return self::current()->translateContextPlural($context, $one, $many, $n, $args);
72    }
73
74    /**
75     * @param array<array-key, string|int|float> $args
76     */
77    public static function translateDomain(string $domain, string $id, array $args = []): string
78    {
79        return self::current()->translateDomain($domain, $id, $args);
80    }
81
82    /**
83     * @param array<array-key, string|int|float> $args
84     */
85    public static function translateDomainContext(
86        string $domain,
87        string $context,
88        string $id,
89        array $args = [],
90    ): string {
91        return self::current()->translateDomainContext($domain, $context, $id, $args);
92    }
93
94    /**
95     * @param array<array-key, string|int|float> $args
96     */
97    public static function translateDomainPlural(
98        string $domain,
99        string $one,
100        string $many,
101        int $n,
102        array $args = [],
103    ): string {
104        return self::current()->translateDomainPlural($domain, $one, $many, $n, $args);
105    }
106
107    /**
108     * @param array<array-key, string|int|float> $args
109     */
110    // @mago-expect lint:excessive-parameter-list The API mirrors the translator method.
111    public static function translateDomainContextPlural(
112        string $domain,
113        string $context,
114        string $one,
115        string $many,
116        int $n,
117        array $args = [],
118    ): string {
119        return self::current()->translateDomainContextPlural($domain, $context, $one, $many, $n, $args);
120    }
121
122    /**
123     * Normalizes variadic message arguments into a single args array. A lone
124     * array argument is a named-placeholder map; anything else is a positional
125     * (sprintf) list.
126     *
127     * @param array<array-key, string|int|float|array<array-key, string|int|float>> $args
128     * @return array<array-key, string|int|float>
129     */
130    public static function args(array $args): array
131    {
132        if (count($args) === 1) {
133            $first = reset($args);
134
135            if (is_array($first)) {
136                return $first;
137            }
138        }
139
140        /** @var array<array-key, string|int|float> $args */
141        return $args;
142    }
143
144    private static function current(): Translator
145    {
146        return self::$translator ?? (self::$fallback ??= new Translator('en', []));
147    }
148}