Translator::_loadTranslations()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 15
rs 10
cc 4
nc 5
nop 3
1
<?php
2
3
/**
4
 * Translator.php - Translator
5
 *
6
 * Provide translation service for strings in the Jaxon library.
7
 *
8
 * @package jaxon-utils
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2022 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-core
13
 */
14
15
namespace Jaxon\Utils\Translation;
16
17
use function array_keys;
18
use function array_map;
19
use function array_merge;
20
use function array_values;
21
use function explode;
22
use function file_exists;
23
use function is_array;
24
use function str_replace;
25
use function trim;
26
27
class Translator
28
{
29
    /**
30
     * The default locale
31
     *
32
     * @var string
33
     */
34
    protected $sDefaultLocale = 'en';
35
36
    /**
37
     * The translations in a flattened array
38
     *
39
     * @var array
40
     */
41
    protected $aTranslations = [];
42
43
    /**
44
     * The translations as received as input
45
     *
46
     * @var array
47
     */
48
    protected $aRawTranslations = [];
49
50
    /**
51
     * Set the default locale
52
     *
53
     * @param string $sLocale
54
     *
55
     * @return void
56
     */
57
    public function setLocale(string $sLocale)
58
    {
59
        if(($sLocale = trim($sLocale)))
60
        {
61
            $this->sDefaultLocale = $sLocale;
62
        }
63
    }
64
65
    /**
66
     * Recursively load translated strings from an array
67
     *
68
     * @param string $sLanguage The language of the translations
69
     * @param string $sPrefix The prefix for names
70
     * @param array $aTranslations The translated strings
71
     *
72
     * @return void
73
     */
74
    private function _loadTranslations(string $sLanguage, string $sPrefix, array $aTranslations)
75
    {
76
        foreach($aTranslations as $sKey => $xTranslation)
77
        {
78
            $sKey = trim($sKey);
79
            $sKey = ($sPrefix) ? $sPrefix . '.' . $sKey : $sKey;
80
            if(is_array($xTranslation))
81
            {
82
                // Recursively read the translations in the array
83
                $this->_loadTranslations($sLanguage, $sKey, $xTranslation);
84
            }
85
            else
86
            {
87
                // Save this translation
88
                $this->aTranslations[$sLanguage][$sKey] = $xTranslation;
89
            }
90
        }
91
    }
92
93
    /**
94
     * Load translated strings from a file
95
     *
96
     * @param string $sFilePath The file full path
97
     * @param string $sLanguage The language of the strings in this file
98
     *
99
     * @return bool
100
     */
101
    public function loadTranslations(string $sFilePath, string $sLanguage): bool
102
    {
103
        if(!file_exists($sFilePath))
104
        {
105
            return false;
106
        }
107
        $aTranslations = require($sFilePath);
108
        if(!is_array($aTranslations))
109
        {
110
            return false;
111
        }
112
113
        // Load the translations
114
        if(!isset($this->aTranslations[$sLanguage]))
115
        {
116
            $this->aTranslations[$sLanguage] = [];
117
        }
118
        $this->aRawTranslations[$sLanguage] =
119
            array_merge($this->aRawTranslations[$sLanguage] ?? [], $aTranslations);
120
        $this->_loadTranslations($sLanguage, '', $aTranslations);
121
        return true;
122
    }
123
124
    /**
125
     * Get a translated string
126
     *
127
     * @param string $sText The key of the translated string
128
     * @param array $aPlaceHolders The placeholders of the translated string
129
     * @param string $sLanguage The language of the translated string
130
     *
131
     * @return string
132
     */
133
    public function trans(string $sText, array $aPlaceHolders = [], string $sLanguage = ''): string
134
    {
135
        $sText = trim($sText);
136
        if(empty($sLanguage))
137
        {
138
            $sLanguage = $this->sDefaultLocale;
139
        }
140
        if(!isset($this->aTranslations[$sLanguage][$sText]))
141
        {
142
            return $sText;
143
        }
144
        $sMessage = $this->aTranslations[$sLanguage][$sText];
145
        if(!empty($aPlaceHolders))
146
        {
147
            $aVars = array_map(function($sVar) {
148
                return ':' . $sVar;
149
            }, array_keys($aPlaceHolders));
150
            $sMessage = str_replace($aVars, array_values($aPlaceHolders), $sMessage);
151
        }
152
        return $sMessage;
153
    }
154
155
    /**
156
     * Get all the translations under a given key
157
     *
158
     * @param string $sKey
159
     * @param string $sLanguage
160
     *
161
     * @return array
162
     */
163
    public function translations(string $sKey, string $sLanguage = ''): array
164
    {
165
        if(empty($sLanguage))
166
        {
167
            $sLanguage = $this->sDefaultLocale;
168
        }
169
        $aKeys = explode('.', $sKey);
170
171
        $aTranslations = $this->aRawTranslations[$sLanguage];
172
        foreach($aKeys as $sKey)
173
        {
174
            if($sKey !== '')
175
            {
176
                $aTranslations = $aTranslations[$sKey] ?? [];
177
            }
178
        }
179
        return $aTranslations;
180
    }
181
}
182