Skip to content

Commit 78ed4e1

Browse files
committed
i18n-tools: Respect the coding standards when adding textdomains with add-textdomain.php.
Props GaryJ, groovecoder. Fixes #21616. git-svn-id: https://develop.svn.wordpress.org/trunk@36603 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 2ba684e commit 78ed4e1

4 files changed

Lines changed: 106 additions & 44 deletions

File tree

tools/i18n/add-textdomain.php

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,40 +17,78 @@ class AddTextdomain {
1717
/**
1818
* Constructor.
1919
*/
20-
function __construct() {
20+
public function __construct() {
2121
$makepot = new MakePOT;
2222
$this->funcs = array_keys( $makepot->rules );
2323
$this->funcs[] = 'translate_nooped_plural';
2424
}
2525

26-
function usage() {
26+
/**
27+
* Prints CLI usage.
28+
*/
29+
public function usage() {
2730
$usage = "Usage: php add-textdomain.php [-i] <domain> <file>\n\nAdds the string <domain> as a last argument to all i18n function calls in <file>\nand prints the modified php file on standard output.\n\nOptions:\n -i Modifies the PHP file in place, instead of printing it to standard output.\n";
2831
fwrite(STDERR, $usage);
2932
exit(1);
3033
}
3134

32-
function process_token($token_text, $inplace) {
33-
if ($inplace)
34-
$this->modified_contents .= $token_text;
35-
else
36-
echo $token_text;
35+
/**
36+
* Adds textdomain to a single file.
37+
*
38+
* @see AddTextdomain::process_string()
39+
*
40+
* @param string $domain Text domain.
41+
* @param string $source_filename Filename with optional path.
42+
* @param bool $inplace True to modifies the PHP file in place. False to print to standard output.
43+
*/
44+
public function process_file( $domain, $source_filename, $inplace ) {
45+
$new_source = $this->process_string( $domain, file_get_contents( $source_filename ) );
46+
47+
if ( $inplace ) {
48+
$f = fopen( $source_filename, 'w' );
49+
fwrite( $f, $new_source );
50+
fclose( $f );
51+
} else {
52+
echo $new_source;
53+
}
3754
}
3855

56+
/**
57+
* Adds textdomain to a string of PHP.
58+
*
59+
* Functions calls should be wrapped in opening and closing PHP delimiters as usual.
60+
*
61+
* @see AddTextdomain::process_tokens()
62+
*
63+
* @param string $domain Text domain.
64+
* @param string $string PHP code to parse.
65+
* @return string Modified source.
66+
*/
67+
public function process_string( $domain, $string ) {
68+
$tokens = token_get_all( $string );
69+
return $this->process_tokens( $domain, $tokens );
70+
}
3971

40-
function process_file($domain, $source_filename, $inplace) {
41-
72+
/**
73+
* Adds textdomain to a set of PHP tokens.
74+
*
75+
* @param string $domain Text domain.
76+
* @param array $tokens PHP tokens. An array of token identifiers. Each individual token identifier is either a
77+
* single character (i.e.: ;, ., >, !, etc.), or a three element array containing the token
78+
* index in element 0, the string content of the original token in element 1 and the line
79+
* number in element 2.
80+
* @return string Modified source.
81+
*/
82+
public function process_tokens( $domain, $tokens ) {
4283
$this->modified_contents = '';
43-
$domain = addslashes($domain);
44-
45-
$source = file_get_contents($source_filename);
46-
$tokens = token_get_all($source);
84+
$domain = addslashes( $domain );
4785

4886
$in_func = false;
4987
$args_started = false;
5088
$parens_balance = 0;
5189
$found_domain = false;
5290

53-
foreach($tokens as $token) {
91+
foreach($tokens as $index => $token) {
5492
$string_success = false;
5593
if (is_array($token)) {
5694
list($id, $text) = $token;
@@ -71,26 +109,28 @@ function process_file($domain, $source_filename, $inplace) {
71109
} elseif (')' == $token) {
72110
--$parens_balance;
73111
if ($in_func && 0 == $parens_balance) {
74-
$token = $found_domain? ')' : ", '$domain')";
112+
if ( ! $found_domain ) {
113+
$token = ", '$domain'";
114+
if ( T_WHITESPACE == $tokens[ $index - 1 ][0] ) {
115+
$token .= ' '; // Maintain code standards if previously present
116+
// Remove previous whitespace token to account for it.
117+
$this->modified_contents = trim( $this->modified_contents );
118+
}
119+
$token .= ')';
120+
}
75121
$in_func = false;
76122
$args_started = false;
77123
$found_domain = false;
78124
}
79125
}
80-
$this->process_token($token, $inplace);
126+
$this->modified_contents .= $token;
81127
}
82128

83-
if ($inplace) {
84-
$f = fopen($source_filename, 'w');
85-
fwrite($f, $this->modified_contents);
86-
fclose($f);
87-
}
129+
return $this->modified_contents;
88130
}
89131
}
90132

91-
92-
// run the CLI only if the file
93-
// wasn't included
133+
// Run the CLI only if the file wasn't included.
94134
$included_files = get_included_files();
95135
if ($included_files[0] == __FILE__) {
96136
$adddomain = new AddTextdomain();

tools/i18n/t/AddTextdomainTest.php

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,37 @@
1010

1111
class AddTextDomainTest extends PHPUnit_Framework_TestCase {
1212

13-
function __construct() {
14-
$this->atd = new AddTextdomain;
13+
function setUp() {
14+
parent::setUp();
15+
$this->atd = new AddTextdomain();
1516
}
1617

1718
function test_add() {
18-
# copy to a new file, so that we don't corrupt the old one
19+
// Copy to a new file, so that we don't corrupt the old one.
1920
copy( 'data/add-textdomain-0.php', 'data/add-textdomain-0-work.php' );
2021
$this->atd->process_file( 'test-domain', 'data/add-textdomain-0-work.php', true );
2122
$this->assertEquals( file_get_contents( 'data/add-textdomain-0-result.php' ), file_get_contents( 'data/add-textdomain-0-work.php' ) );
2223
unlink( 'data/add-textdomain-0-work.php' );
2324
}
25+
26+
/**
27+
* @dataProvider data_textdomain_sources
28+
*/
29+
function test_basic_add_textdomain( $source, $expected ) {
30+
$tokens = token_get_all( $source );
31+
$result = $this->atd->process_tokens( 'foo', $tokens );
32+
$this->assertEquals( $expected, $result );
33+
}
34+
35+
function data_textdomain_sources() {
36+
return array(
37+
array( "<?php __('string'); ?>", "<?php __('string', 'foo'); ?>" ), // Simple single quotes
38+
array( '<?php __("string"); ?>', "<?php __(\"string\", 'foo'); ?>" ), // Simple double quotes
39+
array( "<?php __( 'string' ); ?>", "<?php __( 'string', 'foo' ); ?>" ), // Simple single quotes CS
40+
array( '<?php __( "string" ); ?>', "<?php __( \"string\", 'foo' ); ?>" ), // Simple double quotes CS
41+
array( "<?php __( 'string', 'string2' ); ?>", "<?php __( 'string', 'string2', 'foo' ); ?>" ), // Multiple string args
42+
array( '<?php __( \'string\', $var ); ?>', '<?php __( \'string\', $var, \'foo\' ); ?>' ), // Multiple string / var args
43+
array( "<?php __( 'string', 'foo' ); ?>", "<?php __( 'string', 'foo' ); ?>" ), // Existing textdomain
44+
);
45+
}
2446
}
Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
<?php
22
function call_some_i18n_methods() {
3-
__( 'Hello World' , 'test-domain');
4-
_e( 'Hello World' , 'test-domain');
5-
_n( 'Single', 'Plural', 1 , 'test-domain');
6-
_n_noop( 'Single Noop', 'Plural Noop', 1 , 'test-domain');
7-
_x( 'Hello World', 'Testing' , 'test-domain');
8-
_ex( 'Hello World', 'Testing' , 'test-domain');
9-
_nx( 'Hello World', 'Testing' , 'test-domain');
10-
_nx_noop( 'Hello World Noop', 'Testing' , 'test-domain');
11-
esc_attr__( 'Attribute' , 'test-domain');
12-
esc_html__( 'HTML' , 'test-domain');
13-
esc_attr_e( 'Attribute' , 'test-domain');
14-
esc_html_e( 'HTML' , 'test-domain');
15-
esc_attr_x( 'Attribute', 'Testing' , 'test-domain');
16-
esc_html_x( 'HTML', 'Testing' , 'test-domain');
17-
translate_nooped_plural( 'Plural Noop', 2 , 'test-domain');
18-
}
3+
__( 'Hello World', 'test-domain' );
4+
_e( 'Hello World', 'test-domain' );
5+
_n( 'Single', 'Plural', 1, 'test-domain' );
6+
_n_noop( 'Single Noop', 'Plural Noop', 1, 'test-domain' );
7+
_x( 'Hello World', 'Testing', 'test-domain' );
8+
_ex( 'Hello World', 'Testing', 'test-domain' );
9+
_nx( 'Hello World', 'Testing', 'test-domain' );
10+
_nx_noop( 'Hello World Noop', 'Testing', 'test-domain' );
11+
esc_attr__( 'Attribute', 'test-domain' );
12+
esc_html__( 'HTML', 'test-domain' );
13+
esc_attr_e( 'Attribute', 'test-domain' );
14+
esc_html_e( 'HTML', 'test-domain' );
15+
esc_attr_x( 'Attribute', 'Testing', 'test-domain' );
16+
esc_html_x( 'HTML', 'Testing', 'test-domain' );
17+
translate_nooped_plural( 'Plural Noop', 2, 'test-domain' );
18+
}

tools/i18n/t/data/add-textdomain-0.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ function call_some_i18n_methods() {
1515
esc_attr_x( 'Attribute', 'Testing' );
1616
esc_html_x( 'HTML', 'Testing' );
1717
translate_nooped_plural( 'Plural Noop', 2 );
18-
}
18+
}

0 commit comments

Comments
 (0)