Skip to content

Commit af03f78

Browse files
committedDec 2, 2011
Improve admin checks for language strings
This brings the following improvements to test_lang.php: - Simplify the code by defining a new checkplugins() function for plugins language checks, allowing to use a revised checklangdir() for both the main and the plugin language strings (removes the recursive call) - Use PHP scandir() function to retrieve a sorted array of files instead of manually building it using opendir() and a loop on readdir() - Process the languages in alphabetical order - Array having strings as keys are valid tokens. Fixes #13643 This avoids reporting errors is useful for plugin error strings like $MANTIS_ERROR['plugin_example_error1'] = 'Error message'; - Better formatting of error messages - Whitespace and coding guidelines fixes NOTE: This commit has been ported to master for consistency, although the new format of the strings_english.txt file is not compatible with the logic in test_lang.php.
1 parent 453e7d8 commit af03f78

File tree

1 file changed

+90
-77
lines changed

1 file changed

+90
-77
lines changed
 

Diff for: ‎admin/test_langs.php

+90-77
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323

2424
define( 'PLUGINS_DISABLED', true );
2525
define( 'LANG_LOAD_DISABLED', true );
26+
define( 'STRINGS_ENGLISH', 'strings_english.txt' );
27+
$t_mantis_dir = dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR;
2628

2729
/**
2830
* MantisBT Core API's
2931
*/
30-
require_once( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'core.php' );
32+
require_once( $t_mantis_dir . 'core.php' );
3133

3234
access_ensure_global_level( config_get_global( 'admin_site_threshold' ) );
3335

@@ -42,8 +44,8 @@
4244
define( 'T_DOC_COMMENT', T_ML_COMMENT );
4345
}
4446

45-
if (!checkfile( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR, 'strings_english.txt', true)) {
46-
print_error( "FAILED: Language file 'strings_english.txt' failed." );
47+
if(!checkfile( $t_mantis_dir . 'lang' . DIRECTORY_SEPARATOR, STRINGS_ENGLISH, true)) {
48+
print_error( "Language file '" . STRINGS_ENGLISH . "' failed.", 'FAILED' );
4749
die;
4850
}
4951

@@ -54,21 +56,8 @@
5456
html_page_top();
5557

5658
// check core language files
57-
if( function_exists( 'opendir' ) && function_exists( 'readdir' ) ) {
58-
$t_lang_files = Array();
59-
if( $t_handle = opendir( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'lang' ) ) {
60-
while( false !== ( $t_file = readdir( $t_handle ) ) ) {
61-
if ($t_file == 'strings_english.txt' ) {
62-
echo "Testing english language file '$t_file' (phase 1)...<br />";
63-
flush();
64-
checkfile( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR, $t_file );
65-
}
66-
if( $t_file[0] != '.' && $t_file != 'langreadme.txt' && !is_dir( $t_file ) ) {
67-
$t_lang_files[] = $t_file;
68-
}
69-
}
70-
closedir( $t_handle );
71-
}
59+
if( function_exists( 'scandir' ) ) {
60+
checklangdir( $t_mantis_dir );
7261
}
7362
else {
7463
$t_lang_files = Array();
@@ -78,55 +67,70 @@
7867
}
7968
$t_lang_files[] = $t_lang;
8069
}
70+
asort( $t_lang_files );
71+
checklangdir( $t_mantis_dir, $t_lang_files );
8172
}
8273

83-
if( count( $t_lang_files ) > 0 ) {
84-
echo 'Retrieved ', count( $t_lang_files ), ' languages<br />';
85-
86-
foreach( $t_lang_files as $t_file ) {
87-
echo "Testing language file '$t_file' (phase 1)...<br />";
88-
flush();
89-
90-
checkfile( dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR, $t_file );
91-
}
92-
}
9374

