Version Description
= v160416 =
Requires WordPress v4.2+.
Download this release
Release Info
Developer | raamdev |
Plugin | Comet Cache |
Version | 160417 |
Comparing to | |
See all releases |
Code changes from version 160416 to 160417
- comet-cache.php +1 -1
- readme.txt +5 -1
- src/includes/classes/FeedUtils.php +3 -1
- src/includes/stub.php +1 -1
- src/vendor/autoload.php +1 -1
- src/vendor/composer/autoload_real.php +3 -3
- src/vendor/websharks/wp-i18n-tools/CHANGELOG.md +0 -3
- src/vendor/websharks/wp-i18n-tools/README.md +0 -14
- src/vendor/websharks/wp-i18n-tools/add-textdomain.php +0 -110
- src/vendor/websharks/wp-i18n-tools/cron-svn-pots.php +0 -117
- src/vendor/websharks/wp-i18n-tools/extract/ExtractTest.php +0 -160
- src/vendor/websharks/wp-i18n-tools/extract/TODO +0 -1
- src/vendor/websharks/wp-i18n-tools/extract/extract.php +0 -209
- src/vendor/websharks/wp-i18n-tools/importers-i18n.php +0 -195
- src/vendor/websharks/wp-i18n-tools/makepot.php +0 -570
- src/vendor/websharks/wp-i18n-tools/not-gettexted.php +0 -234
- src/vendor/websharks/wp-i18n-tools/pomo/entry.php +0 -78
- src/vendor/websharks/wp-i18n-tools/pomo/mo.php +0 -258
- src/vendor/websharks/wp-i18n-tools/pomo/po.php +0 -385
- src/vendor/websharks/wp-i18n-tools/pomo/streams.php +0 -209
- src/vendor/websharks/wp-i18n-tools/pomo/translations.php +0 -275
- src/vendor/websharks/wp-i18n-tools/pot-ext-meta.php +0 -76
- src/vendor/websharks/wp-i18n-tools/setup_locale +0 -40
comet-cache.php
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
-
Version:
|
4 |
Text Domain: comet-cache
|
5 |
Plugin Name: Comet Cache
|
6 |
Network: true
|
1 |
<?php
|
2 |
/*
|
3 |
+
Version: 160417
|
4 |
Text Domain: comet-cache
|
5 |
Plugin Name: Comet Cache
|
6 |
Network: true
|
readme.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
=== Comet Cache ===
|
2 |
|
3 |
-
Stable tag:
|
4 |
Requires at least: 4.2
|
5 |
Tested up to: 4.6-alpha
|
6 |
Text Domain: comet-cache
|
@@ -336,6 +336,10 @@ Requires WordPress v4.2+.
|
|
336 |
|
337 |
== Changelog ==
|
338 |
|
|
|
|
|
|
|
|
|
339 |
= v160416 =
|
340 |
|
341 |
- **Enhancement**: Several PHP 5.4+ enhancements, most notably a conversion from PHP Closures to PHP Traits. See [Issue #635](https://github.com/websharks/comet-cache/issues/635).
|
1 |
=== Comet Cache ===
|
2 |
|
3 |
+
Stable tag: 160417
|
4 |
Requires at least: 4.2
|
5 |
Tested up to: 4.6-alpha
|
6 |
Text Domain: comet-cache
|
336 |
|
337 |
== Changelog ==
|
338 |
|
339 |
+
= v160417 =
|
340 |
+
|
341 |
+
- **Bug Fix**: Fixed a "PHP Fatal error: Undefined class constant 'CACHE_PATH_NO_SCHEME'" with introduced by the previous release (v160416). This issue only affected sites where Feed Caching was enabled (_Comet Cache → Plugin Options → RSS, RDF, and Atom Feeds_). Props to MassimoD and @emanwebdev for reporting. See [Issue #739](https://github.com/websharks/comet-cache/issues/739).
|
342 |
+
|
343 |
= v160416 =
|
344 |
|
345 |
- **Enhancement**: Several PHP 5.4+ enhancements, most notably a conversion from PHP Closures to PHP Traits. See [Issue #635](https://github.com/websharks/comet-cache/issues/635).
|
src/includes/classes/FeedUtils.php
CHANGED
@@ -1,12 +1,14 @@
|
|
1 |
<?php
|
2 |
namespace WebSharks\CometCache\Classes;
|
3 |
|
|
|
|
|
4 |
/**
|
5 |
* Feed Utils.
|
6 |
*
|
7 |
* @since 150422 Rewrite.
|
8 |
*/
|
9 |
-
class FeedUtils extends AbsBase
|
10 |
{
|
11 |
/**
|
12 |
* @type string WordPress `home_url()`.
|
1 |
<?php
|
2 |
namespace WebSharks\CometCache\Classes;
|
3 |
|
4 |
+
use WebSharks\CometCache\Interfaces;
|
5 |
+
|
6 |
/**
|
7 |
* Feed Utils.
|
8 |
*
|
9 |
* @since 150422 Rewrite.
|
10 |
*/
|
11 |
+
class FeedUtils extends AbsBase implements Interfaces\Shared\CachePathConsts
|
12 |
{
|
13 |
/**
|
14 |
* @type string WordPress `home_url()`.
|
src/includes/stub.php
CHANGED
@@ -13,7 +13,7 @@ if (!defined('WPINC')) {
|
|
13 |
require_once dirname(__DIR__).'/vendor/autoload.php';
|
14 |
require_once __DIR__.'/functions/i18n-utils.php';
|
15 |
|
16 |
-
${__FILE__}['version'] = '
|
17 |
${__FILE__}['plugin'] = dirname(dirname(__DIR__));
|
18 |
${__FILE__}['plugin'] .= '/'.basename(${__FILE__}['plugin']).'.php';
|
19 |
${__FILE__}['ns_path'] = str_replace('\\', '/', __NAMESPACE__); // To dir/path.
|
13 |
require_once dirname(__DIR__).'/vendor/autoload.php';
|
14 |
require_once __DIR__.'/functions/i18n-utils.php';
|
15 |
|
16 |
+
${__FILE__}['version'] = '160417'; //version//
|
17 |
${__FILE__}['plugin'] = dirname(dirname(__DIR__));
|
18 |
${__FILE__}['plugin'] .= '/'.basename(${__FILE__}['plugin']).'.php';
|
19 |
${__FILE__}['ns_path'] = str_replace('\\', '/', __NAMESPACE__); // To dir/path.
|
src/vendor/autoload.php
CHANGED
@@ -4,4 +4,4 @@
|
|
4 |
|
5 |
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
6 |
|
7 |
-
return
|
4 |
|
5 |
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
6 |
|
7 |
+
return ComposerAutoloaderInit1282194a29af7710e5b95305c89863ea::getLoader();
|
src/vendor/composer/autoload_real.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
-
class
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitc1a53f596a710aab47629b58885a6ec2
|
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
-
spl_autoload_register(array('
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
-
spl_autoload_unregister(array('
|
25 |
|
26 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
27 |
foreach ($map as $namespace => $path) {
|
2 |
|
3 |
// autoload_real.php @generated by Composer
|
4 |
|
5 |
+
class ComposerAutoloaderInit1282194a29af7710e5b95305c89863ea
|
6 |
{
|
7 |
private static $loader;
|
8 |
|
19 |
return self::$loader;
|
20 |
}
|
21 |
|
22 |
+
spl_autoload_register(array('ComposerAutoloaderInit1282194a29af7710e5b95305c89863ea', 'loadClassLoader'), true, true);
|
23 |
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
24 |
+
spl_autoload_unregister(array('ComposerAutoloaderInit1282194a29af7710e5b95305c89863ea', 'loadClassLoader'));
|
25 |
|
26 |
$map = require __DIR__ . '/autoload_namespaces.php';
|
27 |
foreach ($map as $namespace => $path) {
|
src/vendor/websharks/wp-i18n-tools/CHANGELOG.md
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
## v15xxxx
|
2 |
-
|
3 |
-
- Initial release.
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/README.md
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
## WP i18n Tools
|
2 |
-
|
3 |
-
Modified slightly by WebSharks, Inc.
|
4 |
-
|
5 |
-
#### Differences from original:
|
6 |
-
|
7 |
-
- Adding shebang line to the top of `makepot.php`.
|
8 |
-
- Now distributing a packaged PHAR binary w/ each release.
|
9 |
-
- Setting executable bit on `makepot.php` and preserving that with Git.
|
10 |
-
- Updated to support PHP/translations embedded into `.js` files too.
|
11 |
-
- Disabling line wrapping from final output to ensure better consistency.
|
12 |
-
- Adding support for plugin directories that use a `plugin.php` file instead of `[slug].php`.
|
13 |
-
- Adding `composer.json` and package on Packagist.org.
|
14 |
-
- Auto-exclude `(?:.+?/)?vendor/.*` in themes/plugins.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/add-textdomain.php
DELETED
@@ -1,110 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Console application, which adds textdomain argument
|
4 |
-
* to all i18n function calls
|
5 |
-
*
|
6 |
-
* @author
|
7 |
-
* @version $Id$
|
8 |
-
* @package wordpress-i18n
|
9 |
-
*/
|
10 |
-
error_reporting(E_ALL);
|
11 |
-
|
12 |
-
require_once dirname( __FILE__ ) . '/makepot.php';
|
13 |
-
|
14 |
-
class AddTextdomain {
|
15 |
-
|
16 |
-
var $modified_contents = '';
|
17 |
-
var $funcs;
|
18 |
-
|
19 |
-
function AddTextdomain() {
|
20 |
-
$makepot = new MakePOT;
|
21 |
-
$this->funcs = array_keys( $makepot->rules );
|
22 |
-
}
|
23 |
-
|
24 |
-
function usage() {
|
25 |
-
$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";
|
26 |
-
fwrite(STDERR, $usage);
|
27 |
-
exit(1);
|
28 |
-
}
|
29 |
-
|
30 |
-
function process_token($token_text, $inplace) {
|
31 |
-
if ($inplace)
|
32 |
-
$this->modified_contents .= $token_text;
|
33 |
-
else
|
34 |
-
echo $token_text;
|
35 |
-
}
|
36 |
-
|
37 |
-
|
38 |
-
function process_file($domain, $source_filename, $inplace) {
|
39 |
-
|
40 |
-
$this->modified_contents = '';
|
41 |
-
$domain = addslashes($domain);
|
42 |
-
|
43 |
-
$source = file_get_contents($source_filename);
|
44 |
-
$tokens = token_get_all($source);
|
45 |
-
|
46 |
-
$in_func = false;
|
47 |
-
$args_started = false;
|
48 |
-
$parens_balance = 0;
|
49 |
-
$found_domain = false;
|
50 |
-
|
51 |
-
foreach($tokens as $token) {
|
52 |
-
$string_success = false;
|
53 |
-
if (is_array($token)) {
|
54 |
-
list($id, $text) = $token;
|
55 |
-
if (T_STRING == $id && in_array($text, $this->funcs)) {
|
56 |
-
$in_func = true;
|
57 |
-
$parens_balance = 0;
|
58 |
-
$args_started = false;
|
59 |
-
$found_domain = false;
|
60 |
-
} elseif (T_CONSTANT_ENCAPSED_STRING == $id && ("'$domain'" == $text || "\"$domain\"" == $text)) {
|
61 |
-
if ($in_func && $args_started) {
|
62 |
-
$found_domain = true;
|
63 |
-
}
|
64 |
-
}
|
65 |
-
$token = $text;
|
66 |
-
} elseif ('(' == $token){
|
67 |
-
$args_started = true;
|
68 |
-
++$parens_balance;
|
69 |
-
} elseif (')' == $token) {
|
70 |
-
--$parens_balance;
|
71 |
-
if ($in_func && 0 == $parens_balance) {
|
72 |
-
$token = $found_domain? ')' : ", '$domain')";
|
73 |
-
$in_func = false;
|
74 |
-
$args_started = false;
|
75 |
-
$found_domain = false;
|
76 |
-
}
|
77 |
-
}
|
78 |
-
$this->process_token($token, $inplace);
|
79 |
-
}
|
80 |
-
|
81 |
-
if ($inplace) {
|
82 |
-
$f = fopen($source_filename, 'w');
|
83 |
-
fwrite($f, $this->modified_contents);
|
84 |
-
fclose($f);
|
85 |
-
}
|
86 |
-
}
|
87 |
-
}
|
88 |
-
|
89 |
-
|
90 |
-
// run the CLI only if the file
|
91 |
-
// wasn't included
|
92 |
-
$included_files = get_included_files();
|
93 |
-
if ($included_files[0] == __FILE__) {
|
94 |
-
$adddomain = new AddTextdomain;
|
95 |
-
|
96 |
-
if (!isset($argv[1]) || !isset($argv[2])) {
|
97 |
-
$adddomain->usage();
|
98 |
-
}
|
99 |
-
|
100 |
-
$inplace = false;
|
101 |
-
if ('-i' == $argv[1]) {
|
102 |
-
$inplace = true;
|
103 |
-
if (!isset($argv[3])) $adddomain->usage();
|
104 |
-
array_shift($argv);
|
105 |
-
}
|
106 |
-
|
107 |
-
$adddomain->process_file($argv[1], $argv[2], $inplace);
|
108 |
-
}
|
109 |
-
|
110 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/cron-svn-pots.php
DELETED
@@ -1,117 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
require_once dirname( __FILE__ ) . '/makepot.php';
|
3 |
-
|
4 |
-
function silent_system( $command ) {
|
5 |
-
global $at_least_one_error;
|
6 |
-
ob_start();
|
7 |
-
system( "$command 2>&1", $exit_code );
|
8 |
-
$output = ob_get_contents();
|
9 |
-
ob_end_clean();
|
10 |
-
if ( $exit_code != 0 ) {
|
11 |
-
echo "ERROR:\t$command\nCODE:\t$exit_code\nOUTPUT:\n";
|
12 |
-
echo $output."\n";
|
13 |
-
} else {
|
14 |
-
echo "OK:\t$command\n";
|
15 |
-
}
|
16 |
-
return $exit_code;
|
17 |
-
}
|
18 |
-
|
19 |
-
|
20 |
-
$options = getopt( 'c:p:m:n:sa:b:u:w:df' );
|
21 |
-
if ( empty( $options ) ) {
|
22 |
-
?>
|
23 |
-
-s No branch/version directories, it's all flat
|
24 |
-
-c Application svn checkout
|
25 |
-
-p POT svn checkout
|
26 |
-
-m MakePOT project
|
27 |
-
-n POT filename
|
28 |
-
-a Relative path of application inside version dir in -c
|
29 |
-
-b Relative patch of POT dir inside version dir in -p
|
30 |
-
-u SVN username (optional)
|
31 |
-
-w SVN password (optional)
|
32 |
-
-d Dry-run
|
33 |
-
-f Fast - do not update checkouts
|
34 |
-
<?php
|
35 |
-
die;
|
36 |
-
}
|
37 |
-
|
38 |
-
$application_svn_checkout = realpath( $options['c'] );
|
39 |
-
$pot_svn_checkout = realpath( $options['p'] );
|
40 |
-
$makepot_project = str_replace( '-', '_', $options['m'] );
|
41 |
-
$pot_name = $options['n'];
|
42 |
-
$no_branch_dirs = isset( $options['s'] );
|
43 |
-
$relative_application_path = isset( $options['a'] )? '/'.$options['a'] : '';
|
44 |
-
$relative_pot_path = isset( $options['b'] )? '/'.$options['b'] : '';
|
45 |
-
$dry_run = isset( $options['d'] );
|
46 |
-
|
47 |
-
$makepot = new MakePOT;
|
48 |
-
$svn_args = array('--non-interactive');
|
49 |
-
if ( isset( $options['u'] ) && isset( $options['w'] ) ) {
|
50 |
-
$svn_args[] = '--username='.$options['u'];
|
51 |
-
$svn_args[] = '--password='.$options['w'];
|
52 |
-
$svn_args[] = '--no-auth-cache';
|
53 |
-
}
|
54 |
-
$svn_args_str = implode( ' ', array_map( 'escapeshellarg', $svn_args ) );
|
55 |
-
$svn = 'svn '.$svn_args_str;
|
56 |
-
|
57 |
-
|
58 |
-
$versions = array();
|
59 |
-
|
60 |
-
chdir( $application_svn_checkout );
|
61 |
-
if ( ! isset( $options['f'] ) ) {
|
62 |
-
$exit = silent_system( "$svn cleanup" );
|
63 |
-
if ( 0 != $exit ) die();
|
64 |
-
$exit = silent_system( "$svn up" );
|
65 |
-
if ( 0 != $exit ) die();
|
66 |
-
}
|
67 |
-
if ( is_dir( 'trunk' ) ) $versions[] = 'trunk';
|
68 |
-
$branches = glob( 'branches/*' );
|
69 |
-
if ( false !== $branches ) $versions = array_merge( $versions, $branches );
|
70 |
-
$tags = glob( 'tags/*' );
|
71 |
-
if ( false !== $tags ) $versions = array_merge( $versions, $tags );
|
72 |
-
|
73 |
-
if ( $no_branch_dirs ) {
|
74 |
-
$versions = array( '.' );
|
75 |
-
}
|
76 |
-
|
77 |
-
chdir( $pot_svn_checkout );
|
78 |
-
if ( $application_svn_checkout != $pot_svn_checkout && ! isset( $options['f'] ) ) {
|
79 |
-
$exit = silent_system( "$svn cleanup" );
|
80 |
-
if ( 0 != $exit ) die();
|
81 |
-
$exit = silent_system( "$svn up" );
|
82 |
-
if ( 0 != $exit ) die();
|
83 |
-
}
|
84 |
-
$real_application_svn_checkout = realpath( $application_svn_checkout );
|
85 |
-
foreach( $versions as $version ) {
|
86 |
-
$application_path = "$real_application_svn_checkout/$version{$relative_application_path}";
|
87 |
-
if ( !is_dir( $application_path ) ) continue;
|
88 |
-
$pot = "$version{$relative_pot_path}/$pot_name";
|
89 |
-
$exists = is_file( $pot );
|
90 |
-
// do not update old tag pots
|
91 |
-
if ( 'tags/' == substr( $version, 0, 5 ) && $exists ) continue;
|
92 |
-
if ( !is_dir( $version ) ) {
|
93 |
-
$exit = silent_system( "$svn mkdir $version" );
|
94 |
-
if ( 0 != $exit ) continue;
|
95 |
-
}
|
96 |
-
if ( !is_dir(dirname("$pot_svn_checkout/$pot")) ) continue;
|
97 |
-
if ( !call_user_func( array( &$makepot, $makepot_project ), $application_path, "$pot_svn_checkout/$pot" ) ) continue;
|
98 |
-
if ( !file_exists( "$pot_svn_checkout/$pot" ) ) continue;
|
99 |
-
if ( !$exists ) {
|
100 |
-
$exit = silent_system( "$svn add $pot" );
|
101 |
-
if ( 0 != $exit ) continue;
|
102 |
-
}
|
103 |
-
// do not commit if the difference is only in the header, but always commit a new file
|
104 |
-
$real_differences = `svn diff $pot | wc -l` > 16;
|
105 |
-
$target = $exists ? $pot : $version;
|
106 |
-
if ( !$exists || $real_differences ) {
|
107 |
-
preg_match( '/Revision:\s+(\d+)/', `svn info $application_path`, $matches );
|
108 |
-
$logmsg = isset( $matches[1] ) && intval( $matches[1] )? "POT, generated from r".intval( $matches[1] ) : 'Automatic POT update';
|
109 |
-
$command = "$svn ci $target --non-interactive --message='$logmsg'";
|
110 |
-
if ( !$dry_run )
|
111 |
-
silent_system( $command );
|
112 |
-
else
|
113 |
-
echo "CMD:\t$command\n";
|
114 |
-
} else {
|
115 |
-
silent_system( "$svn revert $target" );
|
116 |
-
}
|
117 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/extract/ExtractTest.php
DELETED
@@ -1,160 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
require_once dirname( __FILE__ ) . '/extract.php';
|
4 |
-
|
5 |
-
class ExtractTest extends PHPUnit_Framework_TestCase {
|
6 |
-
|
7 |
-
function setUp() {
|
8 |
-
$this->extractor = new StringExtractor;
|
9 |
-
$this->extractor->rules = array(
|
10 |
-
'__' => array('string'),
|
11 |
-
);
|
12 |
-
}
|
13 |
-
|
14 |
-
function test_with_just_a_string() {
|
15 |
-
$expected = new Translation_Entry( array( 'singular' => 'baba', 'references' => array('baba.php:1') ) );
|
16 |
-
$result = $this->extractor->extract_entries('<?php __("baba"); ?>', 'baba.php' );
|
17 |
-
$this->assertEquals( $expected, $result->entries['baba'] );
|
18 |
-
}
|
19 |
-
|
20 |
-
function test_entry_from_call_simple() {
|
21 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('baba') ), 'baba.php' );
|
22 |
-
$this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba' ) ) );
|
23 |
-
}
|
24 |
-
|
25 |
-
function test_entry_from_call_nonexisting_function() {
|
26 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => 'f', 'args' => array('baba') ), 'baba.php' );
|
27 |
-
$this->assertEquals( $entry, null );
|
28 |
-
}
|
29 |
-
|
30 |
-
function test_entry_from_call_too_few_args() {
|
31 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array() ), 'baba.php' );
|
32 |
-
$this->assertEquals( $entry, null );
|
33 |
-
}
|
34 |
-
|
35 |
-
function test_entry_from_call_non_expected_null_arg() {
|
36 |
-
$this->extractor->rules = array( '_nx' => array( 'singular', 'plural', 'context' ) );
|
37 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '_nx', 'args' => array('%s baba', null, 'noun') ), 'baba.php' );
|
38 |
-
$this->assertEquals( $entry, null );
|
39 |
-
}
|
40 |
-
|
41 |
-
function test_entry_from_call_more_args_should_be_ok() {
|
42 |
-
$this->extractor->rules = array( '__' => array('string') );
|
43 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('baba', 5, 'pijo', null) ), 'baba.php' );
|
44 |
-
$this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba' ) ) );
|
45 |
-
}
|
46 |
-
|
47 |
-
|
48 |
-
function test_entry_from_call_context() {
|
49 |
-
$this->extractor->rules = array( '_x' => array( 'string', 'context' ) );
|
50 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '_x', 'args' => array('baba', 'noun') ), 'baba.php' );
|
51 |
-
$this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba', 'context' => 'noun' ) ) );
|
52 |
-
}
|
53 |
-
|
54 |
-
function test_entry_from_call_plural() {
|
55 |
-
$this->extractor->rules = array( '_n' => array( 'singular', 'plural' ) );
|
56 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '_n', 'args' => array('%s baba', '%s babas') ), 'baba.php' );
|
57 |
-
$this->assertEquals( $entry, new Translation_Entry( array( 'singular' => '%s baba', 'plural' => '%s babas' ) ) );
|
58 |
-
}
|
59 |
-
|
60 |
-
function test_entry_from_call_plural_and_context() {
|
61 |
-
$this->extractor->rules = array( '_nx' => array( 'singular', 'plural', 'context' ) );
|
62 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '_nx', 'args' => array('%s baba', '%s babas', 'noun') ), 'baba.php' );
|
63 |
-
$this->assertEquals( $entry, new Translation_Entry( array( 'singular' => '%s baba', 'plural' => '%s babas', 'context' => 'noun' ) ) );
|
64 |
-
}
|
65 |
-
|
66 |
-
function test_entry_from_call_extracted_comment() {
|
67 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('baba'), 'comment' => 'translators: give me back my pants!' ), 'baba.php' );
|
68 |
-
$this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba', 'extracted_comments' => "translators: give me back my pants!\n" ) ) );
|
69 |
-
}
|
70 |
-
|
71 |
-
function test_entry_from_call_line_number() {
|
72 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('baba'), 'line' => 10 ), 'baba.php' );
|
73 |
-
$this->assertEquals( $entry, new Translation_Entry( array( 'singular' => 'baba', 'references' => array('baba.php:10') ) ) );
|
74 |
-
}
|
75 |
-
|
76 |
-
function test_entry_from_call_zero() {
|
77 |
-
$entry = $this->extractor->entry_from_call( array( 'name' => '__', 'args' => array('0') ), 'baba.php' );
|
78 |
-
$this->assertEquals( $entry, new Translation_Entry( array( 'singular' => '0' ) ) );
|
79 |
-
}
|
80 |
-
|
81 |
-
function test_entry_from_call_multiple() {
|
82 |
-
$this->extractor->rules = array( 'c' => array( 'string', 'singular', 'plural' ) );
|
83 |
-
$entries = $this->extractor->entry_from_call( array( 'name' => 'c', 'args' => array('baba', 'dyado', 'dyados') ), 'baba.php' );
|
84 |
-
$this->assertEquals( array(
|
85 |
-
new Translation_Entry( array( 'singular' => 'baba' ) ), new Translation_Entry( array( 'singular' => 'dyado', 'plural' => 'dyados' ) ) ), $entries );
|
86 |
-
}
|
87 |
-
|
88 |
-
function test_entry_from_call_multiple_first_plural_then_two_strings() {
|
89 |
-
$this->extractor->rules = array( 'c' => array( 'singular', 'plural', null, 'string', 'string' ) );
|
90 |
-
$entries = $this->extractor->entry_from_call( array( 'name' => 'c', 'args' => array('dyado', 'dyados', 'baba', 'foo', 'bar') ), 'baba.php' );
|
91 |
-
$this->assertEquals( array(
|
92 |
-
new Translation_Entry( array( 'singular' => 'dyado', 'plural' => 'dyados' ) ),
|
93 |
-
new Translation_Entry( array( 'singular' => 'foo' ) ),
|
94 |
-
new Translation_Entry( array( 'singular' => 'bar' ) ) ), $entries );
|
95 |
-
}
|
96 |
-
|
97 |
-
function test_find_function_calls_one_arg_literal() {
|
98 |
-
$this->assertEquals( array( array( 'name' => '__', 'args' => array( 'baba' ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('__'), '<?php __("baba"); ?>' ) );
|
99 |
-
}
|
100 |
-
|
101 |
-
function test_find_function_calls_one_arg_zero() {
|
102 |
-
$this->assertEquals( array( array( 'name' => '__', 'args' => array( '0' ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('__'), '<?php __("0"); ?>' ) );
|
103 |
-
}
|
104 |
-
|
105 |
-
function test_find_function_calls_one_arg_non_literal() {
|
106 |
-
$this->assertEquals( array( array( 'name' => '__', 'args' => array( null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('__'), '<?php __("baba" . "dudu"); ?>' ) );
|
107 |
-
}
|
108 |
-
|
109 |
-
function test_find_function_calls_shouldnt_be_mistaken_by_a_class() {
|
110 |
-
$this->assertEquals( array(), $this->extractor->find_function_calls( array('__'), '<?php class __ { }; ("dyado");' ) );
|
111 |
-
}
|
112 |
-
|
113 |
-
function test_find_function_calls_2_args_bad_literal() {
|
114 |
-
$this->assertEquals( array( array( 'name' => 'f', 'args' => array( null, "baba" ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f(5, "baba" ); ' ) );
|
115 |
-
}
|
116 |
-
|
117 |
-
function test_find_function_calls_2_args_bad_literal_bad() {
|
118 |
-
$this->assertEquals( array( array( 'name' => 'f', 'args' => array( null, "baba", null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f(5, "baba", 5 ); ' ) );
|
119 |
-
}
|
120 |
-
|
121 |
-
function test_find_function_calls_1_arg_bad_concat() {
|
122 |
-
$this->assertEquals( array( array( 'name' => 'f', 'args' => array( null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f( "baba" . "baba" ); ' ) );
|
123 |
-
}
|
124 |
-
|
125 |
-
function test_find_function_calls_1_arg_bad_function_call() {
|
126 |
-
$this->assertEquals( array( array( 'name' => 'f', 'args' => array( null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f( g( "baba" ) ); ' ) );
|
127 |
-
}
|
128 |
-
|
129 |
-
function test_find_function_calls_2_arg_literal_bad() {
|
130 |
-
$this->assertEquals( array( array( 'name' => 'f', 'args' => array( "baba", null ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f( "baba", null ); ' ) );
|
131 |
-
}
|
132 |
-
|
133 |
-
function test_find_function_calls_2_arg_bad_with_parens_literal() {
|
134 |
-
$this->assertEquals( array( array( 'name' => 'f', 'args' => array( null, "baba" ), 'line' => 1 ) ), $this->extractor->find_function_calls( array('f'), '<?php f( g( "dyado", "chicho", "lelya "), "baba" ); ' ) );
|
135 |
-
}
|
136 |
-
|
137 |
-
function test_find_function_calls_with_comment() {
|
138 |
-
$this->assertEquals(
|
139 |
-
array( array( 'name' => 'f', 'args' => array( 'baba' ), 'line' => 1, 'comment' => 'translators: let your ears fly!' ) ),
|
140 |
-
$this->extractor->find_function_calls( array('f'), '<?php /* translators: let your ears fly! */ f( "baba" ); ' ) );
|
141 |
-
}
|
142 |
-
|
143 |
-
function test_find_function_calls_with_not_immediate_comment() {
|
144 |
-
$this->assertEquals(
|
145 |
-
array( array( 'name' => 'f', 'args' => array( 'baba' ), 'line' => 1, 'comment' => 'translators: let your ears fly!' ) ),
|
146 |
-
$this->extractor->find_function_calls( array('f'), '<?php /* translators: let your ears fly! */ $foo = g ( f( "baba" ) ); ' ) );
|
147 |
-
}
|
148 |
-
|
149 |
-
function test_find_function_calls_with_not_immediate_comment_include_only_latest() {
|
150 |
-
$this->assertEquals(
|
151 |
-
array( array( 'name' => 'f', 'args' => array( 'baba' ), 'line' => 1, 'comment' => 'translators: let your ears fly!' ) ),
|
152 |
-
$this->extractor->find_function_calls( array('f'), '<?php /* translators: boo */ /* translators: let your ears fly! */ /* baba */ $foo = g ( f( "baba" ) ); ' ) );
|
153 |
-
}
|
154 |
-
|
155 |
-
function test_comment_prefix_should_be_case_insensitive() {
|
156 |
-
$this->assertEquals(
|
157 |
-
array( array( 'name' => 'f', 'args' => array( 'baba' ), 'line' => 1, 'comment' => 'Translators: let your ears fly!' ) ),
|
158 |
-
$this->extractor->find_function_calls( array('f'), '<?php /* Translators: let your ears fly! */ f( "baba" ); ' ) );
|
159 |
-
}
|
160 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/extract/TODO
DELETED
@@ -1 +0,0 @@
|
|
1 |
-
* php-format
|
|
src/vendor/websharks/wp-i18n-tools/extract/extract.php
DELETED
@@ -1,209 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
require_once dirname( __FILE__ ) . '/../pomo/entry.php';
|
3 |
-
require_once dirname( __FILE__ ) . '/../pomo/translations.php';
|
4 |
-
|
5 |
-
class StringExtractor {
|
6 |
-
|
7 |
-
var $rules = array();
|
8 |
-
var $comment_prefix = 'translators:';
|
9 |
-
|
10 |
-
function __construct( $rules = array() ) {
|
11 |
-
$this->rules = $rules;
|
12 |
-
}
|
13 |
-
|
14 |
-
function extract_from_directory( $dir, $excludes = array(), $includes = array(), $prefix = '' ) {
|
15 |
-
$old_cwd = getcwd();
|
16 |
-
chdir( $dir );
|
17 |
-
$translations = new Translations;
|
18 |
-
$file_names = (array) scandir( '.' );
|
19 |
-
foreach ( $file_names as $file_name ) {
|
20 |
-
if ( '.' == $file_name || '..' == $file_name ) continue;
|
21 |
-
if ( preg_match( '/\.(?:php|js)$/', $file_name ) && $this->does_file_name_match( $prefix . $file_name, $excludes, $includes ) ) {
|
22 |
-
$translations->merge_originals_with( $this->extract_from_file( $file_name, $prefix ) );
|
23 |
-
}
|
24 |
-
if ( is_dir( $file_name ) ) {
|
25 |
-
$translations->merge_originals_with( $this->extract_from_directory( $file_name, $excludes, $includes, $prefix . $file_name . '/' ) );
|
26 |
-
}
|
27 |
-
}
|
28 |
-
chdir( $old_cwd );
|
29 |
-
return $translations;
|
30 |
-
}
|
31 |
-
|
32 |
-
function extract_from_file( $file_name, $prefix ) {
|
33 |
-
$code = file_get_contents( $file_name );
|
34 |
-
return $this->extract_entries( $code, $prefix . $file_name );
|
35 |
-
}
|
36 |
-
|
37 |
-
function does_file_name_match( $path, $excludes, $includes ) {
|
38 |
-
if ( $includes ) {
|
39 |
-
$matched_any_include = false;
|
40 |
-
foreach( $includes as $include ) {
|
41 |
-
if ( preg_match( '|^'.$include.'$|', $path ) ) {
|
42 |
-
$matched_any_include = true;
|
43 |
-
break;
|
44 |
-
}
|
45 |
-
}
|
46 |
-
if ( !$matched_any_include ) return false;
|
47 |
-
}
|
48 |
-
if ( $excludes ) {
|
49 |
-
foreach( $excludes as $exclude ) {
|
50 |
-
if ( preg_match( '|^'.$exclude.'$|', $path ) ) {
|
51 |
-
return false;
|
52 |
-
}
|
53 |
-
}
|
54 |
-
}
|
55 |
-
return true;
|
56 |
-
}
|
57 |
-
|
58 |
-
function entry_from_call( $call, $file_name ) {
|
59 |
-
$rule = isset( $this->rules[$call['name']] )? $this->rules[$call['name']] : null;
|
60 |
-
if ( !$rule ) return null;
|
61 |
-
$entry = new Translation_Entry;
|
62 |
-
$multiple = array();
|
63 |
-
$complete = false;
|
64 |
-
for( $i = 0; $i < count( $rule ); ++$i ) {
|
65 |
-
if ( $rule[$i] && ( !isset( $call['args'][$i] ) || !is_string( $call['args'][$i] ) || '' == $call['args'][$i] ) ) return false;
|
66 |
-
switch( $rule[$i] ) {
|
67 |
-
case 'string':
|
68 |
-
if ( $complete ) {
|
69 |
-
$multiple[] = $entry;
|
70 |
-
$entry = new Translation_Entry;
|
71 |
-
$complete = false;
|
72 |
-
}
|
73 |
-
$entry->singular = $call['args'][$i];
|
74 |
-
$complete = true;
|
75 |
-
break;
|
76 |
-
case 'singular':
|
77 |
-
if ( $complete ) {
|
78 |
-
$multiple[] = $entry;
|
79 |
-
$entry = new Translation_Entry;
|
80 |
-
$complete = false;
|
81 |
-
}
|
82 |
-
$entry->singular = $call['args'][$i];
|
83 |
-
$entry->is_plural = true;
|
84 |
-
break;
|
85 |
-
case 'plural':
|
86 |
-
$entry->plural = $call['args'][$i];
|
87 |
-
$entry->is_plural = true;
|
88 |
-
$complete = true;
|
89 |
-
break;
|
90 |
-
case 'context':
|
91 |
-
$entry->context = $call['args'][$i];
|
92 |
-
foreach( $multiple as &$single_entry ) {
|
93 |
-
$single_entry->context = $entry->context;
|
94 |
-
}
|
95 |
-
break;
|
96 |
-
}
|
97 |
-
}
|
98 |
-
if ( isset( $call['line'] ) && $call['line'] ) {
|
99 |
-
$references = array( $file_name . ':' . $call['line'] );
|
100 |
-
$entry->references = $references;
|
101 |
-
foreach( $multiple as &$single_entry ) {
|
102 |
-
$single_entry->references = $references;
|
103 |
-
}
|
104 |
-
}
|
105 |
-
if ( isset( $call['comment'] ) && $call['comment'] ) {
|
106 |
-
$comments = rtrim( $call['comment'] ) . "\n";
|
107 |
-
$entry->extracted_comments = $comments;
|
108 |
-
foreach( $multiple as &$single_entry ) {
|
109 |
-
$single_entry->extracted_comments = $comments;
|
110 |
-
}
|
111 |
-
}
|
112 |
-
if ( $multiple && $entry ) {
|
113 |
-
$multiple[] = $entry;
|
114 |
-
return $multiple;
|
115 |
-
}
|
116 |
-
|
117 |
-
return $entry;
|
118 |
-
}
|
119 |
-
|
120 |
-
function extract_entries( $code, $file_name ) {
|
121 |
-
$translations = new Translations;
|
122 |
-
$function_calls = $this->find_function_calls( array_keys( $this->rules ), $code );
|
123 |
-
foreach( $function_calls as $call ) {
|
124 |
-
$entry = $this->entry_from_call( $call, $file_name );
|
125 |
-
if ( is_array( $entry ) )
|
126 |
-
foreach( $entry as $single_entry )
|
127 |
-
$translations->add_entry_or_merge( $single_entry );
|
128 |
-
elseif ( $entry)
|
129 |
-
$translations->add_entry_or_merge( $entry );
|
130 |
-
}
|
131 |
-
return $translations;
|
132 |
-
}
|
133 |
-
|
134 |
-
/**
|
135 |
-
* Finds all function calls in $code and returns an array with an associative array for each function:
|
136 |
-
* - name - name of the function
|
137 |
-
* - args - array for the function arguments. Each string literal is represented by itself, other arguments are represented by null.
|
138 |
-
* - line - line number
|
139 |
-
*/
|
140 |
-
function find_function_calls( $function_names, $code ) {
|
141 |
-
$tokens = token_get_all( $code );
|
142 |
-
$function_calls = array();
|
143 |
-
$latest_comment = false;
|
144 |
-
$in_func = false;
|
145 |
-
foreach( $tokens as $token ) {
|
146 |
-
$id = $text = null;
|
147 |
-
if ( is_array( $token ) ) list( $id, $text, $line ) = $token;
|
148 |
-
if ( T_WHITESPACE == $id ) continue;
|
149 |
-
if ( T_STRING == $id && in_array( $text, $function_names ) && !$in_func ) {
|
150 |
-
$in_func = true;
|
151 |
-
$paren_level = -1;
|
152 |
-
$args = array();
|
153 |
-
$func_name = $text;
|
154 |
-
$func_line = $line;
|
155 |
-
$func_comment = $latest_comment? $latest_comment : '';
|
156 |
-
|
157 |
-
$just_got_into_func = true;
|
158 |
-
$latest_comment = false;
|
159 |
-
continue;
|
160 |
-
}
|
161 |
-
if ( T_COMMENT == $id ) {
|
162 |
-
$text = trim( preg_replace( '%^/\*|//%', '', preg_replace( '%\*/$%', '', $text ) ) );
|
163 |
-
if ( 0 === stripos( $text, $this->comment_prefix ) ) {
|
164 |
-
$latest_comment = $text;
|
165 |
-
}
|
166 |
-
}
|
167 |
-
if ( !$in_func ) continue;
|
168 |
-
if ( '(' == $token ) {
|
169 |
-
$paren_level++;
|
170 |
-
if ( 0 == $paren_level ) { // start of first argument
|
171 |
-
$just_got_into_func = false;
|
172 |
-
$current_argument = null;
|
173 |
-
$current_argument_is_just_literal = true;
|
174 |
-
}
|
175 |
-
continue;
|
176 |
-
}
|
177 |
-
if ( $just_got_into_func ) {
|
178 |
-
// there wasn't a opening paren just after the function name -- this means it is not a function
|
179 |
-
$in_func = false;
|
180 |
-
$just_got_into_func = false;
|
181 |
-
}
|
182 |
-
if ( ')' == $token ) {
|
183 |
-
if ( 0 == $paren_level ) {
|
184 |
-
$in_func = false;
|
185 |
-
$args[] = $current_argument;
|
186 |
-
$call = array( 'name' => $func_name, 'args' => $args, 'line' => $func_line );
|
187 |
-
if ( $func_comment ) $call['comment'] = $func_comment;
|
188 |
-
$function_calls[] = $call;
|
189 |
-
}
|
190 |
-
$paren_level--;
|
191 |
-
continue;
|
192 |
-
}
|
193 |
-
if ( ',' == $token && 0 == $paren_level ) {
|
194 |
-
$args[] = $current_argument;
|
195 |
-
$current_argument = null;
|
196 |
-
$current_argument_is_just_literal = true;
|
197 |
-
continue;
|
198 |
-
}
|
199 |
-
if ( T_CONSTANT_ENCAPSED_STRING == $id && $current_argument_is_just_literal ) {
|
200 |
-
// we can use eval safely, because we are sure $text is just a string literal
|
201 |
-
eval('$current_argument = '.$text.';' );
|
202 |
-
continue;
|
203 |
-
}
|
204 |
-
$current_argument_is_just_literal = false;
|
205 |
-
$current_argument = null;
|
206 |
-
}
|
207 |
-
return $function_calls;
|
208 |
-
}
|
209 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/importers-i18n.php
DELETED
@@ -1,195 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
ini_set( 'display_errors', 1 );
|
3 |
-
class ImportersI18n {
|
4 |
-
var $importers_slugs = array('wpcat2tag', 'wordpress', 'utw', 'textpattern', 'stp', 'rss', 'opml', 'movabletype', 'livejournal', 'greymatter', 'dotclear', 'blogware', 'blogger');
|
5 |
-
var $username = 'nbachiyski';
|
6 |
-
var $plugins_dir = '/www/wp-content-trunk/plugins';
|
7 |
-
var $glotpress_source_dir = '/Users/nb/glotpress';
|
8 |
-
var $glotpress_api_url = 'http://x/gp/api/projects/importers/%importer%/dev';
|
9 |
-
var $glotpress_url = 'http://x/gp/projects/importers/%importer%/dev';
|
10 |
-
var $minimum_percentage = 80;
|
11 |
-
|
12 |
-
function __construct() {
|
13 |
-
$this->importers = array_map( create_function( '$x', 'return $x."-importer";' ), $this->importers_slugs);
|
14 |
-
}
|
15 |
-
|
16 |
-
function s( $importer, $text ) {
|
17 |
-
return str_replace( array( '%importer%', '%trunk%' ), array( $importer, "$importer/trunk" ), $text );
|
18 |
-
}
|
19 |
-
|
20 |
-
function call_on_all( $command ) {
|
21 |
-
foreach( $this->importers as $importer ) {
|
22 |
-
system( $this->s( $importer, $command ) );
|
23 |
-
}
|
24 |
-
}
|
25 |
-
|
26 |
-
function ls() {
|
27 |
-
$this->call_on_all( "ls %trunk%" );
|
28 |
-
}
|
29 |
-
|
30 |
-
function command( $command ) {
|
31 |
-
$this->call_on_all( $command );
|
32 |
-
}
|
33 |
-
|
34 |
-
|
35 |
-
function checkout() {
|
36 |
-
$this->call_on_all( "svn checkout --username=$this->username http://plugins.svn.wordpress.org/%importer%" );
|
37 |
-
}
|
38 |
-
|
39 |
-
function update() {
|
40 |
-
$this->call_on_all( "svn up %importer%" );
|
41 |
-
}
|
42 |
-
|
43 |
-
function rename_main_file() {
|
44 |
-
$this->call_on_all( "svn mv %importer%/trunk/*.php %importer%/trunk/%importer%.php" );
|
45 |
-
}
|
46 |
-
|
47 |
-
function link( $target ) {
|
48 |
-
$this->call_on_all( "ln -s `pwd`/%importer%/trunk $target/%importer%" );
|
49 |
-
}
|
50 |
-
|
51 |
-
function add_load_plugin_textdomain_call() {
|
52 |
-
foreach( $this->importers as $importer ) {
|
53 |
-
$importer_underscore = str_replace( '-', '_', $importer );
|
54 |
-
$main_file_name = "$importer/trunk/$importer.php";
|
55 |
-
$main_file = file_get_contents( $main_file_name );
|
56 |
-
$main_file .= "
|
57 |
-
function {$importer_underscore}_init() {
|
58 |
-
load_plugin_textdomain( '$importer', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
|
59 |
-
}
|
60 |
-
add_action( 'init', '{$importer_underscore}_init' );
|
61 |
-
";
|
62 |
-
file_put_contents( $main_file_name, $main_file );
|
63 |
-
}
|
64 |
-
}
|
65 |
-
|
66 |
-
function make_languages_dir() {
|
67 |
-
$this->call_on_all( "svn mkdir %importer%/trunk/languages" );
|
68 |
-
}
|
69 |
-
|
70 |
-
function generate_pot() {
|
71 |
-
foreach( $this->importers as $importer ) {
|
72 |
-
$old_cwd = getcwd();
|
73 |
-
chdir( "$importer/trunk/languages" );
|
74 |
-
system( "php ".dirname(__FILE__)."/makepot.php wp-plugin .." );
|
75 |
-
chdir( $old_cwd );
|
76 |
-
}
|
77 |
-
}
|
78 |
-
|
79 |
-
|
80 |
-
function diff() {
|
81 |
-
$this->call_on_all( "svn diff %trunk%" );
|
82 |
-
}
|
83 |
-
|
84 |
-
function st() {
|
85 |
-
$this->call_on_all( "svn st %trunk%" );
|
86 |
-
}
|
87 |
-
|
88 |
-
function svn_add_missing() {
|
89 |
-
$this->call_on_all( "svn add %trunk%/*" );
|
90 |
-
$this->call_on_all( "svn add %trunk%/languages/*" );
|
91 |
-
}
|
92 |
-
|
93 |
-
function lint() {
|
94 |
-
$this->call_on_all( "php -l %importer% %trunk%/%importer%.php" );
|
95 |
-
}
|
96 |
-
|
97 |
-
|
98 |
-
function add_textdomain() {
|
99 |
-
$this->call_on_all( "php ".dirname(__FILE__)."/add-textdomain.php -i %importer% %trunk%/%importer%.php" );
|
100 |
-
}
|
101 |
-
|
102 |
-
function sync() {
|
103 |
-
$this->call_on_all( "cp -R %trunk% $this->plugins_dir/%importer%" );
|
104 |
-
}
|
105 |
-
|
106 |
-
function commit($message) {
|
107 |
-
$this->call_on_all( "svn ci %trunk% -m ".escapeshellarg($message) );
|
108 |
-
}
|
109 |
-
|
110 |
-
function update_translations() {
|
111 |
-
require_once $this->glotpress_source_dir . '/locales/locales.php';
|
112 |
-
foreach( $this->importers as $importer ) {
|
113 |
-
$project_details_json = file_get_contents( $this->s( $importer, $this->glotpress_api_url ) );
|
114 |
-
$project_details = json_decode( $project_details_json );
|
115 |
-
if ( !is_object( $project_details ) ) {
|
116 |
-
echo "Couldn't get project JSON from GlotPress for $importer.\n";
|
117 |
-
continue;
|
118 |
-
}
|
119 |
-
foreach( $project_details->translation_sets as $set ) {
|
120 |
-
$locale = GP_Locales::by_slug( $set->locale );
|
121 |
-
if ( !$locale->wp_locale ) {
|
122 |
-
echo "Locale '$set->locale' doesn't have WordPress equivalent.\n";
|
123 |
-
continue;
|
124 |
-
}
|
125 |
-
$po_file = file_get_contents( $this->s( $importer, $this->glotpress_url ) . "/$locale->slug/$set->slug/export-translations" );
|
126 |
-
if ( !$po_file ) {
|
127 |
-
echo "Couldn't download translation for '$importer' in '$set->locale'.\n";
|
128 |
-
continue;
|
129 |
-
}
|
130 |
-
$po_path = $this->s( $importer, "%trunk%/languages/$locale->wp_locale.po" );
|
131 |
-
$mo_path = str_replace( '.po', '.mo', $po_path );
|
132 |
-
file_put_contents( $po_path, $po_file );
|
133 |
-
$msgfmt_output = `msgfmt --statistics $po_path -o $mo_path 2>&1`;
|
134 |
-
preg_match( '/(\d+) translated messages(?:\.|, (\d+) untranslated messages)/', $msgfmt_output, $matches );
|
135 |
-
if ( isset( $matches[2] ) ) {
|
136 |
-
$translated_percentage = $matches[1] / ( $matches[1] + $matches[2] ) * 100;
|
137 |
-
if ( $translated_percentage < $this->minimum_percentage ) {
|
138 |
-
unlink( $po_path );
|
139 |
-
unlink( $mo_path );
|
140 |
-
echo "Translation of '$importer' in '$locale->slug' has only $translated_percentage% translated, $this->minimum_percentage% are required.\n";
|
141 |
-
}
|
142 |
-
}
|
143 |
-
}
|
144 |
-
}
|
145 |
-
}
|
146 |
-
|
147 |
-
function create_glotpress_projects( $parent_project_path ) {
|
148 |
-
require_once $this->glotpress_source_dir . '/gp-load.php';
|
149 |
-
require_once dirname(__FILE__) . '/makepot.php';
|
150 |
-
$makepot = new MakePOT;
|
151 |
-
$parent_project = GP::$project->by_path( $parent_project_path );
|
152 |
-
if ( !$parent_project ) {
|
153 |
-
echo "Couldn't find project with path $parent_project_path.\n";
|
154 |
-
return;
|
155 |
-
}
|
156 |
-
foreach( $this->importers as $importer ) {
|
157 |
-
$source = $makepot->get_first_lines( $this->s( $importer, '%trunk%/%importer%.php' ), $makepot->max_header_lines);
|
158 |
-
if ( !GP::$project->by_path( "$parent_project_path/$importer") ) {
|
159 |
-
$importer_project = GP::$project->create_and_select(array(
|
160 |
-
'name' => $makepot->get_addon_header('Plugin Name', $source),
|
161 |
-
'slug' => $importer,
|
162 |
-
'description' => $makepot->get_addon_header('Description', $source),
|
163 |
-
'parent_project_id' => $parent_project->id,
|
164 |
-
));
|
165 |
-
} else {
|
166 |
-
echo "Project $parent_project_path/$importer already exists.\n";
|
167 |
-
}
|
168 |
-
if ( !GP::$project->by_path( "$parent_project_path/$importer/dev") ) {
|
169 |
-
$trunk_project = GP::$project->create_and_select(array(
|
170 |
-
'name' => 'Development (trunk)',
|
171 |
-
'slug' => 'dev',
|
172 |
-
'description' => 'Development version of ' . $makepot->get_addon_header('Plugin Name', $source),
|
173 |
-
'parent_project_id' => $importer_project->id,
|
174 |
-
'source_url_template' => $this->s($importer, "http://plugins.trac.wordpress.org/browser/%importer%/trunk/%file%#L%line%"),
|
175 |
-
));
|
176 |
-
} else {
|
177 |
-
echo "Project $parent_project_path/$importer/dev already exists.\n";
|
178 |
-
}
|
179 |
-
}
|
180 |
-
}
|
181 |
-
|
182 |
-
function import_glotpress_originals( $parent_project_path ) {
|
183 |
-
foreach( $this->importers as $importer ) {
|
184 |
-
system( $this->s( $importer, "php $this->glotpress_source_dir/scripts/import-originals.php -p $parent_project_path/%importer%/dev -f %trunk%/languages/%importer%.pot" ) );
|
185 |
-
}
|
186 |
-
}
|
187 |
-
|
188 |
-
function line_of_text( $line ) {
|
189 |
-
foreach( $this->importers as $importer ) {
|
190 |
-
echo $this->s( $importer, $line ) . "\n";
|
191 |
-
}
|
192 |
-
}
|
193 |
-
}
|
194 |
-
$importers_i18n = new ImportersI18n;
|
195 |
-
call_user_func_array( array( &$importers_i18n, $argv[1] ), array_slice( $argv, 2 ) );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/makepot.php
DELETED
@@ -1,570 +0,0 @@
|
|
1 |
-
#!/usr/bin/env php
|
2 |
-
<?php
|
3 |
-
require_once dirname( __FILE__ ) . '/not-gettexted.php';
|
4 |
-
require_once dirname( __FILE__ ) . '/pot-ext-meta.php';
|
5 |
-
require_once dirname( __FILE__ ) . '/extract/extract.php';
|
6 |
-
|
7 |
-
if ( !defined( 'STDERR' ) ) {
|
8 |
-
define( 'STDERR', fopen( 'php://stderr', 'w' ) );
|
9 |
-
}
|
10 |
-
|
11 |
-
class MakePOT {
|
12 |
-
var $max_header_lines = 30;
|
13 |
-
|
14 |
-
var $projects = array(
|
15 |
-
'generic',
|
16 |
-
'wp-frontend',
|
17 |
-
'wp-admin',
|
18 |
-
'wp-network-admin',
|
19 |
-
'wp-core',
|
20 |
-
'wp-ms',
|
21 |
-
'wp-tz',
|
22 |
-
'wp-plugin',
|
23 |
-
'wp-theme',
|
24 |
-
'bb',
|
25 |
-
'mu',
|
26 |
-
'bp',
|
27 |
-
'rosetta',
|
28 |
-
'wporg-bb-forums',
|
29 |
-
);
|
30 |
-
|
31 |
-
var $rules = array(
|
32 |
-
'_' => array('string'),
|
33 |
-
'__' => array('string'),
|
34 |
-
'_e' => array('string'),
|
35 |
-
'_c' => array('string'),
|
36 |
-
'_n' => array('singular', 'plural'),
|
37 |
-
'_n_noop' => array('singular', 'plural'),
|
38 |
-
'_nc' => array('singular', 'plural'),
|
39 |
-
'__ngettext' => array('singular', 'plural'),
|
40 |
-
'__ngettext_noop' => array('singular', 'plural'),
|
41 |
-
'_x' => array('string', 'context'),
|
42 |
-
'_ex' => array('string', 'context'),
|
43 |
-
'_nx' => array('singular', 'plural', null, 'context'),
|
44 |
-
'_nx_noop' => array('singular', 'plural', 'context'),
|
45 |
-
'_n_js' => array('singular', 'plural'),
|
46 |
-
'_nx_js' => array('singular', 'plural', 'context'),
|
47 |
-
'esc_attr__' => array('string'),
|
48 |
-
'esc_html__' => array('string'),
|
49 |
-
'esc_attr_e' => array('string'),
|
50 |
-
'esc_html_e' => array('string'),
|
51 |
-
'esc_attr_x' => array('string', 'context'),
|
52 |
-
'esc_html_x' => array('string', 'context'),
|
53 |
-
'comments_number_link' => array('string', 'singular', 'plural'),
|
54 |
-
);
|
55 |
-
|
56 |
-
var $ms_files = array( 'ms-.*', '.*/ms-.*', '.*/my-.*', 'wp-activate\.php', 'wp-signup\.php', 'wp-admin/network\.php', 'wp-admin/includes/ms\.php', 'wp-admin/network/.*\.php', 'wp-admin/includes/class-wp-ms.*' );
|
57 |
-
|
58 |
-
var $temp_files = array();
|
59 |
-
|
60 |
-
var $meta = array(
|
61 |
-
'default' => array(
|
62 |
-
'from-code' => 'utf-8',
|
63 |
-
'msgid-bugs-address' => 'http://wppolyglots.wordpress.com',
|
64 |
-
'language' => 'php',
|
65 |
-
'add-comments' => 'translators',
|
66 |
-
'comments' => "Copyright (C) {year} {package-name}\nThis file is distributed under the same license as the {package-name} package.",
|
67 |
-
),
|
68 |
-
'generic' => array(),
|
69 |
-
'wp-frontend' => array(
|
70 |
-
'description' => 'Translation of frontend strings in WordPress {version}',
|
71 |
-
'copyright-holder' => 'WordPress',
|
72 |
-
'package-name' => 'WordPress',
|
73 |
-
'package-version' => '{version}',
|
74 |
-
),
|
75 |
-
'wp-admin' => array(
|
76 |
-
'description' => 'Translation of site admin strings in WordPress {version}',
|
77 |
-
'copyright-holder' => 'WordPress',
|
78 |
-
'package-name' => 'WordPress',
|
79 |
-
'package-version' => '{version}',
|
80 |
-
),
|
81 |
-
'wp-network-admin' => array(
|
82 |
-
'description' => 'Translation of network admin strings in WordPress {version}',
|
83 |
-
'copyright-holder' => 'WordPress',
|
84 |
-
'package-name' => 'WordPress',
|
85 |
-
'package-version' => '{version}',
|
86 |
-
),
|
87 |
-
'wp-core' => array(
|
88 |
-
'description' => 'Translation of WordPress {version}',
|
89 |
-
'copyright-holder' => 'WordPress',
|
90 |
-
'package-name' => 'WordPress',
|
91 |
-
'package-version' => '{version}',
|
92 |
-
),
|
93 |
-
'wp-ms' => array(
|
94 |
-
'description' => 'Translation of multisite strings in WordPress {version}',
|
95 |
-
'copyright-holder' => 'WordPress',
|
96 |
-
'package-name' => 'WordPress',
|
97 |
-
'package-version' => '{version}',
|
98 |
-
),
|
99 |
-
'wp-tz' => array(
|
100 |
-
'description' => 'Translation of timezone strings in WordPress {version}',
|
101 |
-
'copyright-holder' => 'WordPress',
|
102 |
-
'package-name' => 'WordPress',
|
103 |
-
'package-version' => '{version}',
|
104 |
-
),
|
105 |
-
'bb' => array(
|
106 |
-
'description' => 'Translation of bbPress',
|
107 |
-
'copyright-holder' => 'bbPress',
|
108 |
-
'package-name' => 'bbPress',
|
109 |
-
),
|
110 |
-
'wp-plugin' => array(
|
111 |
-
'description' => 'Translation of the WordPress plugin {name} {version} by {author}',
|
112 |
-
'msgid-bugs-address' => 'http://wordpress.org/tag/{slug}',
|
113 |
-
'copyright-holder' => '{author}',
|
114 |
-
'package-name' => '{name}',
|
115 |
-
'package-version' => '{version}',
|
116 |
-
),
|
117 |
-
'wp-theme' => array(
|
118 |
-
'description' => 'Translation of the WordPress theme {name} {version} by {author}',
|
119 |
-
'msgid-bugs-address' => 'http://wordpress.org/tags/{slug}',
|
120 |
-
'copyright-holder' => '{author}',
|
121 |
-
'package-name' => '{name}',
|
122 |
-
'package-version' => '{version}',
|
123 |
-
'comments' => 'Copyright (C) {year} {author}\nThis file is distributed under the same license as the {package-name} package.',
|
124 |
-
),
|
125 |
-
'bp' => array(
|
126 |
-
'description' => 'Translation of BuddyPress',
|
127 |
-
'copyright-holder' => 'BuddyPress',
|
128 |
-
'package-name' => 'BuddyPress',
|
129 |
-
),
|
130 |
-
'glotpress' => array(
|
131 |
-
'description' => 'Translation of GlotPress',
|
132 |
-
'copyright-holder' => 'GlotPress',
|
133 |
-
'package-name' => 'GlotPress',
|
134 |
-
),
|
135 |
-
'wporg-bb-forums' => array(
|
136 |
-
'description' => 'WordPress.org International Forums',
|
137 |
-
'copyright-holder' => 'WordPress',
|
138 |
-
'package-name' => 'WordPress.org International Forums',
|
139 |
-
),
|
140 |
-
'rosetta' => array(
|
141 |
-
'description' => 'Rosetta (.wordpress.org locale sites)',
|
142 |
-
'copyright-holder' => 'WordPress',
|
143 |
-
'package-name' => 'Rosetta',
|
144 |
-
),
|
145 |
-
);
|
146 |
-
|
147 |
-
function __construct($deprecated = true) {
|
148 |
-
$this->extractor = new StringExtractor( $this->rules );
|
149 |
-
}
|
150 |
-
|
151 |
-
function __destruct() {
|
152 |
-
foreach ( $this->temp_files as $temp_file )
|
153 |
-
unlink( $temp_file );
|
154 |
-
}
|
155 |
-
|
156 |
-
function tempnam( $file ) {
|
157 |
-
$tempnam = tempnam( sys_get_temp_dir(), $file );
|
158 |
-
$this->temp_files[] = $tempnam;
|
159 |
-
return $tempnam;
|
160 |
-
}
|
161 |
-
|
162 |
-
function realpath_missing($path) {
|
163 |
-
return realpath(dirname($path)).DIRECTORY_SEPARATOR.basename($path);
|
164 |
-
}
|
165 |
-
|
166 |
-
function xgettext($project, $dir, $output_file, $placeholders = array(), $excludes = array(), $includes = array()) {
|
167 |
-
$meta = array_merge( $this->meta['default'], $this->meta[$project] );
|
168 |
-
$placeholders = array_merge( $meta, $placeholders );
|
169 |
-
$meta['output'] = $this->realpath_missing( $output_file );
|
170 |
-
$placeholders['year'] = date( 'Y' );
|
171 |
-
$placeholder_keys = array_map( create_function( '$x', 'return "{".$x."}";' ), array_keys( $placeholders ) );
|
172 |
-
$placeholder_values = array_values( $placeholders );
|
173 |
-
foreach($meta as $key => $value) {
|
174 |
-
$meta[$key] = str_replace($placeholder_keys, $placeholder_values, $value);
|
175 |
-
}
|
176 |
-
|
177 |
-
$originals = $this->extractor->extract_from_directory( $dir, $excludes, $includes );
|
178 |
-
$pot = new PO;
|
179 |
-
$pot->entries = $originals->entries;
|
180 |
-
|
181 |
-
$pot->set_header( 'Project-Id-Version', $meta['package-name'].' '.$meta['package-version'] );
|
182 |
-
$pot->set_header( 'Report-Msgid-Bugs-To', $meta['msgid-bugs-address'] );
|
183 |
-
$pot->set_header( 'POT-Creation-Date', gmdate( 'Y-m-d H:i:s+00:00' ) );
|
184 |
-
$pot->set_header( 'MIME-Version', '1.0' );
|
185 |
-
$pot->set_header( 'Content-Type', 'text/plain; charset=UTF-8' );
|
186 |
-
$pot->set_header( 'Content-Transfer-Encoding', '8bit' );
|
187 |
-
$pot->set_header( 'PO-Revision-Date', date( 'Y') . '-MO-DA HO:MI+ZONE' );
|
188 |
-
$pot->set_header( 'Last-Translator', 'FULL NAME <EMAIL@ADDRESS>' );
|
189 |
-
$pot->set_header( 'Language-Team', 'LANGUAGE <LL@li.org>' );
|
190 |
-
$pot->set_comment_before_headers( $meta['comments'] );
|
191 |
-
$pot->export_to_file( $output_file );
|
192 |
-
return true;
|
193 |
-
}
|
194 |
-
|
195 |
-
function wp_generic($dir, $args) {
|
196 |
-
$defaults = array(
|
197 |
-
'project' => 'wp-core',
|
198 |
-
'output' => null,
|
199 |
-
'default_output' => 'wordpress.pot',
|
200 |
-
'includes' => array(),
|
201 |
-
'excludes' => array_merge(
|
202 |
-
array('wp-admin/includes/continents-cities\.php', 'wp-content/themes/twenty.*', ),
|
203 |
-
$this->ms_files
|
204 |
-
),
|
205 |
-
'extract_not_gettexted' => false,
|
206 |
-
'not_gettexted_files_filter' => false,
|
207 |
-
);
|
208 |
-
$args = array_merge( $defaults, $args );
|
209 |
-
extract( $args );
|
210 |
-
$placeholders = array();
|
211 |
-
if ( $wp_version = $this->wp_version( $dir ) )
|
212 |
-
$placeholders['version'] = $wp_version;
|
213 |
-
else
|
214 |
-
return false;
|
215 |
-
$output = is_null( $output )? $default_output : $output;
|
216 |
-
$res = $this->xgettext( $project, $dir, $output, $placeholders, $excludes, $includes );
|
217 |
-
if ( !$res ) return false;
|
218 |
-
|
219 |
-
if ( $extract_not_gettexted ) {
|
220 |
-
$old_dir = getcwd();
|
221 |
-
$output = realpath( $output );
|
222 |
-
chdir( $dir );
|
223 |
-
$php_files = NotGettexted::list_php_files('.');
|
224 |
-
$php_files = array_filter( $php_files, $not_gettexted_files_filter );
|
225 |
-
$not_gettexted = new NotGettexted;
|
226 |
-
$res = $not_gettexted->command_extract( $output, $php_files );
|
227 |
-
chdir( $old_dir );
|
228 |
-
/* Adding non-gettexted strings can repeat some phrases */
|
229 |
-
$output_shell = escapeshellarg( $output );
|
230 |
-
system( "msguniq --use-first $output_shell -o $output_shell" );
|
231 |
-
}
|
232 |
-
return $res;
|
233 |
-
}
|
234 |
-
|
235 |
-
function wp_core($dir, $output) {
|
236 |
-
if ( file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
|
237 |
-
|
238 |
-
return $this->wp_generic( $dir, array(
|
239 |
-
'project' => 'wp-core', 'output' => $output,
|
240 |
-
'extract_not_gettexted' => true,
|
241 |
-
'not_gettexted_files_filter' => array( &$this, 'is_not_ms_file' ),
|
242 |
-
) );
|
243 |
-
}
|
244 |
-
|
245 |
-
function wp_frontend($dir, $output) {
|
246 |
-
if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
|
247 |
-
|
248 |
-
return $this->wp_generic( $dir, array(
|
249 |
-
'project' => 'wp-frontend', 'output' => $output,
|
250 |
-
'includes' => array(), 'excludes' => array( 'wp-admin/.*', 'wp-content/themes/.*' ),
|
251 |
-
'default_output' => 'wordpress.pot',
|
252 |
-
) );
|
253 |
-
}
|
254 |
-
|
255 |
-
function wp_admin($dir, $output) {
|
256 |
-
if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
|
257 |
-
|
258 |
-
$frontend_pot = $this->tempnam( 'frontend.pot' );
|
259 |
-
if ( false === $frontend_pot ) return false;
|
260 |
-
|
261 |
-
$frontend_result = $this->wp_frontend( $dir, $frontend_pot );
|
262 |
-
if ( ! $frontend_result )
|
263 |
-
return false;
|
264 |
-
|
265 |
-
$result = $this->wp_generic( $dir, array(
|
266 |
-
'project' => 'wp-admin', 'output' => $output,
|
267 |
-
'includes' => array( 'wp-admin/.*' ), 'excludes' => array( 'wp-admin/includes/continents-cities\.php', 'wp-admin/network/.*', 'wp-admin/network.php' ),
|
268 |
-
'default_output' => 'wordpress-admin.pot',
|
269 |
-
) );
|
270 |
-
|
271 |
-
if ( ! $result )
|
272 |
-
return false;
|
273 |
-
|
274 |
-
$potextmeta = new PotExtMeta;
|
275 |
-
$result = $potextmeta->append( "$dir/wp-content/plugins/akismet/akismet.php", $output );
|
276 |
-
if ( ! $result )
|
277 |
-
return false;
|
278 |
-
$result = $potextmeta->append( "$dir/wp-content/plugins/hello.php", $output );
|
279 |
-
if ( ! $result )
|
280 |
-
return false;
|
281 |
-
/* Adding non-gettexted strings can repeat some phrases */
|
282 |
-
$output_shell = escapeshellarg($output);
|
283 |
-
system("msguniq $output_shell -o $output_shell");
|
284 |
-
|
285 |
-
$common_pot = $this->tempnam( 'common.pot' );
|
286 |
-
if ( ! $common_pot )
|
287 |
-
return false;
|
288 |
-
$admin_pot = realpath( is_null( $output ) ? 'wordpress-admin.pot' : $output );
|
289 |
-
system( "msgcat --more-than=1 --use-first $frontend_pot $admin_pot > $common_pot" );
|
290 |
-
system( "msgcat -u --use-first $admin_pot $common_pot -o $admin_pot" );
|
291 |
-
return true;
|
292 |
-
}
|
293 |
-
|
294 |
-
function wp_network_admin($dir, $output) {
|
295 |
-
if ( ! file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
|
296 |
-
|
297 |
-
$frontend_pot = $this->tempnam( 'frontend.pot' );
|
298 |
-
if ( false === $frontend_pot ) return false;
|
299 |
-
|
300 |
-
$frontend_result = $this->wp_frontend( $dir, $frontend_pot );
|
301 |
-
if ( ! $frontend_result )
|
302 |
-
return false;
|
303 |
-
|
304 |
-
$admin_pot = $this->tempnam( 'admin.pot' );
|
305 |
-
if ( false === $admin_pot ) return false;
|
306 |
-
|
307 |
-
$admin_result = $this->wp_admin( $dir, $admin_pot );
|
308 |
-
if ( ! $admin_result )
|
309 |
-
return false;
|
310 |
-
|
311 |
-
$result = $this->wp_generic( $dir, array(
|
312 |
-
'project' => 'wp-network-admin', 'output' => $output,
|
313 |
-
'includes' => array( 'wp-admin/network/.*', 'wp-admin/network.php' ), 'excludes' => array(),
|
314 |
-
'default_output' => 'wordpress-admin-network.pot',
|
315 |
-
) );
|
316 |
-
|
317 |
-
if ( ! $result ) {
|
318 |
-
return false;
|
319 |
-
}
|
320 |
-
|
321 |
-
$common_pot = $this->tempnam( 'common.pot' );
|
322 |
-
if ( ! $common_pot )
|
323 |
-
return false;
|
324 |
-
|
325 |
-
$net_admin_pot = realpath( is_null( $output ) ? 'wordpress-network-admin.pot' : $output );
|
326 |
-
system( "msgcat --more-than=1 --use-first $frontend_pot $admin_pot $net_admin_pot > $common_pot" );
|
327 |
-
system( "msgcat -u --use-first $net_admin_pot $common_pot -o $net_admin_pot" );
|
328 |
-
return true;
|
329 |
-
}
|
330 |
-
|
331 |
-
function wp_ms($dir, $output) {
|
332 |
-
if ( file_exists( "$dir/wp-admin/user/about.php" ) ) return false;
|
333 |
-
if ( !is_file("$dir/wp-admin/ms-users.php") ) return false;
|
334 |
-
$core_pot = $this->tempnam( 'wordpress.pot' );
|
335 |
-
if ( false === $core_pot ) return false;
|
336 |
-
$core_result = $this->wp_core( $dir, $core_pot );
|
337 |
-
if ( ! $core_result )
|
338 |
-
return false;
|
339 |
-
$ms_result = $this->wp_generic( $dir, array(
|
340 |
-
'project' => 'wp-ms', 'output' => $output,
|
341 |
-
'includes' => $this->ms_files, 'excludes' => array(),
|
342 |
-
'default_output' => 'wordpress-ms.pot',
|
343 |
-
'extract_not_gettexted' => true,
|
344 |
-
'not_gettexted_files_filter' => array( &$this, 'is_ms_file' ),
|
345 |
-
) );
|
346 |
-
if ( !$ms_result ) {
|
347 |
-
return false;
|
348 |
-
}
|
349 |
-
$common_pot = $this->tempnam( 'common.pot' );
|
350 |
-
if ( ! $common_pot )
|
351 |
-
return false;
|
352 |
-
$ms_pot = realpath( is_null( $output )? 'wordpress-ms.pot' : $output );
|
353 |
-
system( "msgcat --more-than=1 --use-first $core_pot $ms_pot > $common_pot" );
|
354 |
-
system( "msgcat -u --use-first $ms_pot $common_pot -o $ms_pot" );
|
355 |
-
return true;
|
356 |
-
}
|
357 |
-
|
358 |
-
function wp_tz($dir, $output) {
|
359 |
-
$continents_path = 'wp-admin/includes/continents-cities.php';
|
360 |
-
if ( !file_exists( "$dir/$continents_path" ) ) return false;
|
361 |
-
return $this->wp_generic( $dir, array(
|
362 |
-
'project' => 'wp-tz', 'output' => $output,
|
363 |
-
'includes' => array($continents_path), 'excludes' => array(),
|
364 |
-
'default_output' => 'wordpress-continents-cities.pot',
|
365 |
-
) );
|
366 |
-
}
|
367 |
-
|
368 |
-
function wp_version($dir) {
|
369 |
-
$version_php = $dir.'/wp-includes/version.php';
|
370 |
-
if ( !is_readable( $version_php ) ) return false;
|
371 |
-
return preg_match( '/\$wp_version\s*=\s*\'(.*?)\';/', file_get_contents( $version_php ), $matches )? $matches[1] : false;
|
372 |
-
}
|
373 |
-
|
374 |
-
|
375 |
-
function mu($dir, $output) {
|
376 |
-
$placeholders = array();
|
377 |
-
if (preg_match('/\$wpmu_version\s*=\s*\'(.*?)\';/', file_get_contents($dir.'/wp-includes/version.php'), $matches)) {
|
378 |
-
$placeholders['version'] = $matches[1];
|
379 |
-
}
|
380 |
-
$output = is_null($output)? 'wordpress.pot' : $output;
|
381 |
-
return $this->xgettext('wp', $dir, $output, $placeholders);
|
382 |
-
}
|
383 |
-
|
384 |
-
|
385 |
-
function bb($dir, $output) {
|
386 |
-
$placeholders = array();
|
387 |
-
$output = is_null($output)? 'bbpress.pot' : $output;
|
388 |
-
return $this->xgettext('bb', $dir, $output, $placeholders);
|
389 |
-
|
390 |
-
}
|
391 |
-
|
392 |
-
function get_first_lines($filename, $lines = 30) {
|
393 |
-
$extf = fopen($filename, 'r');
|
394 |
-
if (!$extf) return false;
|
395 |
-
$first_lines = '';
|
396 |
-
foreach(range(1, $lines) as $x) {
|
397 |
-
$line = fgets($extf);
|
398 |
-
if (feof($extf)) break;
|
399 |
-
if (false === $line) {
|
400 |
-
return false;
|
401 |
-
}
|
402 |
-
$first_lines .= $line;
|
403 |
-
}
|
404 |
-
return $first_lines;
|
405 |
-
}
|
406 |
-
|
407 |
-
|
408 |
-
function get_addon_header($header, &$source) {
|
409 |
-
if (preg_match('|'.$header.':(.*)$|mi', $source, $matches))
|
410 |
-
return trim($matches[1]);
|
411 |
-
else
|
412 |
-
return false;
|
413 |
-
}
|
414 |
-
|
415 |
-
function generic($dir, $output) {
|
416 |
-
$output = is_null($output)? "generic.pot" : $output;
|
417 |
-
return $this->xgettext('generic', $dir, $output, array());
|
418 |
-
}
|
419 |
-
|
420 |
-
function guess_plugin_slug($dir) {
|
421 |
-
if ('trunk' == basename($dir)) {
|
422 |
-
$slug = basename(dirname($dir));
|
423 |
-
} elseif (in_array(basename(dirname($dir)), array('branches', 'tags'))) {
|
424 |
-
$slug = basename(dirname(dirname($dir)));
|
425 |
-
} else {
|
426 |
-
$slug = basename($dir);
|
427 |
-
}
|
428 |
-
return $slug;
|
429 |
-
}
|
430 |
-
|
431 |
-
function wp_plugin($dir, $output, $slug = null) {
|
432 |
-
$placeholders = array();
|
433 |
-
// guess plugin slug
|
434 |
-
if (is_null($slug)) {
|
435 |
-
$slug = $this->guess_plugin_slug($dir);
|
436 |
-
}
|
437 |
-
$main_file = $dir.'/'.$slug.'.php';
|
438 |
-
if(!is_file($main_file)) $main_file = $dir.'/plugin.php';
|
439 |
-
$source = $this->get_first_lines($main_file, $this->max_header_lines);
|
440 |
-
|
441 |
-
$placeholders['version'] = $this->get_addon_header('Version', $source);
|
442 |
-
$placeholders['author'] = $this->get_addon_header('Author', $source);
|
443 |
-
$placeholders['name'] = $this->get_addon_header('Plugin Name', $source);
|
444 |
-
$placeholders['slug'] = $slug;
|
445 |
-
|
446 |
-
$output = is_null($output)? "$slug.pot" : $output;
|
447 |
-
$res = $this->xgettext('wp-plugin', $dir, $output, $placeholders, array('(?:.+?/)?vendor/.*'));
|
448 |
-
if (!$res) return false;
|
449 |
-
$potextmeta = new PotExtMeta;
|
450 |
-
$res = $potextmeta->append($main_file, $output);
|
451 |
-
/* Adding non-gettexted strings can repeat some phrases */
|
452 |
-
$output_shell = escapeshellarg($output);
|
453 |
-
system("msguniq $output_shell -o $output_shell --no-wrap");
|
454 |
-
return $res;
|
455 |
-
}
|
456 |
-
|
457 |
-
function wp_theme($dir, $output, $slug = null) {
|
458 |
-
$placeholders = array();
|
459 |
-
// guess plugin slug
|
460 |
-
if (is_null($slug)) {
|
461 |
-
$slug = $this->guess_plugin_slug($dir);
|
462 |
-
}
|
463 |
-
$main_file = $dir.'/style.css';
|
464 |
-
$source = $this->get_first_lines($main_file, $this->max_header_lines);
|
465 |
-
|
466 |
-
$placeholders['version'] = $this->get_addon_header('Version', $source);
|
467 |
-
$placeholders['author'] = $this->get_addon_header('Author', $source);
|
468 |
-
$placeholders['name'] = $this->get_addon_header('Theme Name', $source);
|
469 |
-
$placeholders['slug'] = $slug;
|
470 |
-
|
471 |
-
$license = $this->get_addon_header( 'License', $source );
|
472 |
-
if ( $license )
|
473 |
-
$this->meta['wp-theme']['comments'] = "Copyright (C) {year} {author}\nThis file is distributed under the {$license}.";
|
474 |
-
else
|
475 |
-
$this->meta['wp-theme']['comments'] = "Copyright (C) {year} {author}\nThis file is distributed under the same license as the {package-name} package.";
|
476 |
-
|
477 |
-
$output = is_null($output)? "$slug.pot" : $output;
|
478 |
-
$res = $this->xgettext('wp-theme', $dir, $output, $placeholders, array('(?:.+?/)?vendor/.*'));
|
479 |
-
if (! $res )
|
480 |
-
return false;
|
481 |
-
$potextmeta = new PotExtMeta;
|
482 |
-
$res = $potextmeta->append( $main_file, $output, array( 'Theme Name', 'Theme URI', 'Description', 'Author', 'Author URI' ) );
|
483 |
-
if ( ! $res )
|
484 |
-
return false;
|
485 |
-
// If we're dealing with a pre-3.4 default theme, don't extract page templates before 3.4.
|
486 |
-
$extract_templates = ! in_array( $slug, array( 'twentyten', 'twentyeleven', 'default', 'classic' ) );
|
487 |
-
if ( ! $extract_templates ) {
|
488 |
-
$wp_dir = dirname( dirname( dirname( $dir ) ) );
|
489 |
-
$extract_templates = file_exists( "$wp_dir/wp-admin/user/about.php" ) || ! file_exists( "$wp_dir/wp-load.php" );
|
490 |
-
}
|
491 |
-
if ( $extract_templates ) {
|
492 |
-
$res = $potextmeta->append( $dir, $output, array( 'Template Name' ) );
|
493 |
-
if ( ! $res )
|
494 |
-
return false;
|
495 |
-
$files = scandir( $dir );
|
496 |
-
foreach ( $files as $file ) {
|
497 |
-
if ( '.' == $file[0] || 'CVS' == $file )
|
498 |
-
continue;
|
499 |
-
if ( is_dir( $dir . '/' . $file ) ) {
|
500 |
-
$res = $potextmeta->append( $dir . '/' . $file, $output, array( 'Template Name' ) );
|
501 |
-
if ( ! $res )
|
502 |
-
return false;
|
503 |
-
}
|
504 |
-
}
|
505 |
-
}
|
506 |
-
/* Adding non-gettexted strings can repeat some phrases */
|
507 |
-
$output_shell = escapeshellarg($output);
|
508 |
-
system("msguniq $output_shell -o $output_shell --no-wrap");
|
509 |
-
return $res;
|
510 |
-
}
|
511 |
-
|
512 |
-
function bp($dir, $output) {
|
513 |
-
$output = is_null($output)? "buddypress.pot" : $output;
|
514 |
-
return $this->xgettext('bp', $dir, $output, array(), array('bp-forums/bbpress/.*'));
|
515 |
-
}
|
516 |
-
|
517 |
-
function glotpress( $dir, $output ) {
|
518 |
-
$output = is_null( $output ) ? "glotpress.pot" : $output;
|
519 |
-
return $this->xgettext( 'glotpress', $dir, $output );
|
520 |
-
}
|
521 |
-
|
522 |
-
function wporg_bb_forums( $dir, $output ) {
|
523 |
-
$output = is_null( $output ) ? 'wporg.pot' : $output;
|
524 |
-
return $this->xgettext( 'wporg-bb-forums', $dir, $output, array(), array(
|
525 |
-
'bb-plugins/elfakismet/.*',
|
526 |
-
'bb-plugins/support-forum/.*',
|
527 |
-
) );
|
528 |
-
}
|
529 |
-
|
530 |
-
function rosetta( $dir, $output ) {
|
531 |
-
$output = is_null( $output )? 'rosetta.pot' : $output;
|
532 |
-
return $this->xgettext( 'rosetta', $dir, $output, array(), array(), array(
|
533 |
-
'mu-plugins/rosetta.*\.php',
|
534 |
-
'mu-plugins/rosetta/[^/]+\.php',
|
535 |
-
'mu-plugins/rosetta/tmpl/.*\.php',
|
536 |
-
'themes/rosetta/.*\.php',
|
537 |
-
) );
|
538 |
-
}
|
539 |
-
|
540 |
-
function is_ms_file( $file_name ) {
|
541 |
-
$is_ms_file = false;
|
542 |
-
$prefix = substr( $file_name, 0, 2 ) === './'? '\./' : '';
|
543 |
-
foreach( $this->ms_files as $ms_file )
|
544 |
-
if ( preg_match( '|^'.$prefix.$ms_file.'$|', $file_name ) ) {
|
545 |
-
$is_ms_file = true;
|
546 |
-
break;
|
547 |
-
}
|
548 |
-
return $is_ms_file;
|
549 |
-
}
|
550 |
-
|
551 |
-
function is_not_ms_file( $file_name ) {
|
552 |
-
return !$this->is_ms_file( $file_name );
|
553 |
-
}
|
554 |
-
}
|
555 |
-
|
556 |
-
if ((defined('IS_PHAR_MAKEPOT') && IS_PHAR_MAKEPOT) || (($included_files = get_included_files()) && $included_files[0] == __FILE__)) {
|
557 |
-
$makepot = new MakePOT;
|
558 |
-
if ((3 == count($argv) || 4 == count($argv)) && in_array($method = str_replace('-', '_', $argv[1]), get_class_methods($makepot))) {
|
559 |
-
$res = call_user_func(array(&$makepot, $method), realpath($argv[2]), isset($argv[3])? $argv[3] : null);
|
560 |
-
if (false === $res) {
|
561 |
-
fwrite(STDERR, "Couldn't generate POT file!\n");
|
562 |
-
}
|
563 |
-
} else {
|
564 |
-
$usage = "Usage: php makepot.php PROJECT DIRECTORY [OUTPUT]\n\n";
|
565 |
-
$usage .= "Generate POT file from the files in DIRECTORY [OUTPUT]\n";
|
566 |
-
$usage .= "Available projects: ".implode(', ', $makepot->projects)."\n";
|
567 |
-
fwrite(STDERR, $usage);
|
568 |
-
exit(1);
|
569 |
-
}
|
570 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/not-gettexted.php
DELETED
@@ -1,234 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Console application, which extracts or replaces strings for
|
4 |
-
* translation, which cannot be gettexted
|
5 |
-
*
|
6 |
-
* @version $Id$
|
7 |
-
* @package wordpress-i18n
|
8 |
-
* @subpackage tools
|
9 |
-
*/
|
10 |
-
// see: http://php.net/tokenizer
|
11 |
-
if ( ! defined( 'T_ML_COMMENT' ) )
|
12 |
-
define( 'T_ML_COMMENT', T_COMMENT );
|
13 |
-
else
|
14 |
-
define( 'T_DOC_COMMENT', T_ML_COMMENT );
|
15 |
-
|
16 |
-
require_once dirname( __FILE__ ) . '/pomo/po.php';
|
17 |
-
require_once dirname( __FILE__ ) . '/pomo/mo.php';
|
18 |
-
|
19 |
-
class NotGettexted {
|
20 |
-
var $enable_logging = false;
|
21 |
-
|
22 |
-
var $STAGE_OUTSIDE = 0;
|
23 |
-
var $STAGE_START_COMMENT = 1;
|
24 |
-
var $STAGE_WHITESPACE_BEFORE = 2;
|
25 |
-
var $STAGE_STRING = 3;
|
26 |
-
var $STAGE_WHITESPACE_AFTER = 4;
|
27 |
-
var $STAGE_END_COMMENT = 4;
|
28 |
-
|
29 |
-
var $commands = array('extract' => 'command_extract', 'replace' => 'command_replace' );
|
30 |
-
|
31 |
-
|
32 |
-
function logmsg() {
|
33 |
-
$args = func_get_args();
|
34 |
-
if ($this->enable_logging) error_log(implode(' ', $args));
|
35 |
-
}
|
36 |
-
|
37 |
-
function stderr($msg, $nl=true) {
|
38 |
-
fwrite(STDERR, $msg.($nl? "\n" : ""));
|
39 |
-
}
|
40 |
-
|
41 |
-
function cli_die($msg) {
|
42 |
-
$this->stderr($msg);
|
43 |
-
exit(1);
|
44 |
-
}
|
45 |
-
|
46 |
-
function unchanged_token($token, $s='') {
|
47 |
-
return is_array($token)? $token[1] : $token;
|
48 |
-
}
|
49 |
-
|
50 |
-
function ignore_token($token, $s='') {
|
51 |
-
return '';
|
52 |
-
}
|
53 |
-
|
54 |
-
function list_php_files($dir) {
|
55 |
-
$files = array();
|
56 |
-
$items = scandir( $dir );
|
57 |
-
foreach ( (array) $items as $item ) {
|
58 |
-
$full_item = $dir . '/' . $item;
|
59 |
-
if ('.' == $item || '..' == $item)
|
60 |
-
continue;
|
61 |
-
if ('.php' == substr($item, -4))
|
62 |
-
$files[] = $full_item;
|
63 |
-
if (is_dir($full_item))
|
64 |
-
$files += array_merge($files, NotGettexted::list_php_files($full_item, $files));
|
65 |
-
}
|
66 |
-
return $files;
|
67 |
-
}
|
68 |
-
|
69 |
-
|
70 |
-
function make_string_aggregator($global_array_name, $filename) {
|
71 |
-
$a = $global_array_name;
|
72 |
-
return create_function('$string, $comment_id, $line_number', 'global $'.$a.'; $'.$a.'[] = array($string, $comment_id, '.var_export($filename, true).', $line_number);');
|
73 |
-
}
|
74 |
-
|
75 |
-
function make_mo_replacer($global_mo_name) {
|
76 |
-
$m = $global_mo_name;
|
77 |
-
return create_function('$token, $string', 'global $'.$m.'; return var_export($'.$m.'->translate($string), true);');
|
78 |
-
}
|
79 |
-
|
80 |
-
function walk_tokens(&$tokens, $string_action, $other_action, $register_action=null) {
|
81 |
-
|
82 |
-
$current_comment_id = '';
|
83 |
-
$current_string = '';
|
84 |
-
$current_string_line = 0;
|
85 |
-
|
86 |
-
$result = '';
|
87 |
-
$line = 1;
|
88 |
-
|
89 |
-
foreach($tokens as $token) {
|
90 |
-
if (is_array($token)) {
|
91 |
-
list($id, $text) = $token;
|
92 |
-
$line += substr_count($text, "\n");
|
93 |
-
if ((T_ML_COMMENT == $id || T_COMMENT == $id) && preg_match('|/\*\s*(/?WP_I18N_[a-z_]+)\s*\*/|i', $text, $matches)) {
|
94 |
-
if ($this->STAGE_OUTSIDE == $stage) {
|
95 |
-
$stage = $this->STAGE_START_COMMENT;
|
96 |
-
$current_comment_id = $matches[1];
|
97 |
-
$this->logmsg('start comment', $current_comment_id);
|
98 |
-
$result .= call_user_func($other_action, $token);
|
99 |
-
continue;
|
100 |
-
}
|
101 |
-
if ($this->STAGE_START_COMMENT <= $stage && $stage <= $this->STAGE_WHITESPACE_AFTER && '/'.$current_comment_id == $matches[1]) {
|
102 |
-
$stage = $this->STAGE_END_COMMENT;
|
103 |
-
$this->logmsg('end comment', $current_comment_id);
|
104 |
-
$result .= call_user_func($other_action, $token);
|
105 |
-
if (!is_null($register_action)) call_user_func($register_action, $current_string, $current_comment_id, $current_string_line);
|
106 |
-
continue;
|
107 |
-
}
|
108 |
-
} else if (T_CONSTANT_ENCAPSED_STRING == $id) {
|
109 |
-
if ($this->STAGE_START_COMMENT <= $stage && $stage < $this->STAGE_WHITESPACE_AFTER) {
|
110 |
-
eval('$current_string='.$text.';');
|
111 |
-
$this->logmsg('string', $current_string);
|
112 |
-
$current_string_line = $line;
|
113 |
-
$result .= call_user_func($string_action, $token, $current_string);
|
114 |
-
continue;
|
115 |
-
}
|
116 |
-
} else if (T_WHITESPACE == $id) {
|
117 |
-
if ($this->STAGE_START_COMMENT <= $stage && $stage < $this->STAGE_STRING) {
|
118 |
-
$stage = $this->STAGE_WHITESPACE_BEFORE;
|
119 |
-
$this->logmsg('whitespace before');
|
120 |
-
$result .= call_user_func($other_action, $token);
|
121 |
-
continue;
|
122 |
-
}
|
123 |
-
if ($this->STAGE_STRING < $stage && $stage < $this->STAGE_END_COMMENT) {
|
124 |
-
$stage = $this->STAGE_WHITESPACE_AFTER;
|
125 |
-
$this->logmsg('whitespace after');
|
126 |
-
$result .= call_user_func($other_action, $token);
|
127 |
-
continue;
|
128 |
-
}
|
129 |
-
}
|
130 |
-
}
|
131 |
-
$result .= call_user_func($other_action, $token);
|
132 |
-
$stage = $this->STAGE_OUTSIDE;
|
133 |
-
$current_comment_id = '';
|
134 |
-
$current_string = '';
|
135 |
-
$current_string_line = 0;
|
136 |
-
}
|
137 |
-
return $result;
|
138 |
-
}
|
139 |
-
|
140 |
-
|
141 |
-
function command_extract() {
|
142 |
-
$args = func_get_args();
|
143 |
-
$pot_filename = $args[0];
|
144 |
-
if (isset($args[1]) && is_array($args[1]))
|
145 |
-
$filenames = $args[1];
|
146 |
-
else
|
147 |
-
$filenames = array_slice($args, 1);
|
148 |
-
|
149 |
-
$global_name = '__entries_'.mt_rand(1, 1000);
|
150 |
-
$GLOBALS[$global_name] = array();
|
151 |
-
|
152 |
-
foreach($filenames as $filename) {
|
153 |
-
$tokens = token_get_all(file_get_contents($filename));
|
154 |
-
$aggregator = $this->make_string_aggregator($global_name, $filename);
|
155 |
-
$this->walk_tokens($tokens, array(&$this, 'ignore_token'), array(&$this, 'ignore_token'), $aggregator);
|
156 |
-
}
|
157 |
-
|
158 |
-
$potf = '-' == $pot_filename? STDOUT : @fopen($pot_filename, 'a');
|
159 |
-
if (false === $potf) {
|
160 |
-
$this->cli_die("Couldn't open pot file: $pot_filename");
|
161 |
-
}
|
162 |
-
|
163 |
-
foreach($GLOBALS[$global_name] as $item) {
|
164 |
-
@list($string, $comment_id, $filename, $line_number) = $item;
|
165 |
-
$filename = isset($filename)? preg_replace('|^\./|', '', $filename) : '';
|
166 |
-
$ref_line_number = isset($line_number)? ":$line_number" : '';
|
167 |
-
$args = array(
|
168 |
-
'singular' => $string,
|
169 |
-
'extracted_comments' => "Not gettexted string $comment_id",
|
170 |
-
'references' => array("$filename$ref_line_number"),
|
171 |
-
);
|
172 |
-
$entry = new Translation_Entry($args);
|
173 |
-
fwrite($potf, "\n".PO::export_entry($entry)."\n");
|
174 |
-
}
|
175 |
-
if ('-' != $pot_filename) fclose($potf);
|
176 |
-
return true;
|
177 |
-
}
|
178 |
-
|
179 |
-
function command_replace() {
|
180 |
-
$args = func_get_args();
|
181 |
-
$mo_filename = $args[0];
|
182 |
-
if (isset($args[1]) && is_array($args[1]))
|
183 |
-
$filenames = $args[1];
|
184 |
-
else
|
185 |
-
$filenames = array_slice($args, 1);
|
186 |
-
|
187 |
-
$global_name = '__mo_'.mt_rand(1, 1000);
|
188 |
-
$GLOBALS[$global_name] = new MO();
|
189 |
-
$replacer = $this->make_mo_replacer($global_name);
|
190 |
-
|
191 |
-
$res = $GLOBALS[$global_name]->import_from_file($mo_filename);
|
192 |
-
if (false === $res) {
|
193 |
-
$this->cli_die("Couldn't read MO file '$mo_filename'!");
|
194 |
-
}
|
195 |
-
foreach($filenames as $filename) {
|
196 |
-
$source = file_get_contents($filename);
|
197 |
-
if ( strlen($source) > 150000 ) continue;
|
198 |
-
$tokens = token_get_all($source);
|
199 |
-
$new_file = $this->walk_tokens($tokens, $replacer, array(&$this, 'unchanged_token'));
|
200 |
-
$f = fopen($filename, 'w');
|
201 |
-
fwrite($f, $new_file);
|
202 |
-
fclose($f);
|
203 |
-
}
|
204 |
-
return true;
|
205 |
-
}
|
206 |
-
|
207 |
-
function usage() {
|
208 |
-
$this->stderr('php i18n-comments.php COMMAND OUTPUTFILE INPUTFILES');
|
209 |
-
$this->stderr('Extracts and replaces strings, which cannot be gettexted');
|
210 |
-
$this->stderr('Commands:');
|
211 |
-
$this->stderr(' extract POTFILE PHPFILES appends the strings to POTFILE');
|
212 |
-
$this->stderr(' replace MOFILE PHPFILES replaces strings in PHPFILES with translations from MOFILE');
|
213 |
-
}
|
214 |
-
|
215 |
-
function cli() {
|
216 |
-
global $argv, $commands;
|
217 |
-
if (count($argv) < 4 || !in_array($argv[1], array_keys($this->commands))) {
|
218 |
-
$this->usage();
|
219 |
-
exit(1);
|
220 |
-
}
|
221 |
-
call_user_func_array(array(&$this, $this->commands[$argv[1]]), array_slice($argv, 2));
|
222 |
-
}
|
223 |
-
}
|
224 |
-
|
225 |
-
// run the CLI only if the file
|
226 |
-
// wasn't included
|
227 |
-
$included_files = get_included_files();
|
228 |
-
if ($included_files[0] == __FILE__) {
|
229 |
-
error_reporting(E_ALL);
|
230 |
-
$not_gettexted = new NotGettexted;
|
231 |
-
$not_gettexted->cli();
|
232 |
-
}
|
233 |
-
|
234 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/pomo/entry.php
DELETED
@@ -1,78 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Contains Translation_Entry class
|
4 |
-
*
|
5 |
-
* @version $Id: entry.php 718 2012-10-31 00:32:02Z nbachiyski $
|
6 |
-
* @package pomo
|
7 |
-
* @subpackage entry
|
8 |
-
*/
|
9 |
-
|
10 |
-
if ( !class_exists( 'Translation_Entry' ) ):
|
11 |
-
/**
|
12 |
-
* Translation_Entry class encapsulates a translatable string
|
13 |
-
*/
|
14 |
-
class Translation_Entry {
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Whether the entry contains a string and its plural form, default is false
|
18 |
-
*
|
19 |
-
* @var boolean
|
20 |
-
*/
|
21 |
-
var $is_plural = false;
|
22 |
-
|
23 |
-
var $context = null;
|
24 |
-
var $singular = null;
|
25 |
-
var $plural = null;
|
26 |
-
var $translations = array();
|
27 |
-
var $translator_comments = '';
|
28 |
-
var $extracted_comments = '';
|
29 |
-
var $references = array();
|
30 |
-
var $flags = array();
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @param array $args associative array, support following keys:
|
34 |
-
* - singular (string) -- the string to translate, if omitted and empty entry will be created
|
35 |
-
* - plural (string) -- the plural form of the string, setting this will set {@link $is_plural} to true
|
36 |
-
* - translations (array) -- translations of the string and possibly -- its plural forms
|
37 |
-
* - context (string) -- a string differentiating two equal strings used in different contexts
|
38 |
-
* - translator_comments (string) -- comments left by translators
|
39 |
-
* - extracted_comments (string) -- comments left by developers
|
40 |
-
* - references (array) -- places in the code this strings is used, in relative_to_root_path/file.php:linenum form
|
41 |
-
* - flags (array) -- flags like php-format
|
42 |
-
*/
|
43 |
-
function Translation_Entry($args=array()) {
|
44 |
-
// if no singular -- empty object
|
45 |
-
if (!isset($args['singular'])) {
|
46 |
-
return;
|
47 |
-
}
|
48 |
-
// get member variable values from args hash
|
49 |
-
foreach ($args as $varname => $value) {
|
50 |
-
$this->$varname = $value;
|
51 |
-
}
|
52 |
-
if (isset($args['plural'])) $this->is_plural = true;
|
53 |
-
if (!is_array($this->translations)) $this->translations = array();
|
54 |
-
if (!is_array($this->references)) $this->references = array();
|
55 |
-
if (!is_array($this->flags)) $this->flags = array();
|
56 |
-
}
|
57 |
-
|
58 |
-
/**
|
59 |
-
* Generates a unique key for this entry
|
60 |
-
*
|
61 |
-
* @return string|bool the key or false if the entry is empty
|
62 |
-
*/
|
63 |
-
function key() {
|
64 |
-
if (is_null($this->singular)) return false;
|
65 |
-
// prepend context and EOT, like in MO files
|
66 |
-
return is_null($this->context)? $this->singular : $this->context.chr(4).$this->singular;
|
67 |
-
}
|
68 |
-
|
69 |
-
function merge_with(&$other) {
|
70 |
-
$this->flags = array_unique( array_merge( $this->flags, $other->flags ) );
|
71 |
-
$this->references = array_unique( array_merge( $this->references, $other->references ) );
|
72 |
-
if ( $this->extracted_comments != $other->extracted_comments ) {
|
73 |
-
$this->extracted_comments .= $other->extracted_comments;
|
74 |
-
}
|
75 |
-
|
76 |
-
}
|
77 |
-
}
|
78 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/pomo/mo.php
DELETED
@@ -1,258 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Class for working with MO files
|
4 |
-
*
|
5 |
-
* @version $Id: mo.php 780 2013-06-19 12:12:28Z markoheijnen $
|
6 |
-
* @package pomo
|
7 |
-
* @subpackage mo
|
8 |
-
*/
|
9 |
-
|
10 |
-
require_once dirname(__FILE__) . '/translations.php';
|
11 |
-
require_once dirname(__FILE__) . '/streams.php';
|
12 |
-
|
13 |
-
if ( !class_exists( 'MO' ) ):
|
14 |
-
class MO extends Gettext_Translations {
|
15 |
-
|
16 |
-
var $_nplurals = 2;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Fills up with the entries from MO file $filename
|
20 |
-
*
|
21 |
-
* @param string $filename MO file to load
|
22 |
-
*/
|
23 |
-
function import_from_file($filename) {
|
24 |
-
$reader = new POMO_FileReader($filename);
|
25 |
-
if (!$reader->is_resource())
|
26 |
-
return false;
|
27 |
-
return $this->import_from_reader($reader);
|
28 |
-
}
|
29 |
-
|
30 |
-
function export_to_file($filename) {
|
31 |
-
$fh = fopen($filename, 'wb');
|
32 |
-
if ( !$fh ) return false;
|
33 |
-
$res = $this->export_to_file_handle( $fh );
|
34 |
-
fclose($fh);
|
35 |
-
return $res;
|
36 |
-
}
|
37 |
-
|
38 |
-
function export() {
|
39 |
-
$tmp_fh = fopen("php://temp", 'r+');
|
40 |
-
if ( !$tmp_fh ) return false;
|
41 |
-
$this->export_to_file_handle( $tmp_fh );
|
42 |
-
rewind( $tmp_fh );
|
43 |
-
return stream_get_contents( $tmp_fh );
|
44 |
-
}
|
45 |
-
|
46 |
-
function is_entry_good_for_export( $entry ) {
|
47 |
-
if ( empty( $entry->translations ) ) {
|
48 |
-
return false;
|
49 |
-
}
|
50 |
-
|
51 |
-
if ( !array_filter( $entry->translations ) ) {
|
52 |
-
return false;
|
53 |
-
}
|
54 |
-
|
55 |
-
return true;
|
56 |
-
}
|
57 |
-
|
58 |
-
function export_to_file_handle($fh) {
|
59 |
-
$entries = array_filter( $this->entries, array( $this, 'is_entry_good_for_export' ) );
|
60 |
-
ksort($entries);
|
61 |
-
$magic = 0x950412de;
|
62 |
-
$revision = 0;
|
63 |
-
$total = count($entries) + 1; // all the headers are one entry
|
64 |
-
$originals_lenghts_addr = 28;
|
65 |
-
$translations_lenghts_addr = $originals_lenghts_addr + 8 * $total;
|
66 |
-
$size_of_hash = 0;
|
67 |
-
$hash_addr = $translations_lenghts_addr + 8 * $total;
|
68 |
-
$current_addr = $hash_addr;
|
69 |
-
fwrite($fh, pack('V*', $magic, $revision, $total, $originals_lenghts_addr,
|
70 |
-
$translations_lenghts_addr, $size_of_hash, $hash_addr));
|
71 |
-
fseek($fh, $originals_lenghts_addr);
|
72 |
-
|
73 |
-
// headers' msgid is an empty string
|
74 |
-
fwrite($fh, pack('VV', 0, $current_addr));
|
75 |
-
$current_addr++;
|
76 |
-
$originals_table = chr(0);
|
77 |
-
|
78 |
-
foreach($entries as $entry) {
|
79 |
-
$originals_table .= $this->export_original($entry) . chr(0);
|
80 |
-
$length = strlen($this->export_original($entry));
|
81 |
-
fwrite($fh, pack('VV', $length, $current_addr));
|
82 |
-
$current_addr += $length + 1; // account for the NULL byte after
|
83 |
-
}
|
84 |
-
|
85 |
-
$exported_headers = $this->export_headers();
|
86 |
-
fwrite($fh, pack('VV', strlen($exported_headers), $current_addr));
|
87 |
-
$current_addr += strlen($exported_headers) + 1;
|
88 |
-
$translations_table = $exported_headers . chr(0);
|
89 |
-
|
90 |
-
foreach($entries as $entry) {
|
91 |
-
$translations_table .= $this->export_translations($entry) . chr(0);
|
92 |
-
$length = strlen($this->export_translations($entry));
|
93 |
-
fwrite($fh, pack('VV', $length, $current_addr));
|
94 |
-
$current_addr += $length + 1;
|
95 |
-
}
|
96 |
-
|
97 |
-
fwrite($fh, $originals_table);
|
98 |
-
fwrite($fh, $translations_table);
|
99 |
-
return true;
|
100 |
-
}
|
101 |
-
|
102 |
-
function export_original($entry) {
|
103 |
-
//TODO: warnings for control characters
|
104 |
-
$exported = $entry->singular;
|
105 |
-
if ($entry->is_plural) $exported .= chr(0).$entry->plural;
|
106 |
-
if (!is_null($entry->context)) $exported = $entry->context . chr(4) . $exported;
|
107 |
-
return $exported;
|
108 |
-
}
|
109 |
-
|
110 |
-
function export_translations($entry) {
|
111 |
-
//TODO: warnings for control characters
|
112 |
-
return implode(chr(0), $entry->translations);
|
113 |
-
}
|
114 |
-
|
115 |
-
function export_headers() {
|
116 |
-
$exported = '';
|
117 |
-
foreach($this->headers as $header => $value) {
|
118 |
-
$exported.= "$header: $value\n";
|
119 |
-
}
|
120 |
-
return $exported;
|
121 |
-
}
|
122 |
-
|
123 |
-
function get_byteorder($magic) {
|
124 |
-
// The magic is 0x950412de
|
125 |
-
|
126 |
-
// bug in PHP 5.0.2, see https://savannah.nongnu.org/bugs/?func=detailitem&item_id=10565
|
127 |
-
$magic_little = (int) - 1794895138;
|
128 |
-
$magic_little_64 = (int) 2500072158;
|
129 |
-
// 0xde120495
|
130 |
-
$magic_big = ((int) - 569244523) & 0xFFFFFFFF;
|
131 |
-
if ($magic_little == $magic || $magic_little_64 == $magic) {
|
132 |
-
return 'little';
|
133 |
-
} else if ($magic_big == $magic) {
|
134 |
-
return 'big';
|
135 |
-
} else {
|
136 |
-
return false;
|
137 |
-
}
|
138 |
-
}
|
139 |
-
|
140 |
-
function import_from_reader($reader) {
|
141 |
-
$endian_string = MO::get_byteorder($reader->readint32());
|
142 |
-
if (false === $endian_string) {
|
143 |
-
return false;
|
144 |
-
}
|
145 |
-
$reader->setEndian($endian_string);
|
146 |
-
|
147 |
-
$endian = ('big' == $endian_string)? 'N' : 'V';
|
148 |
-
|
149 |
-
$header = $reader->read(24);
|
150 |
-
if ($reader->strlen($header) != 24)
|
151 |
-
return false;
|
152 |
-
|
153 |
-
// parse header
|
154 |
-
$header = unpack("{$endian}revision/{$endian}total/{$endian}originals_lenghts_addr/{$endian}translations_lenghts_addr/{$endian}hash_length/{$endian}hash_addr", $header);
|
155 |
-
if (!is_array($header))
|
156 |
-
return false;
|
157 |
-
|
158 |
-
extract( $header );
|
159 |
-
|
160 |
-
// support revision 0 of MO format specs, only
|
161 |
-
if ($revision != 0)
|
162 |
-
return false;
|
163 |
-
|
164 |
-
// seek to data blocks
|
165 |
-
$reader->seekto($originals_lenghts_addr);
|
166 |
-
|
167 |
-
// read originals' indices
|
168 |
-
$originals_lengths_length = $translations_lenghts_addr - $originals_lenghts_addr;
|
169 |
-
if ( $originals_lengths_length != $total * 8 )
|
170 |
-
return false;
|
171 |
-
|
172 |
-
$originals = $reader->read($originals_lengths_length);
|
173 |
-
if ( $reader->strlen( $originals ) != $originals_lengths_length )
|
174 |
-
return false;
|
175 |
-
|
176 |
-
// read translations' indices
|
177 |
-
$translations_lenghts_length = $hash_addr - $translations_lenghts_addr;
|
178 |
-
if ( $translations_lenghts_length != $total * 8 )
|
179 |
-
return false;
|
180 |
-
|
181 |
-
$translations = $reader->read($translations_lenghts_length);
|
182 |
-
if ( $reader->strlen( $translations ) != $translations_lenghts_length )
|
183 |
-
return false;
|
184 |
-
|
185 |
-
// transform raw data into set of indices
|
186 |
-
$originals = $reader->str_split( $originals, 8 );
|
187 |
-
$translations = $reader->str_split( $translations, 8 );
|
188 |
-
|
189 |
-
// skip hash table
|
190 |
-
$strings_addr = $hash_addr + $hash_length * 4;
|
191 |
-
|
192 |
-
$reader->seekto($strings_addr);
|
193 |
-
|
194 |
-
$strings = $reader->read_all();
|
195 |
-
$reader->close();
|
196 |
-
|
197 |
-
for ( $i = 0; $i < $total; $i++ ) {
|
198 |
-
$o = unpack( "{$endian}length/{$endian}pos", $originals[$i] );
|
199 |
-
$t = unpack( "{$endian}length/{$endian}pos", $translations[$i] );
|
200 |
-
if ( !$o || !$t ) return false;
|
201 |
-
|
202 |
-
// adjust offset due to reading strings to separate space before
|
203 |
-
$o['pos'] -= $strings_addr;
|
204 |
-
$t['pos'] -= $strings_addr;
|
205 |
-
|
206 |
-
$original = $reader->substr( $strings, $o['pos'], $o['length'] );
|
207 |
-
$translation = $reader->substr( $strings, $t['pos'], $t['length'] );
|
208 |
-
|
209 |
-
if ('' === $original) {
|
210 |
-
$headers = $this->make_headers($translation);
|
211 |
-
$this->set_headers($headers);
|
212 |
-
} else {
|
213 |
-
$entry = &$this->make_entry($original, $translation);
|
214 |
-
$this->entries[$entry->key()] = &$entry;
|
215 |
-
}
|
216 |
-
}
|
217 |
-
return true;
|
218 |
-
}
|
219 |
-
|
220 |
-
/**
|
221 |
-
* Build a Translation_Entry from original string and translation strings,
|
222 |
-
* found in a MO file
|
223 |
-
*
|
224 |
-
* @static
|
225 |
-
* @param string $original original string to translate from MO file. Might contain
|
226 |
-
* 0x04 as context separator or 0x00 as singular/plural separator
|
227 |
-
* @param string $translation translation string from MO file. Might contain
|
228 |
-
* 0x00 as a plural translations separator
|
229 |
-
*/
|
230 |
-
function &make_entry($original, $translation) {
|
231 |
-
$entry = new Translation_Entry();
|
232 |
-
// look for context
|
233 |
-
$parts = explode(chr(4), $original);
|
234 |
-
if (isset($parts[1])) {
|
235 |
-
$original = $parts[1];
|
236 |
-
$entry->context = $parts[0];
|
237 |
-
}
|
238 |
-
// look for plural original
|
239 |
-
$parts = explode(chr(0), $original);
|
240 |
-
$entry->singular = $parts[0];
|
241 |
-
if (isset($parts[1])) {
|
242 |
-
$entry->is_plural = true;
|
243 |
-
$entry->plural = $parts[1];
|
244 |
-
}
|
245 |
-
// plural translations are also separated by \0
|
246 |
-
$entry->translations = explode(chr(0), $translation);
|
247 |
-
return $entry;
|
248 |
-
}
|
249 |
-
|
250 |
-
function select_plural_form($count) {
|
251 |
-
return $this->gettext_select_plural_form($count);
|
252 |
-
}
|
253 |
-
|
254 |
-
function get_plural_forms_count() {
|
255 |
-
return $this->_nplurals;
|
256 |
-
}
|
257 |
-
}
|
258 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/pomo/po.php
DELETED
@@ -1,385 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Class for working with PO files
|
4 |
-
*
|
5 |
-
* @version $Id: po.php 812 2013-10-18 17:34:16Z markoheijnen $
|
6 |
-
* @package pomo
|
7 |
-
* @subpackage po
|
8 |
-
*/
|
9 |
-
|
10 |
-
require_once dirname(__FILE__) . '/translations.php';
|
11 |
-
|
12 |
-
define('PO_MAX_LINE_LEN', 79);
|
13 |
-
|
14 |
-
ini_set('auto_detect_line_endings', 1);
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Routines for working with PO files
|
18 |
-
*/
|
19 |
-
if ( !class_exists( 'PO' ) ):
|
20 |
-
class PO extends Gettext_Translations {
|
21 |
-
|
22 |
-
var $comments_before_headers = '';
|
23 |
-
|
24 |
-
/**
|
25 |
-
* Exports headers to a PO entry
|
26 |
-
*
|
27 |
-
* @return string msgid/msgstr PO entry for this PO file headers, doesn't contain newline at the end
|
28 |
-
*/
|
29 |
-
function export_headers() {
|
30 |
-
$header_string = '';
|
31 |
-
foreach($this->headers as $header => $value) {
|
32 |
-
$header_string.= "$header: $value\n";
|
33 |
-
}
|
34 |
-
$poified = PO::poify($header_string);
|
35 |
-
if ($this->comments_before_headers)
|
36 |
-
$before_headers = $this->prepend_each_line(rtrim($this->comments_before_headers)."\n", '# ');
|
37 |
-
else
|
38 |
-
$before_headers = '';
|
39 |
-
return rtrim("{$before_headers}msgid \"\"\nmsgstr $poified");
|
40 |
-
}
|
41 |
-
|
42 |
-
/**
|
43 |
-
* Exports all entries to PO format
|
44 |
-
*
|
45 |
-
* @return string sequence of mgsgid/msgstr PO strings, doesn't containt newline at the end
|
46 |
-
*/
|
47 |
-
function export_entries() {
|
48 |
-
//TODO sorting
|
49 |
-
return implode("\n\n", array_map(array('PO', 'export_entry'), $this->entries));
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Exports the whole PO file as a string
|
54 |
-
*
|
55 |
-
* @param bool $include_headers whether to include the headers in the export
|
56 |
-
* @return string ready for inclusion in PO file string for headers and all the enrtries
|
57 |
-
*/
|
58 |
-
function export($include_headers = true) {
|
59 |
-
$res = '';
|
60 |
-
if ($include_headers) {
|
61 |
-
$res .= $this->export_headers();
|
62 |
-
$res .= "\n\n";
|
63 |
-
}
|
64 |
-
$res .= $this->export_entries();
|
65 |
-
return $res;
|
66 |
-
}
|
67 |
-
|
68 |
-
/**
|
69 |
-
* Same as {@link export}, but writes the result to a file
|
70 |
-
*
|
71 |
-
* @param string $filename where to write the PO string
|
72 |
-
* @param bool $include_headers whether to include tje headers in the export
|
73 |
-
* @return bool true on success, false on error
|
74 |
-
*/
|
75 |
-
function export_to_file($filename, $include_headers = true) {
|
76 |
-
$fh = fopen($filename, 'w');
|
77 |
-
if (false === $fh) return false;
|
78 |
-
$export = $this->export($include_headers);
|
79 |
-
$res = fwrite($fh, $export);
|
80 |
-
if (false === $res) return false;
|
81 |
-
return fclose($fh);
|
82 |
-
}
|
83 |
-
|
84 |
-
/**
|
85 |
-
* Text to include as a comment before the start of the PO contents
|
86 |
-
*
|
87 |
-
* Doesn't need to include # in the beginning of lines, these are added automatically
|
88 |
-
*/
|
89 |
-
function set_comment_before_headers( $text ) {
|
90 |
-
$this->comments_before_headers = $text;
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* Formats a string in PO-style
|
95 |
-
*
|
96 |
-
* @static
|
97 |
-
* @param string $string the string to format
|
98 |
-
* @return string the poified string
|
99 |
-
*/
|
100 |
-
public static function poify($string) {
|
101 |
-
$quote = '"';
|
102 |
-
$slash = '\\';
|
103 |
-
$newline = "\n";
|
104 |
-
|
105 |
-
$replaces = array(
|
106 |
-
"$slash" => "$slash$slash",
|
107 |
-
"$quote" => "$slash$quote",
|
108 |
-
"\t" => '\t',
|
109 |
-
);
|
110 |
-
|
111 |
-
$string = str_replace(array_keys($replaces), array_values($replaces), $string);
|
112 |
-
|
113 |
-
$po = $quote.implode("${slash}n$quote$newline$quote", explode($newline, $string)).$quote;
|
114 |
-
// add empty string on first line for readbility
|
115 |
-
if (false !== strpos($string, $newline) &&
|
116 |
-
(substr_count($string, $newline) > 1 || !($newline === substr($string, -strlen($newline))))) {
|
117 |
-
$po = "$quote$quote$newline$po";
|
118 |
-
}
|
119 |
-
// remove empty strings
|
120 |
-
$po = str_replace("$newline$quote$quote", '', $po);
|
121 |
-
return $po;
|
122 |
-
}
|
123 |
-
|
124 |
-
/**
|
125 |
-
* Gives back the original string from a PO-formatted string
|
126 |
-
*
|
127 |
-
* @static
|
128 |
-
* @param string $string PO-formatted string
|
129 |
-
* @return string enascaped string
|
130 |
-
*/
|
131 |
-
public static function unpoify($string) {
|
132 |
-
$escapes = array('t' => "\t", 'n' => "\n", '\\' => '\\');
|
133 |
-
$lines = array_map('trim', explode("\n", $string));
|
134 |
-
$lines = array_map(array('PO', 'trim_quotes'), $lines);
|
135 |
-
$unpoified = '';
|
136 |
-
$previous_is_backslash = false;
|
137 |
-
foreach($lines as $line) {
|
138 |
-
preg_match_all('/./u', $line, $chars);
|
139 |
-
$chars = $chars[0];
|
140 |
-
foreach($chars as $char) {
|
141 |
-
if (!$previous_is_backslash) {
|
142 |
-
if ('\\' == $char)
|
143 |
-
$previous_is_backslash = true;
|
144 |
-
else
|
145 |
-
$unpoified .= $char;
|
146 |
-
} else {
|
147 |
-
$previous_is_backslash = false;
|
148 |
-
$unpoified .= isset($escapes[$char])? $escapes[$char] : $char;
|
149 |
-
}
|
150 |
-
}
|
151 |
-
}
|
152 |
-
return $unpoified;
|
153 |
-
}
|
154 |
-
|
155 |
-
/**
|
156 |
-
* Inserts $with in the beginning of every new line of $string and
|
157 |
-
* returns the modified string
|
158 |
-
*
|
159 |
-
* @static
|
160 |
-
* @param string $string prepend lines in this string
|
161 |
-
* @param string $with prepend lines with this string
|
162 |
-
*/
|
163 |
-
public static function prepend_each_line($string, $with) {
|
164 |
-
$php_with = var_export($with, true);
|
165 |
-
$lines = explode("\n", $string);
|
166 |
-
// do not prepend the string on the last empty line, artefact by explode
|
167 |
-
if ("\n" == substr($string, -1)) unset($lines[count($lines) - 1]);
|
168 |
-
$res = implode("\n", array_map(create_function('$x', "return $php_with.\$x;"), $lines));
|
169 |
-
// give back the empty line, we ignored above
|
170 |
-
if ("\n" == substr($string, -1)) $res .= "\n";
|
171 |
-
return $res;
|
172 |
-
}
|
173 |
-
|
174 |
-
/**
|
175 |
-
* Prepare a text as a comment -- wraps the lines and prepends #
|
176 |
-
* and a special character to each line
|
177 |
-
*
|
178 |
-
* @access private
|
179 |
-
* @param string $text the comment text
|
180 |
-
* @param string $char character to denote a special PO comment,
|
181 |
-
* like :, default is a space
|
182 |
-
*/
|
183 |
-
public static function comment_block($text, $char=' ') {
|
184 |
-
$text = wordwrap($text, PO_MAX_LINE_LEN - 3);
|
185 |
-
return PO::prepend_each_line($text, "#$char ");
|
186 |
-
}
|
187 |
-
|
188 |
-
/**
|
189 |
-
* Builds a string from the entry for inclusion in PO file
|
190 |
-
*
|
191 |
-
* @static
|
192 |
-
* @param object &$entry the entry to convert to po string
|
193 |
-
* @return string|bool PO-style formatted string for the entry or
|
194 |
-
* false if the entry is empty
|
195 |
-
*/
|
196 |
-
public static function export_entry(&$entry) {
|
197 |
-
if (is_null($entry->singular)) return false;
|
198 |
-
$po = array();
|
199 |
-
if (!empty($entry->translator_comments)) $po[] = PO::comment_block($entry->translator_comments);
|
200 |
-
if (!empty($entry->extracted_comments)) $po[] = PO::comment_block($entry->extracted_comments, '.');
|
201 |
-
if (!empty($entry->references)) $po[] = PO::comment_block(implode(' ', $entry->references), ':');
|
202 |
-
if (!empty($entry->flags)) $po[] = PO::comment_block(implode(", ", $entry->flags), ',');
|
203 |
-
if (!is_null($entry->context)) $po[] = 'msgctxt '.PO::poify($entry->context);
|
204 |
-
$po[] = 'msgid '.PO::poify($entry->singular);
|
205 |
-
if (!$entry->is_plural) {
|
206 |
-
$translation = empty($entry->translations)? '' : $entry->translations[0];
|
207 |
-
$po[] = 'msgstr '.PO::poify($translation);
|
208 |
-
} else {
|
209 |
-
$po[] = 'msgid_plural '.PO::poify($entry->plural);
|
210 |
-
$translations = empty($entry->translations)? array('', '') : $entry->translations;
|
211 |
-
foreach($translations as $i => $translation) {
|
212 |
-
$po[] = "msgstr[$i] ".PO::poify($translation);
|
213 |
-
}
|
214 |
-
}
|
215 |
-
return implode("\n", $po);
|
216 |
-
}
|
217 |
-
|
218 |
-
function import_from_file($filename) {
|
219 |
-
$f = fopen($filename, 'r');
|
220 |
-
if (!$f) return false;
|
221 |
-
$lineno = 0;
|
222 |
-
while (true) {
|
223 |
-
$res = $this->read_entry($f, $lineno);
|
224 |
-
if (!$res) break;
|
225 |
-
if ($res['entry']->singular == '') {
|
226 |
-
$headers = $this->make_headers($res['entry']->translations[0]);
|
227 |
-
$this->set_headers($headers);
|
228 |
-
} else {
|
229 |
-
$this->add_entry($res['entry']);
|
230 |
-
}
|
231 |
-
}
|
232 |
-
PO::read_line($f, 'clear');
|
233 |
-
if ( false === $res ) {
|
234 |
-
return false;
|
235 |
-
}
|
236 |
-
if ( ! $this->headers && ! $this->entries ) {
|
237 |
-
return false;
|
238 |
-
}
|
239 |
-
return true;
|
240 |
-
}
|
241 |
-
|
242 |
-
function read_entry($f, $lineno = 0) {
|
243 |
-
$entry = new Translation_Entry();
|
244 |
-
// where were we in the last step
|
245 |
-
// can be: comment, msgctxt, msgid, msgid_plural, msgstr, msgstr_plural
|
246 |
-
$context = '';
|
247 |
-
$msgstr_index = 0;
|
248 |
-
$is_final = create_function('$context', 'return $context == "msgstr" || $context == "msgstr_plural";');
|
249 |
-
while (true) {
|
250 |
-
$lineno++;
|
251 |
-
$line = PO::read_line($f);
|
252 |
-
if (!$line) {
|
253 |
-
if (feof($f)) {
|
254 |
-
if ($is_final($context))
|
255 |
-
break;
|
256 |
-
elseif (!$context) // we haven't read a line and eof came
|
257 |
-
return null;
|
258 |
-
else
|
259 |
-
return false;
|
260 |
-
} else {
|
261 |
-
return false;
|
262 |
-
}
|
263 |
-
}
|
264 |
-
if ($line == "\n") continue;
|
265 |
-
$line = trim($line);
|
266 |
-
if (preg_match('/^#/', $line, $m)) {
|
267 |
-
// the comment is the start of a new entry
|
268 |
-
if ($is_final($context)) {
|
269 |
-
PO::read_line($f, 'put-back');
|
270 |
-
$lineno--;
|
271 |
-
break;
|
272 |
-
}
|
273 |
-
// comments have to be at the beginning
|
274 |
-
if ($context && $context != 'comment') {
|
275 |
-
return false;
|
276 |
-
}
|
277 |
-
// add comment
|
278 |
-
$this->add_comment_to_entry($entry, $line);
|
279 |
-
} elseif (preg_match('/^msgctxt\s+(".*")/', $line, $m)) {
|
280 |
-
if ($is_final($context)) {
|
281 |
-
PO::read_line($f, 'put-back');
|
282 |
-
$lineno--;
|
283 |
-
break;
|
284 |
-
}
|
285 |
-
if ($context && $context != 'comment') {
|
286 |
-
return false;
|
287 |
-
}
|
288 |
-
$context = 'msgctxt';
|
289 |
-
$entry->context .= PO::unpoify($m[1]);
|
290 |
-
} elseif (preg_match('/^msgid\s+(".*")/', $line, $m)) {
|
291 |
-
if ($is_final($context)) {
|
292 |
-
PO::read_line($f, 'put-back');
|
293 |
-
$lineno--;
|
294 |
-
break;
|
295 |
-
}
|
296 |
-
if ($context && $context != 'msgctxt' && $context != 'comment') {
|
297 |
-
return false;
|
298 |
-
}
|
299 |
-
$context = 'msgid';
|
300 |
-
$entry->singular .= PO::unpoify($m[1]);
|
301 |
-
} elseif (preg_match('/^msgid_plural\s+(".*")/', $line, $m)) {
|
302 |
-
if ($context != 'msgid') {
|
303 |
-
return false;
|
304 |
-
}
|
305 |
-
$context = 'msgid_plural';
|
306 |
-
$entry->is_plural = true;
|
307 |
-
$entry->plural .= PO::unpoify($m[1]);
|
308 |
-
} elseif (preg_match('/^msgstr\s+(".*")/', $line, $m)) {
|
309 |
-
if ($context != 'msgid') {
|
310 |
-
return false;
|
311 |
-
}
|
312 |
-
$context = 'msgstr';
|
313 |
-
$entry->translations = array(PO::unpoify($m[1]));
|
314 |
-
} elseif (preg_match('/^msgstr\[(\d+)\]\s+(".*")/', $line, $m)) {
|
315 |
-
if ($context != 'msgid_plural' && $context != 'msgstr_plural') {
|
316 |
-
return false;
|
317 |
-
}
|
318 |
-
$context = 'msgstr_plural';
|
319 |
-
$msgstr_index = $m[1];
|
320 |
-
$entry->translations[$m[1]] = PO::unpoify($m[2]);
|
321 |
-
} elseif (preg_match('/^".*"$/', $line)) {
|
322 |
-
$unpoified = PO::unpoify($line);
|
323 |
-
switch ($context) {
|
324 |
-
case 'msgid':
|
325 |
-
$entry->singular .= $unpoified; break;
|
326 |
-
case 'msgctxt':
|
327 |
-
$entry->context .= $unpoified; break;
|
328 |
-
case 'msgid_plural':
|
329 |
-
$entry->plural .= $unpoified; break;
|
330 |
-
case 'msgstr':
|
331 |
-
$entry->translations[0] .= $unpoified; break;
|
332 |
-
case 'msgstr_plural':
|
333 |
-
$entry->translations[$msgstr_index] .= $unpoified; break;
|
334 |
-
default:
|
335 |
-
return false;
|
336 |
-
}
|
337 |
-
} else {
|
338 |
-
return false;
|
339 |
-
}
|
340 |
-
}
|
341 |
-
if (array() == array_filter($entry->translations, create_function('$t', 'return $t || "0" === $t;'))) {
|
342 |
-
$entry->translations = array();
|
343 |
-
}
|
344 |
-
return array('entry' => $entry, 'lineno' => $lineno);
|
345 |
-
}
|
346 |
-
|
347 |
-
function read_line($f, $action = 'read') {
|
348 |
-
static $last_line = '';
|
349 |
-
static $use_last_line = false;
|
350 |
-
if ('clear' == $action) {
|
351 |
-
$last_line = '';
|
352 |
-
return true;
|
353 |
-
}
|
354 |
-
if ('put-back' == $action) {
|
355 |
-
$use_last_line = true;
|
356 |
-
return true;
|
357 |
-
}
|
358 |
-
$line = $use_last_line? $last_line : fgets($f);
|
359 |
-
$line = ( "\r\n" == substr( $line, -2 ) ) ? rtrim( $line, "\r\n" ) . "\n" : $line;
|
360 |
-
$last_line = $line;
|
361 |
-
$use_last_line = false;
|
362 |
-
return $line;
|
363 |
-
}
|
364 |
-
|
365 |
-
function add_comment_to_entry(&$entry, $po_comment_line) {
|
366 |
-
$first_two = substr($po_comment_line, 0, 2);
|
367 |
-
$comment = trim(substr($po_comment_line, 2));
|
368 |
-
if ('#:' == $first_two) {
|
369 |
-
$entry->references = array_merge($entry->references, preg_split('/\s+/', $comment));
|
370 |
-
} elseif ('#.' == $first_two) {
|
371 |
-
$entry->extracted_comments = trim($entry->extracted_comments . "\n" . $comment);
|
372 |
-
} elseif ('#,' == $first_two) {
|
373 |
-
$entry->flags = array_merge($entry->flags, preg_split('/,\s*/', $comment));
|
374 |
-
} else {
|
375 |
-
$entry->translator_comments = trim($entry->translator_comments . "\n" . $comment);
|
376 |
-
}
|
377 |
-
}
|
378 |
-
|
379 |
-
public static function trim_quotes($s) {
|
380 |
-
if ( substr($s, 0, 1) == '"') $s = substr($s, 1);
|
381 |
-
if ( substr($s, -1, 1) == '"') $s = substr($s, 0, -1);
|
382 |
-
return $s;
|
383 |
-
}
|
384 |
-
}
|
385 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/pomo/streams.php
DELETED
@@ -1,209 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Classes, which help reading streams of data from files.
|
4 |
-
* Based on the classes from Danilo Segan <danilo@kvota.net>
|
5 |
-
*
|
6 |
-
* @version $Id: streams.php 718 2012-10-31 00:32:02Z nbachiyski $
|
7 |
-
* @package pomo
|
8 |
-
* @subpackage streams
|
9 |
-
*/
|
10 |
-
|
11 |
-
if ( !class_exists( 'POMO_Reader' ) ):
|
12 |
-
class POMO_Reader {
|
13 |
-
|
14 |
-
var $endian = 'little';
|
15 |
-
var $_post = '';
|
16 |
-
|
17 |
-
function POMO_Reader() {
|
18 |
-
$this->is_overloaded = ((ini_get("mbstring.func_overload") & 2) != 0) && function_exists('mb_substr');
|
19 |
-
$this->_pos = 0;
|
20 |
-
}
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Sets the endianness of the file.
|
24 |
-
*
|
25 |
-
* @param $endian string 'big' or 'little'
|
26 |
-
*/
|
27 |
-
function setEndian($endian) {
|
28 |
-
$this->endian = $endian;
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* Reads a 32bit Integer from the Stream
|
33 |
-
*
|
34 |
-
* @return mixed The integer, corresponding to the next 32 bits from
|
35 |
-
* the stream of false if there are not enough bytes or on error
|
36 |
-
*/
|
37 |
-
function readint32() {
|
38 |
-
$bytes = $this->read(4);
|
39 |
-
if (4 != $this->strlen($bytes))
|
40 |
-
return false;
|
41 |
-
$endian_letter = ('big' == $this->endian)? 'N' : 'V';
|
42 |
-
$int = unpack($endian_letter, $bytes);
|
43 |
-
return array_shift($int);
|
44 |
-
}
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Reads an array of 32-bit Integers from the Stream
|
48 |
-
*
|
49 |
-
* @param integer count How many elements should be read
|
50 |
-
* @return mixed Array of integers or false if there isn't
|
51 |
-
* enough data or on error
|
52 |
-
*/
|
53 |
-
function readint32array($count) {
|
54 |
-
$bytes = $this->read(4 * $count);
|
55 |
-
if (4*$count != $this->strlen($bytes))
|
56 |
-
return false;
|
57 |
-
$endian_letter = ('big' == $this->endian)? 'N' : 'V';
|
58 |
-
return unpack($endian_letter.$count, $bytes);
|
59 |
-
}
|
60 |
-
|
61 |
-
|
62 |
-
function substr($string, $start, $length) {
|
63 |
-
if ($this->is_overloaded) {
|
64 |
-
return mb_substr($string, $start, $length, 'ascii');
|
65 |
-
} else {
|
66 |
-
return substr($string, $start, $length);
|
67 |
-
}
|
68 |
-
}
|
69 |
-
|
70 |
-
function strlen($string) {
|
71 |
-
if ($this->is_overloaded) {
|
72 |
-
return mb_strlen($string, 'ascii');
|
73 |
-
} else {
|
74 |
-
return strlen($string);
|
75 |
-
}
|
76 |
-
}
|
77 |
-
|
78 |
-
function str_split($string, $chunk_size) {
|
79 |
-
if (!function_exists('str_split')) {
|
80 |
-
$length = $this->strlen($string);
|
81 |
-
$out = array();
|
82 |
-
for ($i = 0; $i < $length; $i += $chunk_size)
|
83 |
-
$out[] = $this->substr($string, $i, $chunk_size);
|
84 |
-
return $out;
|
85 |
-
} else {
|
86 |
-
return str_split( $string, $chunk_size );
|
87 |
-
}
|
88 |
-
}
|
89 |
-
|
90 |
-
|
91 |
-
function pos() {
|
92 |
-
return $this->_pos;
|
93 |
-
}
|
94 |
-
|
95 |
-
function is_resource() {
|
96 |
-
return true;
|
97 |
-
}
|
98 |
-
|
99 |
-
function close() {
|
100 |
-
return true;
|
101 |
-
}
|
102 |
-
}
|
103 |
-
endif;
|
104 |
-
|
105 |
-
if ( !class_exists( 'POMO_FileReader' ) ):
|
106 |
-
class POMO_FileReader extends POMO_Reader {
|
107 |
-
function POMO_FileReader($filename) {
|
108 |
-
parent::POMO_Reader();
|
109 |
-
$this->_f = fopen($filename, 'rb');
|
110 |
-
}
|
111 |
-
|
112 |
-
function read($bytes) {
|
113 |
-
return fread($this->_f, $bytes);
|
114 |
-
}
|
115 |
-
|
116 |
-
function seekto($pos) {
|
117 |
-
if ( -1 == fseek($this->_f, $pos, SEEK_SET)) {
|
118 |
-
return false;
|
119 |
-
}
|
120 |
-
$this->_pos = $pos;
|
121 |
-
return true;
|
122 |
-
}
|
123 |
-
|
124 |
-
function is_resource() {
|
125 |
-
return is_resource($this->_f);
|
126 |
-
}
|
127 |
-
|
128 |
-
function feof() {
|
129 |
-
return feof($this->_f);
|
130 |
-
}
|
131 |
-
|
132 |
-
function close() {
|
133 |
-
return fclose($this->_f);
|
134 |
-
}
|
135 |
-
|
136 |
-
function read_all() {
|
137 |
-
$all = '';
|
138 |
-
while ( !$this->feof() )
|
139 |
-
$all .= $this->read(4096);
|
140 |
-
return $all;
|
141 |
-
}
|
142 |
-
}
|
143 |
-
endif;
|
144 |
-
|
145 |
-
if ( !class_exists( 'POMO_StringReader' ) ):
|
146 |
-
/**
|
147 |
-
* Provides file-like methods for manipulating a string instead
|
148 |
-
* of a physical file.
|
149 |
-
*/
|
150 |
-
class POMO_StringReader extends POMO_Reader {
|
151 |
-
|
152 |
-
var $_str = '';
|
153 |
-
|
154 |
-
function POMO_StringReader($str = '') {
|
155 |
-
parent::POMO_Reader();
|
156 |
-
$this->_str = $str;
|
157 |
-
$this->_pos = 0;
|
158 |
-
}
|
159 |
-
|
160 |
-
|
161 |
-
function read($bytes) {
|
162 |
-
$data = $this->substr($this->_str, $this->_pos, $bytes);
|
163 |
-
$this->_pos += $bytes;
|
164 |
-
if ($this->strlen($this->_str) < $this->_pos) $this->_pos = $this->strlen($this->_str);
|
165 |
-
return $data;
|
166 |
-
}
|
167 |
-
|
168 |
-
function seekto($pos) {
|
169 |
-
$this->_pos = $pos;
|
170 |
-
if ($this->strlen($this->_str) < $this->_pos) $this->_pos = $this->strlen($this->_str);
|
171 |
-
return $this->_pos;
|
172 |
-
}
|
173 |
-
|
174 |
-
function length() {
|
175 |
-
return $this->strlen($this->_str);
|
176 |
-
}
|
177 |
-
|
178 |
-
function read_all() {
|
179 |
-
return $this->substr($this->_str, $this->_pos, $this->strlen($this->_str));
|
180 |
-
}
|
181 |
-
|
182 |
-
}
|
183 |
-
endif;
|
184 |
-
|
185 |
-
if ( !class_exists( 'POMO_CachedFileReader' ) ):
|
186 |
-
/**
|
187 |
-
* Reads the contents of the file in the beginning.
|
188 |
-
*/
|
189 |
-
class POMO_CachedFileReader extends POMO_StringReader {
|
190 |
-
function POMO_CachedFileReader($filename) {
|
191 |
-
parent::POMO_StringReader();
|
192 |
-
$this->_str = file_get_contents($filename);
|
193 |
-
if (false === $this->_str)
|
194 |
-
return false;
|
195 |
-
$this->_pos = 0;
|
196 |
-
}
|
197 |
-
}
|
198 |
-
endif;
|
199 |
-
|
200 |
-
if ( !class_exists( 'POMO_CachedIntFileReader' ) ):
|
201 |
-
/**
|
202 |
-
* Reads the contents of the file in the beginning.
|
203 |
-
*/
|
204 |
-
class POMO_CachedIntFileReader extends POMO_CachedFileReader {
|
205 |
-
function POMO_CachedIntFileReader($filename) {
|
206 |
-
parent::POMO_CachedFileReader($filename);
|
207 |
-
}
|
208 |
-
}
|
209 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/pomo/translations.php
DELETED
@@ -1,275 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Class for a set of entries for translation and their associated headers
|
4 |
-
*
|
5 |
-
* @version $Id: translations.php 811 2013-10-18 17:26:21Z markoheijnen $
|
6 |
-
* @package pomo
|
7 |
-
* @subpackage translations
|
8 |
-
*/
|
9 |
-
|
10 |
-
require_once dirname(__FILE__) . '/entry.php';
|
11 |
-
|
12 |
-
if ( !class_exists( 'Translations' ) ):
|
13 |
-
class Translations {
|
14 |
-
var $entries = array();
|
15 |
-
var $headers = array();
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Add entry to the PO structure
|
19 |
-
*
|
20 |
-
* @param object &$entry
|
21 |
-
* @return bool true on success, false if the entry doesn't have a key
|
22 |
-
*/
|
23 |
-
function add_entry($entry) {
|
24 |
-
if (is_array($entry)) {
|
25 |
-
$entry = new Translation_Entry($entry);
|
26 |
-
}
|
27 |
-
$key = $entry->key();
|
28 |
-
if (false === $key) return false;
|
29 |
-
$this->entries[$key] = &$entry;
|
30 |
-
return true;
|
31 |
-
}
|
32 |
-
|
33 |
-
function add_entry_or_merge($entry) {
|
34 |
-
if (is_array($entry)) {
|
35 |
-
$entry = new Translation_Entry($entry);
|
36 |
-
}
|
37 |
-
$key = $entry->key();
|
38 |
-
if (false === $key) return false;
|
39 |
-
if (isset($this->entries[$key]))
|
40 |
-
$this->entries[$key]->merge_with($entry);
|
41 |
-
else
|
42 |
-
$this->entries[$key] = &$entry;
|
43 |
-
return true;
|
44 |
-
}
|
45 |
-
|
46 |
-
/**
|
47 |
-
* Sets $header PO header to $value
|
48 |
-
*
|
49 |
-
* If the header already exists, it will be overwritten
|
50 |
-
*
|
51 |
-
* TODO: this should be out of this class, it is gettext specific
|
52 |
-
*
|
53 |
-
* @param string $header header name, without trailing :
|
54 |
-
* @param string $value header value, without trailing \n
|
55 |
-
*/
|
56 |
-
function set_header($header, $value) {
|
57 |
-
$this->headers[$header] = $value;
|
58 |
-
}
|
59 |
-
|
60 |
-
function set_headers($headers) {
|
61 |
-
foreach($headers as $header => $value) {
|
62 |
-
$this->set_header($header, $value);
|
63 |
-
}
|
64 |
-
}
|
65 |
-
|
66 |
-
function get_header($header) {
|
67 |
-
return isset($this->headers[$header])? $this->headers[$header] : false;
|
68 |
-
}
|
69 |
-
|
70 |
-
function translate_entry(&$entry) {
|
71 |
-
$key = $entry->key();
|
72 |
-
return isset($this->entries[$key])? $this->entries[$key] : false;
|
73 |
-
}
|
74 |
-
|
75 |
-
function translate($singular, $context=null) {
|
76 |
-
$entry = new Translation_Entry(array('singular' => $singular, 'context' => $context));
|
77 |
-
$translated = $this->translate_entry($entry);
|
78 |
-
return ($translated && !empty($translated->translations))? $translated->translations[0] : $singular;
|
79 |
-
}
|
80 |
-
|
81 |
-
/**
|
82 |
-
* Given the number of items, returns the 0-based index of the plural form to use
|
83 |
-
*
|
84 |
-
* Here, in the base Translations class, the common logic for English is implemented:
|
85 |
-
* 0 if there is one element, 1 otherwise
|
86 |
-
*
|
87 |
-
* This function should be overrided by the sub-classes. For example MO/PO can derive the logic
|
88 |
-
* from their headers.
|
89 |
-
*
|
90 |
-
* @param integer $count number of items
|
91 |
-
*/
|
92 |
-
function select_plural_form($count) {
|
93 |
-
return 1 == $count? 0 : 1;
|
94 |
-
}
|
95 |
-
|
96 |
-
function get_plural_forms_count() {
|
97 |
-
return 2;
|
98 |
-
}
|
99 |
-
|
100 |
-
function translate_plural($singular, $plural, $count, $context = null) {
|
101 |
-
$entry = new Translation_Entry(array('singular' => $singular, 'plural' => $plural, 'context' => $context));
|
102 |
-
$translated = $this->translate_entry($entry);
|
103 |
-
$index = $this->select_plural_form($count);
|
104 |
-
$total_plural_forms = $this->get_plural_forms_count();
|
105 |
-
if ($translated && 0 <= $index && $index < $total_plural_forms &&
|
106 |
-
is_array($translated->translations) &&
|
107 |
-
isset($translated->translations[$index]))
|
108 |
-
return $translated->translations[$index];
|
109 |
-
else
|
110 |
-
return 1 == $count? $singular : $plural;
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Merge $other in the current object.
|
115 |
-
*
|
116 |
-
* @param Object &$other Another Translation object, whose translations will be merged in this one
|
117 |
-
* @return void
|
118 |
-
**/
|
119 |
-
function merge_with(&$other) {
|
120 |
-
foreach( $other->entries as $entry ) {
|
121 |
-
$this->entries[$entry->key()] = $entry;
|
122 |
-
}
|
123 |
-
}
|
124 |
-
|
125 |
-
function merge_originals_with(&$other) {
|
126 |
-
foreach( $other->entries as $entry ) {
|
127 |
-
if ( !isset( $this->entries[$entry->key()] ) )
|
128 |
-
$this->entries[$entry->key()] = $entry;
|
129 |
-
else
|
130 |
-
$this->entries[$entry->key()]->merge_with($entry);
|
131 |
-
}
|
132 |
-
}
|
133 |
-
}
|
134 |
-
|
135 |
-
class Gettext_Translations extends Translations {
|
136 |
-
/**
|
137 |
-
* The gettext implementation of select_plural_form.
|
138 |
-
*
|
139 |
-
* It lives in this class, because there are more than one descendand, which will use it and
|
140 |
-
* they can't share it effectively.
|
141 |
-
*
|
142 |
-
*/
|
143 |
-
function gettext_select_plural_form($count) {
|
144 |
-
if (!isset($this->_gettext_select_plural_form) || is_null($this->_gettext_select_plural_form)) {
|
145 |
-
list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
|
146 |
-
$this->_nplurals = $nplurals;
|
147 |
-
$this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
|
148 |
-
}
|
149 |
-
return call_user_func($this->_gettext_select_plural_form, $count);
|
150 |
-
}
|
151 |
-
|
152 |
-
function nplurals_and_expression_from_header($header) {
|
153 |
-
if (preg_match('/^\s*nplurals\s*=\s*(\d+)\s*;\s+plural\s*=\s*(.+)$/', $header, $matches)) {
|
154 |
-
$nplurals = (int)$matches[1];
|
155 |
-
$expression = trim($this->parenthesize_plural_exression($matches[2]));
|
156 |
-
return array($nplurals, $expression);
|
157 |
-
} else {
|
158 |
-
return array(2, 'n != 1');
|
159 |
-
}
|
160 |
-
}
|
161 |
-
|
162 |
-
/**
|
163 |
-
* Makes a function, which will return the right translation index, according to the
|
164 |
-
* plural forms header
|
165 |
-
*/
|
166 |
-
function make_plural_form_function($nplurals, $expression) {
|
167 |
-
$expression = str_replace('n', '$n', $expression);
|
168 |
-
$func_body = "
|
169 |
-
\$index = (int)($expression);
|
170 |
-
return (\$index < $nplurals)? \$index : $nplurals - 1;";
|
171 |
-
return create_function('$n', $func_body);
|
172 |
-
}
|
173 |
-
|
174 |
-
/**
|
175 |
-
* Adds parantheses to the inner parts of ternary operators in
|
176 |
-
* plural expressions, because PHP evaluates ternary oerators from left to right
|
177 |
-
*
|
178 |
-
* @param string $expression the expression without parentheses
|
179 |
-
* @return string the expression with parentheses added
|
180 |
-
*/
|
181 |
-
function parenthesize_plural_exression($expression) {
|
182 |
-
$expression .= ';';
|
183 |
-
$res = '';
|
184 |
-
$depth = 0;
|
185 |
-
for ($i = 0; $i < strlen($expression); ++$i) {
|
186 |
-
$char = $expression[$i];
|
187 |
-
switch ($char) {
|
188 |
-
case '?':
|
189 |
-
$res .= ' ? (';
|
190 |
-
$depth++;
|
191 |
-
break;
|
192 |
-
case ':':
|
193 |
-
$res .= ') : (';
|
194 |
-
break;
|
195 |
-
case ';':
|
196 |
-
$res .= str_repeat(')', $depth) . ';';
|
197 |
-
$depth= 0;
|
198 |
-
break;
|
199 |
-
default:
|
200 |
-
$res .= $char;
|
201 |
-
}
|
202 |
-
}
|
203 |
-
return rtrim($res, ';');
|
204 |
-
}
|
205 |
-
|
206 |
-
function make_headers($translation) {
|
207 |
-
$headers = array();
|
208 |
-
// sometimes \ns are used instead of real new lines
|
209 |
-
$translation = str_replace('\n', "\n", $translation);
|
210 |
-
$lines = explode("\n", $translation);
|
211 |
-
foreach($lines as $line) {
|
212 |
-
$parts = explode(':', $line, 2);
|
213 |
-
if (!isset($parts[1])) continue;
|
214 |
-
$headers[trim($parts[0])] = trim($parts[1]);
|
215 |
-
}
|
216 |
-
return $headers;
|
217 |
-
}
|
218 |
-
|
219 |
-
function set_header($header, $value) {
|
220 |
-
parent::set_header($header, $value);
|
221 |
-
if ('Plural-Forms' == $header) {
|
222 |
-
list( $nplurals, $expression ) = $this->nplurals_and_expression_from_header($this->get_header('Plural-Forms'));
|
223 |
-
$this->_nplurals = $nplurals;
|
224 |
-
$this->_gettext_select_plural_form = $this->make_plural_form_function($nplurals, $expression);
|
225 |
-
}
|
226 |
-
}
|
227 |
-
}
|
228 |
-
endif;
|
229 |
-
|
230 |
-
if ( !class_exists( 'NOOP_Translations' ) ):
|
231 |
-
/**
|
232 |
-
* Provides the same interface as Translations, but doesn't do anything
|
233 |
-
*/
|
234 |
-
class NOOP_Translations {
|
235 |
-
var $entries = array();
|
236 |
-
var $headers = array();
|
237 |
-
|
238 |
-
function add_entry($entry) {
|
239 |
-
return true;
|
240 |
-
}
|
241 |
-
|
242 |
-
function set_header($header, $value) {
|
243 |
-
}
|
244 |
-
|
245 |
-
function set_headers($headers) {
|
246 |
-
}
|
247 |
-
|
248 |
-
function get_header($header) {
|
249 |
-
return false;
|
250 |
-
}
|
251 |
-
|
252 |
-
function translate_entry(&$entry) {
|
253 |
-
return false;
|
254 |
-
}
|
255 |
-
|
256 |
-
function translate($singular, $context=null) {
|
257 |
-
return $singular;
|
258 |
-
}
|
259 |
-
|
260 |
-
function select_plural_form($count) {
|
261 |
-
return 1 == $count? 0 : 1;
|
262 |
-
}
|
263 |
-
|
264 |
-
function get_plural_forms_count() {
|
265 |
-
return 2;
|
266 |
-
}
|
267 |
-
|
268 |
-
function translate_plural($singular, $plural, $count, $context = null) {
|
269 |
-
return 1 == $count? $singular : $plural;
|
270 |
-
}
|
271 |
-
|
272 |
-
function merge_with(&$other) {
|
273 |
-
}
|
274 |
-
}
|
275 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/pot-ext-meta.php
DELETED
@@ -1,76 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Console application, which adds metadata strings from
|
4 |
-
* a WordPress extension to a POT file
|
5 |
-
*
|
6 |
-
* @version $Id$
|
7 |
-
* @package wordpress-i18n
|
8 |
-
* @subpackage tools
|
9 |
-
*/
|
10 |
-
|
11 |
-
require_once dirname( __FILE__ ) . '/pomo/po.php';
|
12 |
-
require_once dirname( __FILE__ ) . '/makepot.php';
|
13 |
-
|
14 |
-
class PotExtMeta {
|
15 |
-
|
16 |
-
var $headers = array(
|
17 |
-
'Plugin Name',
|
18 |
-
'Theme Name',
|
19 |
-
'Plugin URI',
|
20 |
-
'Theme URI',
|
21 |
-
'Description',
|
22 |
-
'Author',
|
23 |
-
'Author URI',
|
24 |
-
'Tags',
|
25 |
-
);
|
26 |
-
|
27 |
-
|
28 |
-
function usage() {
|
29 |
-
fwrite(STDERR, "Usage: php pot-ext-meta.php EXT POT\n");
|
30 |
-
fwrite(STDERR, "Adds metadata from a WordPress theme or plugin file EXT to POT file\n");
|
31 |
-
exit(1);
|
32 |
-
}
|
33 |
-
|
34 |
-
function load_from_file($ext_filename) {
|
35 |
-
$source = MakePOT::get_first_lines($ext_filename);
|
36 |
-
$pot = '';
|
37 |
-
foreach($this->headers as $header) {
|
38 |
-
$string = MakePOT::get_addon_header($header, $source);
|
39 |
-
if (!$string) continue;
|
40 |
-
$args = array(
|
41 |
-
'singular' => $string,
|
42 |
-
'extracted_comments' => $header.' of the plugin/theme',
|
43 |
-
);
|
44 |
-
$entry = new Translation_Entry($args);
|
45 |
-
$pot .= "\n".PO::export_entry($entry)."\n";
|
46 |
-
}
|
47 |
-
return $pot;
|
48 |
-
}
|
49 |
-
|
50 |
-
function append( $ext_filename, $pot_filename, $headers = null ) {
|
51 |
-
if ( $headers )
|
52 |
-
$this->headers = (array) $headers;
|
53 |
-
if ( is_dir( $ext_filename ) ) {
|
54 |
-
$pot = implode('', array_map(array(&$this, 'load_from_file'), glob("$ext_filename/*.php")));
|
55 |
-
} else {
|
56 |
-
$pot = $this->load_from_file($ext_filename);
|
57 |
-
}
|
58 |
-
$potf = '-' == $pot_filename? STDOUT : fopen($pot_filename, 'a');
|
59 |
-
if (!$potf) return false;
|
60 |
-
fwrite($potf, $pot);
|
61 |
-
if ('-' != $pot_filename) fclose($potf);
|
62 |
-
return true;
|
63 |
-
}
|
64 |
-
}
|
65 |
-
|
66 |
-
$included_files = get_included_files();
|
67 |
-
if ($included_files[0] == __FILE__) {
|
68 |
-
ini_set('display_errors', 1);
|
69 |
-
$potextmeta = new PotExtMeta;
|
70 |
-
if (!isset($argv[1])) {
|
71 |
-
$potextmeta->usage();
|
72 |
-
}
|
73 |
-
$potextmeta->append( $argv[1], isset( $argv[2] ) ? $argv[2] : '-', isset( $argv[3] ) ? $argv[3] : null );
|
74 |
-
}
|
75 |
-
|
76 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
src/vendor/websharks/wp-i18n-tools/setup_locale
DELETED
@@ -1,40 +0,0 @@
|
|
1 |
-
#!/bin/sh
|
2 |
-
# setup_locale - Creates the directory structure for a new locale in the
|
3 |
-
# wordpress-i18n repository for a new locale.
|
4 |
-
|
5 |
-
# First argument is the locale. Ex: es_ES
|
6 |
-
locale=$1
|
7 |
-
|
8 |
-
if [ -z "$locale" ]
|
9 |
-
then
|
10 |
-
echo "A locale must be specified."
|
11 |
-
echo Usage is: $0 locale [repository]
|
12 |
-
exit
|
13 |
-
fi
|
14 |
-
|
15 |
-
# Second argument is the base directory of your working copy
|
16 |
-
# of wordpress-i18n.
|
17 |
-
base=$2
|
18 |
-
|
19 |
-
if [ -z "$base" ]
|
20 |
-
then
|
21 |
-
base=.
|
22 |
-
fi
|
23 |
-
|
24 |
-
if [ ! -d "$base" ]
|
25 |
-
then
|
26 |
-
echo "Directory $base does not exist."
|
27 |
-
echo Usage is: $0 locale [repository]
|
28 |
-
exit
|
29 |
-
fi
|
30 |
-
|
31 |
-
cd $base
|
32 |
-
|
33 |
-
svn mkdir $locale
|
34 |
-
svn mkdir $locale/trunk
|
35 |
-
svn mkdir $locale/branches
|
36 |
-
svn mkdir $locale/tags
|
37 |
-
|
38 |
-
svn mkdir $locale/trunk/dist
|
39 |
-
|
40 |
-
svn commit $locale -m "$locale" --force-log
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|