/
MantisLanguage.class.php
253 lines (222 loc) · 7.91 KB
/
MantisLanguage.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
<?php
class MantisLanguage {
/*
* Cache of localization strings in the language files
*/
static $s_lang_strings = array();
/*
* stack for language overrides
*/
static $s_lang_overrides = array();
/*
* To be used in custom_strings_inc.php :
*/
static $s_active_language = '';
/**
* Loads the specified language and stores it in $s_lang_strings, to be used by Get()
* @param string $p_lang
* @param string $p_dir
* @return null
*/
private static function Load( $p_lang, $p_dir = null ) {
self::$s_active_language = $p_lang;
if( isset( self::$s_lang_strings[$p_lang] ) && is_null( $p_dir ) ) {
return;
}
if( !lang_is_valid( $p_lang ) ) {
return;
}
// Step 1 - Load Requested Language file
// @@ and if file doesn't exist???
if( $p_dir === null ) {
include_once( config_get( 'language_path' ) . 'strings_' . $p_lang . '.txt' );
} else {
if( is_file( $p_dir . 'strings_' . $p_lang . '.txt' ) ) {
include_once( $p_dir . 'strings_' . $p_lang . '.txt' );
}
}
// Step 2 - Allow overriding strings declared in the language file.
// custom_strings_inc.php can use $g_active_language
// 2 formats:
// $s_* - old format
// $s_custom_strings array - new format
// NOTE: it's not expected that you'd mix/merge old/new formats within this file.
$t_custom_strings = config_get( 'custom_strings_file' ) ;
if( file_exists( $t_custom_strings ) ) {
# this may be loaded multiple times, once per language
require( $t_custom_strings );
}
// Step 3 - New Language file format
// Language file consists of an array
if( isset( $s_messages ) ) {
// lang strings array entry can only be set if $p_dir is not null - i.e. in a plugin
if( isset( self::$s_lang_strings[$p_lang] ) ) {
if( isset( $s_custom_messages[$p_lang] ) ) {
// Step 4 - handle merging in custom strings:
// Possible states:
// 4.a - new string format + new custom string format
self::$s_lang_strings[$p_lang] = array_replace( ((array)self::$s_lang_strings[$p_lang]), (array)$s_messages, (array)$s_custom_messages[$p_lang]);
return;
} else {
self::$s_lang_strings[$p_lang] = array_replace( ((array)self::$s_lang_strings[$p_lang]), (array)$s_messages);
}
} else {
// new language loaded
self::$s_lang_strings[$p_lang] = $s_messages;
if( isset( $s_custom_messages[$p_lang] ) ) {
// 4.a - new string format + new custom string format
self::$s_lang_strings[$p_lang] = array_replace( ((array)self::$s_lang_strings[$p_lang]), (array)$s_custom_messages[$p_lang]);
return;
}
}
}
// 4.b new string format + old custom string format
// 4.c - old string format + old custom string format
if( !isset( $s_messages ) || file_exists( $t_custom_strings ) ) {
$t_vars = get_defined_vars();
foreach( array_keys( $t_vars ) as $t_var ) {
$t_lang_var = preg_replace( '/^s_/', '', $t_var );
if( $t_lang_var != $t_var ) {
self::$s_lang_strings[$p_lang][$t_lang_var] = $$t_var;
}
else if( 'MANTIS_ERROR' == $t_var ) {
if( isset( self::$s_lang_strings[$p_lang][$t_lang_var] ) ) {
foreach( $$t_var as $key => $val ) {
self::$s_lang_strings[$p_lang][$t_lang_var][$key] = $val;
}
} else {
self::$s_lang_strings[$p_lang][$t_lang_var] = $$t_var;
}
}
}
// 4.d old string format + new custom string format
// merge new custom strings into array in same way we merge in 4.a
if( isset( $s_custom_messages[$p_lang] ) ) {
self::$s_lang_strings[$p_lang] = array_replace( ((array)self::$s_lang_strings[$p_lang]), (array)$s_custom_messages[$p_lang]);
}
}
}
/**
* Retrieves an internationalized string
* This function will return one of (in order of preference):
* 1. The string in the current user's preferred language (if defined)
* 2. The string in English
* @param string $p_string
* @param string $p_lang
* @param bool $p_error default: true - error if string not found
* @return string
*/
public static function Get( $p_string, $p_lang = null, $p_error = true ) {
# If no specific language is requested, we'll
# try to determine the language from the users
# preferences
$t_lang = $p_lang;
if( null === $t_lang ) {
$t_lang = MantisLanguage::GetCurrentLanguage();
}
// Now we'll make sure that the requested language is loaded
self::EnsureLoaded( $t_lang );
// Step 1 - see if language string exists in requested language
if( MantisLanguage::StringExists( $p_string, $t_lang ) ) {
return self::$s_lang_strings[$t_lang][$p_string];
} else {
// Language string doesn't exist in requested language
// Step 2 - See if language string exists in current plugin
$t_plugin_current = plugin_get_current();
if( !is_null( $t_plugin_current ) ) {
// Step 3 - Plugin exists: load language file
if( $t_lang != 'english' ) {
MantisLanguage::Load( $t_lang, config_get( 'plugin_path' ) . $t_plugin_current . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR );
if( MantisLanguage::StringExists( $p_string, $t_lang ) ) {
return self::$s_lang_strings[$t_lang][$p_string];
}
}
// Step 4 - Localised language entry didn't exist - fallback to english for plugin
MantisLanguage::Load( 'english', config_get( 'plugin_path' ) . $t_plugin_current . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR );
if( MantisLanguage::StringExists( $p_string, $t_lang ) ) {
return self::$s_lang_strings[$t_lang][$p_string];
}
}
// Step 5 - string didn't exist, try fall back to english:
if( $t_lang == 'english' ) {
if( $p_error ) {
throw new MantisBT\Exception\Lang_String_Not_Found( $p_string );
}
return '';
} else {
// if string is not found in a language other than english, then retry using the english language.
return self::Get( $p_string, 'english' );
}
}
}
/**
* Ensures that a language file has been loaded
* @param string $p_lang the language name
* @return null
*/
private static function EnsureLoaded( $p_lang ) {
if( !isset( self::$s_lang_strings[$p_lang] ) ) {
MantisLanguage::Load( $p_lang );
}
}
public static function ActiveLanguage( $p_lang ) {
self::$s_active_language = $p_lang;
}
/**
* language stack implementation
* push a language onto the stack
* @param string $p_lang
* @return null
*/
public static function Push( $p_lang = null ) {
# If no specific language is requested, we'll
# try to determine the language from the users
# preferences
$t_lang = $p_lang;
if( null === $t_lang ) {
$t_lang = config_get( 'default_language' );
}
# don't allow 'auto' as a language to be pushed onto the stack
# The results from auto are always the local user, not what the
# override wants, unless this is the first language setting
if(( 'auto' == $t_lang ) && ( 0 < count( $g_lang_overrides ) ) ) {
$t_lang = config_get( 'fallback_language' );
}
self::$s_lang_overrides[] = $t_lang;
# Remember the language
self::$s_active_language = $t_lang;
# make sure it's loaded
self::EnsureLoaded( $t_lang );
}
/**
* Pop a language off the stack and return it
* @return string
*/
public static function Pop() {
return array_pop( self::$s_lang_overrides );
}
/**
* Check if the language string currently exists e.g. it has been loaded. If found return true, otherwise return false.
* @param string $p_string
* @param string $p_lang
* @return bool
*/
private static function StringExists( $p_string, $p_lang ) {
return( isset( self::$s_lang_strings[$p_lang] ) && isset( self::$s_lang_strings[$p_lang][$p_string] ) );
}
/**
* return the value on top of the language stack.
* return default if stack is empty
* @return string
*/
private static function GetCurrentLanguage() {
global $g_lang_overrides;
$t_count_overrides = count( $g_lang_overrides );
if( $t_count_overrides > 0 ) {
$t_lang = $g_lang_overrides[$t_count_overrides - 1];
} else {
$t_lang = lang_get_default();
}
return $t_lang;
}
}