9475
// attempt to find plugin language files
95-
echo "Trying to find+check plugin language files...<br />";
96-
if( function_exists( 'opendir' ) && function_exists( 'readdir' ) ) {
97-
checklangdir ( config_get( 'plugin_path' ) );
76+
echo "<br />Trying to find+check plugin language files...<br />";
77+
if( function_exists( 'scandir' ) ) {
78+
checkplugins( config_get( 'plugin_path' ) );
9879
} else {
99-
echo 'php opendir/readdir are disabled - skipping<br />';
80+
echo 'php scandir is disabled - skipping<br />';
10081
}
10182

102-
function checklangdir( $p_path, $p_subpath = '' ) {
103-
$p_path = $p_path . DIRECTORY_SEPARATOR . $p_subpath . DIRECTORY_SEPARATOR;
104-
if( $handle = opendir( $p_path ) ) {
105-
while( false !== ( $file = readdir( $handle ) ) ) {
106-
if ( $file[0] == '.' )
107-
continue;
108-
if ( $p_subpath == '' ) {
109-
echo "Checking language files for plugin $file:<br />";
83+
function checkplugins( $p_path ) {
84+
$t_path = rtrim( $p_path, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR;
11085

111-
if (file_exists( $p_path . DIRECTORY_SEPARATOR . $p_subpath . DIRECTORY_SEPARATOR . $file . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . 'strings_english.txt' ) ) {
112-
echo "Testing english language for plugin '$file' (phase 1)...<br />";
113-
flush();
114-
checkfile( $p_path . DIRECTORY_SEPARATOR . $p_subpath . DIRECTORY_SEPARATOR . $file . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR, 'strings_english.txt' );
115-
}
86+
$t_plugins = @scandir( $t_path );
87+
if( false == $t_plugins ) {
88+
print_error( "plugin path $t_path not found or not accessible" );
89+
}
90+
else {
91+
foreach( $t_plugins as $t_plugin ) {
92+
if( $t_plugin[0] == '.' ) {
93+
continue;
11694
}
95+
echo "<br />Checking language files for plugin $t_plugin:<br />";
96+
checklangdir( $t_path . $t_plugin );
97+
}
98+
}
99+
}
117100

118-
if( !is_dir( $p_path . DIRECTORY_SEPARATOR . $file ) && $p_subpath == 'lang' ) {
119-
checkfile( $p_path, $file );
120-
} else {
121-
if ( is_dir( $p_path . DIRECTORY_SEPARATOR . $file ) )
122-
checklangdir( $p_path, $file);
101+
function checklangdir( $p_path, $p_lang_files = null ) {
102+
$t_path = rtrim( $p_path, DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR;
103+
104+
if( is_array( $p_lang_files ) ) {
105+
$t_lang_files = $p_lang_files;
106+
}
107+
else {
108+
$t_lang_files = @scandir( $t_path );
109+
}
110+
if( false == $t_lang_files ) {
111+
print_error( "language dir $t_path not found or not accessible" );
112+
}
113+
else {
114+
if( in_array( STRINGS_ENGLISH, $t_lang_files ) ) {
115+
echo "Testing English language file...<br />";
116+
flush();
117+
checkfile( $t_path, STRINGS_ENGLISH );
118+
}
119+
// Skipping english language, readme and hidden files
120+
foreach( $t_lang_files as $key => $t_lang ) {
121+
if( $t_lang[0] == '.' || $t_lang == 'langreadme.txt' || $t_lang == STRINGS_ENGLISH ) {
122+
unset( $t_lang_files[$key] );
123+
}
124+
}
125+
if( !empty($t_lang_files ) ) {
126+
echo 'Retrieved ', count( $t_lang_files ), ' languages<br />';
127+
foreach( $t_lang_files as $t_lang ) {
128+
checkfile( $t_path, $t_lang );
123129
}
124130
}
125-
closedir( $handle );
126131
}
127132
}
128133

129-
130134
function checkfile( $p_path, $p_file, $p_quiet = false ) {
131135
if( !$p_quiet) {
132136
echo "Testing language file '$p_file' (phase 1)...<br />";
@@ -136,11 +140,11 @@ function checkfile( $p_path, $p_file, $p_quiet = false ) {
136140
$file = $p_path . $p_file;
137141

138142
set_error_handler( 'lang_error_handler' );
139-
$result = checktoken( $file, ($p_file == 'strings_english.txt' ? true : false) );
143+
$result = checktoken( $file, ($p_file == STRINGS_ENGLISH ) );
140144
restore_error_handler();
141145

142146
if( !$result ) {
143-
print_error( "FAILED: Language file '$p_file' failed at phase 1." );
147+
print_error( "Language file '$p_file' failed at phase 1.", 'FAILED' );
144148
if( $p_quiet ) {
145149
return false;
146150
}
@@ -161,14 +165,14 @@ function checkfile( $p_path, $p_file, $p_quiet = false ) {
161165
restore_error_handler();
162166

163167
if( $result === false ) {
164-
print_error( "FAILED: Language file '$p_file' failed at eval" );
168+
print_error( "Language file '$p_file' failed at eval", 'FAILED' );
165169
if( $p_quiet ) {
166170
return false;
167171
}
168172
}
169173

170174
if( !empty( $data ) ) {
171-
print_error( "FAILED: Language file '$p_file' failed at require_once (data output: " . var_export( $data, true ) . ")" );
175+
print_error( "Language file '$p_file' failed at require_once (data output: " . var_export( $data, true ) . ")", 'FAILED' );
172176
if( $p_quiet ) {
173177
return false;
174178
}
@@ -200,7 +204,7 @@ function checktoken( $file, $base = false ) {
200204
switch( $token ) {
201205
case '=':
202206
if( $last_token != T_VARIABLE ) {
203-
print_error( "ERROR: = sign without variable" );
207+
print_error( "'=' sign without variable (line $line)" );
204208
$pass = false;
205209
}
206210
$set_variable = true;
@@ -216,10 +220,11 @@ function checktoken( $file, $base = false ) {
216220
$pass = false;
217221
}
218222
$expectendarr = false;
223+
$variablearr = false;
219224
break;
220225
case ';':
221226
if( !$need_end_variable ) {
222-
print_error( "ERROR: function seperator found at unexpected location (line $line)" );
227+
print_error( "function seperator found at unexpected location (line $line)" );
223228
$pass = false;
224229
}
225230
$need_end_variable = false;
@@ -228,12 +233,12 @@ function checktoken( $file, $base = false ) {
228233
if( $last_token == T_CONSTANT_ENCAPSED_STRING ) {
229234
$twopartstring = true;
230235
} else {
231-
print_error( "ERROR: string concat found at unexpected location (line $line)" );
236+
print_error( "string concat found at unexpected location (line $line)" );
232237
$pass = false;
233238
}
234239
break;
235240
default:
236-
print_error( "UNKNOWN TOKEN" . $token );
241+
print_error( "unknown token $token" );
237242
$pass = false;
238243
break;
239244
}
@@ -255,7 +260,7 @@ function checktoken( $file, $base = false ) {
255260
continue;
256261
}
257262

258-
print_error( "ERROR" . $id . token_name( $id ) . $text . $line );
263+
print_error( "token# $id: " . token_name( $id ) . " = $text (line $line)" );
259264
$pass = false;
260265
}
261266

@@ -267,7 +272,7 @@ function checktoken( $file, $base = false ) {
267272
$in_php_code = false;
268273
break;
269274
case T_INLINE_HTML:
270-
print_error( "ERROR: Whitespace in language file outside of PHP code block (line $line)" );
275+
print_error( "Whitespace in language file outside of PHP code block (line $line)" );
271276
$pass = false;
272277
break;
273278
case T_VARIABLE:
@@ -283,48 +288,55 @@ function checktoken( $file, $base = false ) {
283288
if( $variablearr ) {
284289
$current_var .= $text;
285290
if( !defined( $text ) ) {
286-
print_error( "undefined constant: $current_var" );
291+
print_error( "undefined constant: $text (line $line)" );
287292
}
288293
} else {
289-
print_error( "ERROR: T_STRING found at unexpected location (line $line)" );
294+
print_error( "T_STRING found at unexpected location (line $line)" );
290295
$pass = false;
291296
}
292-
if ( strpos($current_var,"\n") !== false ) {
293-
print_error( "PARSER - NEW LINE IN STRING: " . $id . token_name( $id ) . $text . $line );
297+
if( strpos( $current_var, "\n" ) !== false ) {
298+
print_error( "NEW LINE in string: $id " . token_name( $id ) . " = $text (line $line)", 'PARSER' );
294299
$pass = false;
295300
$fatal = true;
296301
}
297302
$last_token2 = T_VARIABLE;
298303
$expectendarr = true;
299304
break;
300305
case T_CONSTANT_ENCAPSED_STRING:
301-
if ( $token[1][0] != '\'' ) {
302-
print_error( "ERROR: Language strings should be single-quoted (line $line)" );
306+
if( $token[1][0] != '\'' ) {
307+
print_error( "Language strings should be single-quoted (line $line)" );
303308
}
309+
if( $variablearr ) {
310+
$current_var .= $text;
311+
$last_token2 = T_VARIABLE;
312+
$expectendarr = true;
313+
break;
314+
}
315+
304316
if( $last_token == T_VARIABLE && $set_variable && $current_var != null ) {
305317
if( isset( $variables[$current_var] ) ) {
306-
print_error( "ERROR: duplicate language string ($current_var ) (line $line)" );
318+
print_error( "duplicate language string ($current_var ) (line $line)" );
307319
} else {
308320
$variables[$current_var] = $text;
309321
}
310322

311-
if ( $base ) {
323+
if( $base ) {
312324
// english
313325
//if( isset( $basevariables[$current_var] ) ) {
314326
// print_error( "WARN: english string redefined - plugin? $current_var" );
315327
//}
316328
$basevariables[$current_var] = true;
317329
} else {
318330
if( !isset( $basevariables[$current_var] ) ) {
319-
print_error( "WARN: String defined in non-english file that does not exist ( $current_var )" );
331+
print_error( "'$current_var' is not defined in the English language file", 'WARNING' );
320332
//} else {
321333
// missing translation
322334
}
323335
}
324336

325337
}
326-
if ( strpos($current_var,"\n") !== false ) {
327-
print_error( "PARSER - NEW LINE IN STRING: " . $id . token_name( $id ) . $text . $line );
338+
if( strpos( $current_var, "\n" ) !== false ) {
339+
print_error( "NEW LINE in string: $id " . token_name( $id ) . " = $text (line $line)", 'PARSER' );
328340
$pass = false;
329341
$fatal = true;
330342
}
@@ -333,7 +345,7 @@ function checktoken( $file, $base = false ) {
333345
break;
334346
default:
335347
// if (!$in_php_code)
336-
print_error( "PARSER: " . $id . token_name( $id ) . $text . $line );
348+
print_error( "$id " . token_name( $id ) . " = $text (line $line)", 'PARSER' );
337349
$pass = false;
338350
break;
339351
}
@@ -344,8 +356,9 @@ function checktoken( $file, $base = false ) {
344356
}
345357
}
346358

347-
if ($fatal)
359+
if( $fatal ) {
348360
break;
361+
}
349362
}
350363

351364
return $pass;
@@ -355,8 +368,8 @@ function lang_error_handler( $p_type, $p_error, $p_file, $p_line, $p_context ) {
355368
print_error( "error handler thrown: " . $p_type . '<br />' . $p_error . '<br />' . $p_file . '<br />' . $p_line . '<br />' . $p_context );
356369
}
357370

358-
function print_error( $p_string ) {
359-
echo '<p class="error-msg">ERROR: ', $p_string, '</p>';
371+
function print_error( $p_string, $p_type = 'ERROR' ) {
372+
echo '<p class="error-msg">', "$p_type: $p_string", '</p>';
360373
}
361374

362375
html_page_bottom();

0 commit comments

Comments
 (0)
Please sign in to comment.