Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
10 / 10
CRAP
100.00% covered (success)
100.00%
1 / 1
Translator
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
10 / 10
14
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
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
 translateText
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 replaceText
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getLocale
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLocale
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getLocales
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasLocale
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setLocales
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 Engelsystem\Helpers\Translation;
6
7class Translator
8{
9    protected string $locale;
10
11    /** @var callable */
12    protected $getTranslatorCallback;
13
14    /** @var callable */
15    protected $localeChangeCallback;
16
17    /**
18     * Translator constructor.
19     *
20     * @param string[] $locales
21     */
22    public function __construct(
23        string $locale,
24        protected string $fallbackLocale,
25        callable $getTranslatorCallback,
26        protected array $locales = [],
27        callable $localeChangeCallback = null
28    ) {
29        $this->localeChangeCallback = $localeChangeCallback;
30        $this->getTranslatorCallback = $getTranslatorCallback;
31
32        $this->setLocale($locale);
33    }
34
35    /**
36     * Get the translation for a given key
37     */
38    public function translate(string $key, array $replace = []): string
39    {
40        return $this->translateText('gettext', [$key], $replace);
41    }
42
43    /**
44     * Get the translation for a given key
45     */
46    public function translatePlural(string $key, string $pluralKey, int $number, array $replace = []): string
47    {
48        return $this->translateText('ngettext', [$key, $pluralKey, $number], $replace);
49    }
50
51    protected function translateText(string $type, array $parameters, array $replace = []): mixed
52    {
53        $translated = $parameters[0];
54
55        foreach ([$this->locale, $this->fallbackLocale] as $lang) {
56            /** @var GettextTranslator $translator */
57            $translator = call_user_func($this->getTranslatorCallback, $lang);
58
59            try {
60                $translated = call_user_func_array([$translator, $type], $parameters);
61                break;
62            } catch (TranslationNotFound) {
63            }
64        }
65
66        return $this->replaceText($translated, $replace);
67    }
68
69    /**
70     * Replace placeholders
71     */
72    protected function replaceText(string $key, array $replace = []): mixed
73    {
74        if (empty($replace)) {
75            return $key;
76        }
77
78        return call_user_func_array('sprintf', array_merge([$key], array_values($replace)));
79    }
80
81    public function getLocale(): string
82    {
83        return $this->locale;
84    }
85
86    public function setLocale(string $locale): void
87    {
88        $this->locale = $locale;
89
90        if (is_callable($this->localeChangeCallback)) {
91            call_user_func_array($this->localeChangeCallback, [$locale]);
92        }
93    }
94
95    /**
96     * @return string[]
97     */
98    public function getLocales(): array
99    {
100        return $this->locales;
101    }
102
103    public function hasLocale(string $locale): bool
104    {
105        return isset($this->locales[$locale]);
106    }
107
108    /**
109     * @param string[] $locales
110     */
111    public function setLocales(array $locales): void
112    {
113        $this->locales = $locales;
114    }
115}