. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
| Server IP : 94.23.64.18 / Your IP :
216.73.216.185 [
Web Server : Apache System : Linux webm005.cluster107.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64 User : villadal ( 6036) PHP Version : 7.4.33 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl Domains : 2 Domains MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/villadal/www/old/wp-content/plugins/codestyling-localization/includes/ |
Upload File : |
<?php
if (!defined('T_ML_COMMENT'))
define('T_ML_COMMENT', T_COMMENT);
else
define('T_DOC_COMMENT', T_ML_COMMENT);
class csp_l10n_parser {
function csp_l10n_parser($basedir, $textdomain, $do_gettext = true, $do_domains=false) {
$domains = array(
'load_textdomain',
'load_theme_textdomain',
'load_plugin_textdomain',
'load_muplugin_textdomain', //3.0
'load_child_theme_textdomain', //2.9
'define'
);
$gettext = array(
'__',
'_e',
'_c', //context by |
'_nc', //context by |
'__ngettext', '_n',
'__ngettext_noop', '_n_noop',
'_x', //see "_c" but explicite context
'_ex', //see "_c" but explicite context
'_nx', //see "_n" but but additional context,
'_nx_noop' //see "_n_noop" but but additional context,
);
$escapements = array(
'esc_attr__',
'esc_html__',
'esc_attr_e',
'esc_html_e',
'esc_attr_x',
'esc_html_x'
); //needed only for checks against developer own functions for gettext like Ozz is using
$this->component_type = 'unknown';
$this->textdomain = $textdomain;
$this->basedir = $basedir;
$this->filename = '';
$this->l10n_functions = array();
$this->buildin_functions = array_merge($gettext, $escapements);
if ($do_gettext) $this->l10n_functions = array_merge($this->l10n_functions, $gettext);
if ($do_domains) $this->l10n_functions = array_merge($this->l10n_functions, $domains);
$this->l10n_regular = '/('.implode('$|', $this->l10n_functions).'$)/';
$this->l10n_domains = '/('.implode('|',$domains).')/';
$this->regexp_wp_msfiles = "/(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.*)/";
$this->is_new_kernel_translation = @file_exists(dirname(dirname(dirname(dirname(dirname(__FILE__))))).'/wp-admin/user/about.php');
}
function parseFile($filename, $component_type) {
if (file_exists($filename)){
$this->filename = str_replace($this->basedir, '', $filename);
$content = file_get_contents($filename);
return $this->parseString($content, $component_type);
}
return false;
}
function parseString($content, $component_type) {
$results = array(
'gettext' => array(),
'not_gettext' => array(),
'textdomains' => array()
);
$this->component_type = $component_type;
$in_func = false;
$in_domain = false;
$in_not_gettext = false;
$args_started = false;
$parens_balance = 0;
$tokens = token_get_all($content);
$cur_not_gettext = false;
$cur_func = false;
$cur_full_func = false;
$cur_translator_hint = false;
$line_number = 1;
$cur_match_line = 1;
$cur_argc = 0;
$cur_args = array();
$bad_argc = array();
foreach($tokens as $token) {
if (is_array($token)) {
list($id, $text) = $token;
if (T_STRING == $id && preg_match($this->l10n_regular, $text, $m)) {
$in_func = true;
$in_domain = preg_match($this->l10n_domains, $text);
$parens_balance = 0;
$args_started = false;
$cur_func = $m[1];
$cur_full_func = $text;
$token = $text;
} elseif (T_STRING == $id && $in_func) {
if($in_domain) {
if(isset($cur_args[$cur_argc])){
$cur_args[$cur_argc] .= '['.$text.']';
}else{
$cur_args[$cur_argc] = '['.$text.']';
}
$token = $text;
}else{
$bad_argc[] = $cur_argc; //avoid stacked functions inside parts of required params!
$token = $text;
}
} elseif (T_CONSTANT_ENCAPSED_STRING == $id) {
if ($in_func && $args_started) {
if ($text{0} == '"') {
$text = substr($text, 1, strlen($text)-2);
$text = str_replace('\"', '"', $text);
$text = str_replace("\\$", "$", $text);
$text = str_replace("\r\n", "\n", $text);
$token = $text;
$text = str_replace("\\n", "\n", $text);
}
else{
$text = substr($text, 1, strlen($text)-2);
$text = str_replace("\\'", "'", $text);
$text = str_replace("\\$", "$", $text);
$text = str_replace("\r\n", "\n", $text);
$text = str_replace("\\n", "\n", $text);
$text = str_replace("\\\\", "\\", $text);
$token = $text;
}
if(isset($cur_args[$cur_argc])){
$cur_args[$cur_argc] .= $text;
}else{
$cur_args[$cur_argc] = $text;
}
if ($cur_argc == 0) $cur_match_line = $line_number;
}elseif($in_not_gettext) {
if ($text{0} == '"') {
$text = trim($text, '"');
$text = str_replace('\"', '"', $text);
}
else{
$text = trim($text, "'");
$text = str_replace("\\'", "'", $text);
}
$text = str_replace("\\$", "$", $text);
$text = str_replace("\r\n", "\n", $text);
$results['not_gettext'][] = $this->_build_non_gettext($line_number, $cur_not_gettext, $text);
$cur_not_gettext = false;
$token = $text;
}
else {
$token = $text;
}
} elseif ((T_ML_COMMENT == $id || T_COMMENT == $id) && preg_match('|/\*\s*(/?WP_I18N_[a-z_]+)\s*\*/|i', $text, $matches)) {
$in_not_gettext = $matches[1]{0} == 'W';
if ($in_not_gettext) $cur_not_gettext = 'Not gettexted string '.$matches[1];
$token = $text;
} elseif ((T_ML_COMMENT == $id || T_COMMENT == $id) && preg_match('/\*\s(translators:.*)\*/i', $text, $matches)) {
$cur_translator_hint = $matches[1];
$token = $text;
} elseif (T_ML_COMMENT == $id || T_COMMENT == $id || T_DOC_COMMENT == $id) {
$header = $this->_detect_plugin_header($text);
if (count($header) > 0) {
foreach($header as $gt){
$results['gettext'][] = $gt;
}
}
$token = $text;
} elseif((T_VARIABLE == $id)||(T_OBJECT_OPERATOR == $id)||(T_STRING == $id)) {
if ($in_func && $in_domain && $args_started) {
if(isset($cur_args[$cur_argc])){
$cur_args[$cur_argc] .= $text;
}else{
$cur_args[$cur_argc] = $text;
}
}
$token = $text;
}
else {
$token = $text;
}
} elseif ('(' == $token){
$args_started = true;
++$parens_balance;
} elseif (',' == $token) {
if ($in_func && $args_started) {
$cur_argc++;
}
} elseif (')' == $token) {
--$parens_balance;
if ($in_func && 0 == $parens_balance) {
if (count($cur_args) && isset($cur_args[0])) {
//skip those, where all args are variables
$is_dev_func = !in_array($cur_full_func, $this->buildin_functions);
$gt = $this->_build_gettext($cur_match_line, $cur_func, $cur_args, $cur_argc, $is_dev_func, $bad_argc);
if (is_array($gt)) {
if ($in_domain) {
$results['textdomains'][] = $gt;
}else {
if ($cur_translator_hint !== false) {
$gt['CC'][] = $cur_translator_hint;
}
$results['gettext'][] = $gt;
}
}
}
$in_func = false;
$in_domain = false;
$args_started = false;
$cur_func = false;
$cur_full_func = false;
$cur_translator_hint = false;
$cur_argc = 0;
$cur_args = array();
$bad_argc = array();
}
}else {
if($in_domain) {
if(isset($cur_args[$cur_argc])){
// $cur_args[$cur_argc] .= $token;
}else{
// $cur_args[$cur_argc] = $token;
}
/*
var_dump($token);
var_dump($id);
var_dump($text);
var_dump(token_name($id));
var_dump("===========");
*/
}
}
$line_number += substr_count($token, "\n");
}
return $results;
}
function _detect_plugin_header($comment) {
$result = array();
if (($this->component_type != 'plugins') && ($this->component_type != 'plugins_mu'))
return $result;
$default_headers = array(
'Name' => 'Plugin Name',
'PluginURI' => 'Plugin URI',
'Version' => 'Version',
'Description' => 'Description',
'Author' => 'Author',
'AuthorURI' => 'Author URI',
'TextDomain' => 'Text Domain',
'DomainPath' => 'Domain Path'
);
foreach ( $default_headers as $field => $regex ) {
preg_match( '/' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $comment, ${$field});
if ( !empty( ${$field} ) )
${$field} = trim(preg_replace("/\s*(?:\*\/|\?>).*/", '', ${$field}[1]));
else
${$field} = '';
}
$data = compact( array_keys( $default_headers ) );
if (!empty($data['Name']) && !empty($data['TextDomain']) && !empty($data['DomainPath'])) {
//attach the header strings now
foreach ( array('Name', 'PluginURI', 'Description', 'Author', 'AuthorURI', 'Version') as $field ) {
$gt = $this->_build_gettext(
0, //line
'__', //func
array($data[$field]), //args
1,
true, //dev func
array() //bad argc
);
if (is_array($gt)) {
$gt['CC'][] = 'translators: plugin header field \''.$field.'\'';
$result[] = $gt;
}
}
}
return $result;
}
function _ltd_validate($text)
{
$r = strip_tags($text);
if ($r != $text) return "{bug-detected}";
return $text;
}
function _build_gettext($line, $func, $args, $argc, $is_dev_func, $bad_argc) {
$res = array(
'msgid' => '',
'R' => $this->filename.':'.$line,
'CC' => array(),
'LTD' => ($is_dev_func ? $this->textdomain : 'default')
);
//check if we doing wordpress
if ($this->component_type == 'wordpress') {
//special handling of WordPress new separations starting version 3.4
if (($res['LTD'] == 'default') && $this->is_new_kernel_translation) {
//test for admin
if (preg_match("/wp-admin\/.*/", $this->filename) && !preg_match("/(wp-admin\/includes\/continents-cities\.php|wp-admin\/network\/.*|wp-admin\/network\.php)/", $this->filename)) {
$res['LTD'] = 'admin';
}
elseif (preg_match("/(wp-admin\/network\/.*|wp-admin\/network\.php)/", $this->filename)) {
$res['LTD'] = 'admin-network';
}
}
else{
//check if this is multi-site specific file for lower WordPress versions
if ($res['LTD'] == 'default') {
if (preg_match($this->regexp_wp_msfiles, $this->filename)) {
$res['LTD'] = 'ms';
}
}
}
}
switch($func) {
case '__':
// see also esc_html__
//see also esc_attr__
//[0] => phrase
//[1] => textdomain (optional)
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[0];
if (isset($args[1])) $res['LTD'] = $this->_ltd_validate(trim($args[1]));
elseif ($argc == 1) $res['LTD'] = $this->textdomain;
case '_e':
//see also esc_html_e
//see also esc_attr_e
//[0] => phrase
//[1] => textdomain (optional)
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[0];
if (isset($args[1])) $res['LTD'] = $this->_ltd_validate(trim($args[1]));
elseif ($argc == 1) $res['LTD'] = $this->textdomain;
case '_c':
//[0] => phrase
//[1] => textdomain (optional)
$res['msgid'] = $args[0];
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (isset($args[1])) $res['LTD'] = $this->_ltd_validate(trim($args[1]));
elseif ($argc == 1) $res['LTD'] = $this->textdomain;
break;
case '_x':
//see "_c" but explicite context
//see also esc_html_x
//see also esc_attr_x
//[0] => phrase
//[1] => context
//[2] => textdomain (optional)
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (in_array(1, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[1]."\04".$args[0];
if (isset($args[2])) $res['LTD'] = $this->_ltd_validate(trim($args[2]));
elseif ($argc == 2) $res['LTD'] = $this->textdomain;
break;
case '_ex':
//see "_c" but explicite context
//[0] => phrase
//[1] => context
//[2] => textdomain (optional)
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (in_array(1, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[1]."\04".$args[0];
if (isset($args[2])) $res['LTD'] = $this->_ltd_validate(trim($args[2]));
elseif ($argc == 2) $res['LTD'] = $this->textdomain;
break;
case '__ngettext':
//[0] => phrase singular
//[1] => phrase plural
//[2] => number
//[3] => textdomain (optional)
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (in_array(1, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[0]."\00".$args[1];
$res['P'] = true;
if (isset($args[3])) $res['LTD'] = $this->_ltd_validate(trim($args[3]));
elseif ($argc == 3) $res['LTD'] = $this->textdomain;
break;
case '_n':
//[0] => phrase singular
//[1] => phrase plural
//[2] => number
//[3] => textdomain (optional)
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (in_array(1, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[0]."\00".$args[1];
$res['P'] = true;
if (isset($args[3])) $res['LTD'] = $this->_ltd_validate(trim($args[3]));
elseif ($argc == 3) $res['LTD'] = $this->textdomain;
break;
case '_nc':
//[0] => phrase singular
//[1] => phrase plural
//[2] => number
//[3] => textdomain (optional)
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (in_array(1, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[0]."\00".$args[1];
$res['P'] = true;
if (isset($args[3])) $res['LTD'] = $this->_ltd_validate(trim($args[3]));
elseif ($argc == 3) $res['LTD'] = $this->textdomain;
break;
case '_nx':
//see "_n" but but additional context,
//[0] => phrase singular
//[1] => phrase plural
//[2] => number
//[3] => context
//[4] => textdomain (optional)
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (in_array(1, $bad_argc)) return null; //error, this can't be a function
if (in_array(3, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[3]."\04".$args[0]."\00".$args[1];
$res['P'] = true;
if (isset($args[4])) $res['LTD'] = html_entity_decode(strip_tags(trim($args[4])));
elseif ($argc == 4) $res['LTD'] = $this->textdomain;
break;
case '__ngettext_noop':
//[0] => phrase singular
//[1] => phrase plural
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (in_array(1, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[0]."\00".$args[1];
$res['P'] = true;
$res['LTD'] = $this->textdomain; //noop's translated later mostly with correct texdomain
break;
case '_n_noop':
//see deprecated __ngettext_noop
//[0] => phrase singular
//[1] => phrase plural
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (in_array(1, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[0]."\00".$args[1];
$res['P'] = true;
$res['LTD'] = $this->textdomain; //noop's translated later mostly with correct texdomain
break;
case '_nx_noop':
//see "_n_noop" but but additional context,
//[0] => phrase singular
//[1] => phrase plural
//[2] => context
if (in_array(0, $bad_argc)) return null; //error, this can't be a function
if (in_array(1, $bad_argc)) return null; //error, this can't be a function
if (in_array(2, $bad_argc)) return null; //error, this can't be a function
$res['msgid'] = $args[2]."\04".$args[0]."\00".$args[1];
$res['P'] = true;
$res['LTD'] = $this->textdomain; //noop's translated later mostly with correct texdomain
break;
case 'load_textdomain':
$res = array('func' => $func, 'textdomain' => '', 'rel_path' => false, 'path' => false);
if (isset($args[0])) $res['textdomain'] = $args[0];
if (isset($args[1])) $res['path'] = $args[1];
break;
case 'load_theme_textdomain':
$res = array('func' => $func, 'textdomain' => '', 'rel_path' => false, 'path' => false);
if (isset($args[0])) $res['textdomain'] = $args[0];
if (isset($args[1])) $res['path'] = $args[1];
break;
case 'load_plugin_textdomain':
$res = array('func' => $func, 'textdomain' => '', 'rel_path' => false, 'path' => false);
if (isset($args[0])) $res['textdomain'] = $args[0];
if (isset($args[1])) $res['path'] = $args[1];
if (isset($args[2])) $res['rel_path'] = $args[2];
break;
case 'load_muplugin_textdomain':
$res = array('func' => $func, 'textdomain' => '', 'rel_path' => false, 'path' => false);
if (isset($args[0])) $res['textdomain'] = $args[0];
if (isset($args[1])) $res['rel_path'] = $args[1];
break;
case 'load_child_theme_textdomain':
$res = array('func' => $func, 'textdomain' => '', 'rel_path' => false, 'path' => false);
if (isset($args[0])) $res['textdomain'] = $args[0];
if (isset($args[1])) $res['path'] = $args[1];
break;
case 'define':
$res = array('func' => $func);
if (isset($args[0])) $res['const'] = $args[0];
if (isset($args[1])) $res['value'] = $args[1];
break;
default:
/*
var_dump('-----LINE-----');
var_dump($line);
var_dump('-----FUNC-----');
var_dump($func);
var_dump('-----ARGS-----');
var_dump($args);
var_dump('-----ARGC-----');
var_dump($argc);
var_dump('-----IS_DEV_FUNC-----');
var_dump($is_dev_func);
var_dump('-----BAD_ARGC-----');
var_dump($bad_argc);
exit();
*/
;
}
//permit splitting the "Center" qualified within one file, because WP doesn't provide it.
if ($this->component_type == 'wordpress' && preg_match('/continents-cities\.php/', $this->filename) && $res['msgid'] == 'Center') {
$res['msgid'] = "continents-cities\04Center";
$res['CC'] = array('translators: this is an artificial split between the admin and continent text, because of different contextual usage.');
}
return $res;
}
function _build_non_gettext($line, $stage, $text) {
return array(
'msgid' => $text,
'R' => $this->filename.':'.$line,
'CC' => array($stage),
'LTD' => '{php-code}'
);
}
}
?>