00001 <?php
00013 if(!file_exists('profiles/cmdline.php')) {
00014 die("Run this script from your top-level app directory (eg, /var/www/html/app)\n");
00015 }
00016 require_once('profiles/cmdline.php');
00017
00018 function findfiles($path, $func)
00019 {
00020 foreach(glob($path.'/*') as $fn) {
00021 if(is_dir($fn)) {
00022 findfiles($fn, $func);
00023 } else {
00024 $ext = array_pop(explode('.', $fn));
00025 if($ext != 'php') continue;
00026 $func($fn);
00027 }
00028 }
00029 }
00030
00031 function process($fn)
00032 {
00033 global $STRINGS;
00034
00035 $contents = file_get_contents($fn);
00036 if($contents === false) {
00037 echo "Error: cannot open file: $fn\n";
00038 return;
00039 }
00040
00041 $tokens = @token_get_all($contents);
00042
00043 if(0) {
00044
00045 foreach($tokens as $token) {
00046 if(is_string($token)) {
00047 echo "STRING: $token\n";
00048 } else {
00049 echo token_name($token[0]).": {$token[1]}\n";
00050 }
00051 }
00052 }
00053
00054 $_php = false;
00055 $_stage = 0;
00056 foreach($tokens as $token) {
00057 if(is_string($token)) {
00058 if($token == '(' && $_stage == 1) {
00059 $_stage = 2;
00060 }
00061 if($token == ')') {
00062 $_stage = 0;
00063 }
00064 } else {
00065 list($id, $text, $linenum) = $token;
00066 switch($id) {
00067 case T_WHITESPACE:
00068 continue;
00069 break;
00070 case T_OPEN_TAG:
00071 case T_OPEN_TAG_WITH_ECHO:
00072 $_php = true;
00073 $_stage = 0;
00074 break;
00075 case T_CLOSE_TAG:
00076 $_php = false;
00077 $_stage = 0;
00078 break;
00079 case T_STRING:
00080 if($_php && ($text == '__' || $text == '_e')) {
00081 $_stage = 1;
00082 }
00083 break;
00084 case T_CONSTANT_ENCAPSED_STRING:
00085 if($_stage == 2) {
00086 $_stage = 0;
00087 $str = trim($text);
00088
00089 $quote = substr($str, 0, 1);
00090 $str = substr($str, 1, strlen($str)-2);
00091
00092 if($quote == "'") {
00093 eval("\$str = '$str';");
00094 } else if($quote == '"') {
00095 eval("\$str = \"$str\";");
00096 }
00097 if(!isset($STRINGS[$str])) {
00098 $STRINGS[$str] = array(
00099 'locations' => array(),
00100 'translated' => $str
00101 );
00102 }
00103 $STRINGS[$str]['locations'][] = "$fn:$linenum";
00104 }
00105 break;
00106 }
00107 }
00108 }
00109 }
00110
00111 $args = $_SERVER['argv'];
00112 array_shift($args);
00113
00114
00115
00116
00117
00118 $opts = getopt("lm:");
00119 foreach($opts as $k=>$v) {
00120 switch($k) {
00121 case 'l': array_shift($args); break;
00122 case 'm': array_shift($args); array_shift($args); break;
00123 }
00124 }
00125
00126 if(count($args) < 2) {
00127 echo "desc: Scans PHP files for strings enclosed in i18n functions __() or _e()\n";
00128 echo " and builds a PHP messages file from the results. If the messages.php file\n";
00129 echo " does not exist, it will be created. If it already exists, it will be\n";
00130 echo " merged/updated.\n\n";
00131 echo "usage: i18n_scan.php [-l] [-m] <language_code> <language_name>\n";
00132 echo "ex: i18n_scan.php en English\n";
00133 echo "ex: i18n_scan.php -m mymod de German\n\n";
00134 echo "options:\n";
00135 echo " -l Include the file and line number of each occurrence of each string.\n";
00136 echo " -m <mod> Scan within a module. Use this when building messages for a module.\n\n";
00137 exit(0);
00138 }
00139
00140 $OPTIONS = array(
00141 'locations' => isset($opts['l']),
00142 'module' => isset($opts['m']) ? $opts['m'] : false
00143 );
00144
00145 $STRINGS = array();
00146 $LANG_CODE = $args[0];
00147 $LANG_NAME = $args[1];
00148 if($OPTIONS['module']) {
00149 $MESSAGES_FILE = DIR_FS_APP."/modules/{$OPTIONS['module']}/config/i18n/$LANG_CODE/messages.php";
00150 } else {
00151 $MESSAGES_FILE = DIR_FS_APP."/config/i18n/$LANG_CODE/messages.php";
00152 }
00153
00154 if(file_exists($MESSAGES_FILE)) {
00155 include($MESSAGES_FILE);
00156 if($LANGUAGE_CODE != $LANG_CODE) {
00157 die("Error: Language in $MESSAGE_FILES does not match the one specified: $LANG_CODE\n");
00158 }
00159 foreach($MESSAGES as $k=>$v) {
00160 $STRINGS[$k] = array(
00161 'locations' => array(),
00162 'translated' => $v
00163 );
00164 }
00165 }
00166
00167 if($OPTIONS['module']) {
00168 $mod_dirs = array('config','models','pages','plugins','templates');
00169 foreach($mod_dirs as $dir) {
00170 $d = DIR_FS_APP."/modules/{$OPTIONS['module']}/$dir";
00171 echo "Scanning $d\n";
00172 findfiles($d, 'process');
00173 }
00174 } else {
00175 $app_dirs = array('bin','config','core','models','pages','plugins',
00176 'profiles','templates');
00177 $pronto_dirs = array('core','plugins','profiles');
00178 foreach($app_dirs as $dir) {
00179 $d = DIR_FS_APP."/$dir";
00180 echo "Scanning $d\n";
00181 findfiles($d, 'process');
00182 }
00183 foreach($pronto_dirs as $dir) {
00184 $d = DIR_FS_PRONTO."/$dir";
00185 echo "Scanning $d\n";
00186 findfiles($d, 'process');
00187 }
00188 }
00189 ksort($STRINGS);
00190
00191 @mkdir(dirname($MESSAGES_FILE), 0755, true);
00192 $mode = file_exists($MESSAGES_FILE) ? 'update' : 'create';
00193 $fp = fopen($MESSAGES_FILE, 'w');
00194 if($fp === false) die("Error: cannot open file for write: $MESSAGES_FILE\n");
00195
00196 $now = date('Y-m-d H:i:s');
00197 $header = <<<EOT
00198 <?php
00199
00200
00201
00202
00203 \$LANGUAGE_CODE = '$LANG_CODE';
00204 \$LANGUAGE_NAME = '$LANG_NAME';
00205
00206 \$MESSAGES = array(
00207
00208 EOT;
00209 fputs($fp, $header);
00210
00211 foreach($STRINGS as $str=>$arr) {
00212 $s = str_replace('"', "\\\"", $str);
00213 $t = str_replace('"', "\\\"", $arr['translated']);
00214 if($OPTIONS['locations'] && count($arr['locations'])) {
00215 fputs($fp, "\t// ".join(', ',$arr['locations'])."\n");
00216 }
00217 fputs($fp, "\t\"$s\" => \"$t\",\n");
00218 }
00219 fputs($fp, ");\n\n?>");
00220
00221 fclose($fp);
00222
00223 echo "\nSuccessfully {$mode}d $MESSAGES_FILE\n";
00224
00225 ?>