* @license PHP License * @package WB * @subpackage base */ WBClass::load('WBNLS_Extractor'); /** * Native Lanauge Support: Extractor PHP System Files * * Extract translatable strings from PHP files in Wombat project folder * and from patForms * * @version 0.1.1 * @package WB * @subpackage nls */ class WBNLS_Extractor_PHPSystem extends WBNLS_Extractor { /** * List of files to ignore * @var array */ private $ignoreFile = array(); /** * actually extract messages * * Extract messages from well known system PHP folders: * include/WB/*, include/patForms/patForms/* * * @return int $total */ protected function extract() { $sys = WBParam::get('wb/dir/system'); $this->ignoreFile[] = $sys . '/include/WB/Config/Unserializer.php'; $this->ignoreFile[] = $sys . '/include/patEx/Template/Function/Gettext.php'; $cnt = $this->extractPhpDir($sys . '/include/WB'); $cnt += $this->extractPhpDir($sys . '/include/patEx'); $cnt += $this->extractPhpDir($sys . '/include/patForms/patForms'); return $cnt; } /** * recursively find all PHP files * * Walk through folder and find all PHP files to be extracted * * @param string $folder * @return int $cnt */ protected function extractPhpDir($dir) { $cnt = 0; $dh = new DirectoryIterator($dir); foreach ($dh as $i) { $name = $i->getFilename(); if ($i->isDot() || '.' == $name[0]) { continue; } if ($i->isDir()) { $cnt += $this->extractPhpDir($i->getRealPath()); continue; } $name = explode('.', $name); if ('php' != end($name)) { continue; } if (in_array($i->getRealPath(), $this->ignoreFile)) { continue; } $this->extractPhpFile($i->getRealPath()); ++$cnt; } return $cnt; } /** * extract strings from PHP file * * Tokenize php file and extract pati18n::gettext() calls * * @param string $realpath */ private function extractPhpFile($realpath) { $string = file_get_contents($realpath); $tokens = token_get_all($string); for ($i = 0; $i < count($tokens); ++$i) { $t = $tokens[$i]; if (!is_array($t)) { continue; } if ($t[0] == T_DOUBLE_COLON) { $left = $tokens[($i - 1)]; if ($left[0] != T_STRING || strtolower($left[1]) != 'pati18n' ) { continue; } $right = $tokens[($i + 1)]; if ($right[0] != T_STRING) { continue; } ++$i; $domain = null; switch (strtolower($right[1])) { case 'dgettext': $d = $this->getNextString($i, $tokens); $domain = $d[1]; // fall through case 'gettext': $t = $this->getNextString($i, $tokens); // ignore if ($t[1] == '$value') { break; } try { $this->imp->addMsg($t[1], null, $domain); } catch(Exception $e) { $err = array( 'msg' => $e->getMessage(), 'type' => 'exception' ); $this->addError($err); } break; case 'dngettext': $d = $this->getNextString($i, $tokens); $domain = $d[1]; // fall through case 'ngettext': $s = $this->getNextString($i, $tokens); $p = $this->getNextString($i, $tokens); try { $id = $this->imp->addMsg($t[1], null, $domain); $this->imp->addMsg($p[1], $id, $domain); } catch(Exception $e) { $err = array( 'msg' => $e->getMessage(), 'type' => 'exception' ); $this->addError($err); } break; default: continue; break; } } } } /** * get next token string * * Auxilliary method to find next string token and strip rubish * * @param int $i * @param array $token * @return array */ private function getNextString(&$i, $tokens) { ++$i; while(true) { $t = $tokens[$i]; // skip "(" if (!is_array($t) && $t == '(') { ++$i; continue; } // skip blanks if (is_array($t) && $t[0] != T_WHITESPACE ) { break; } ++$i; } $t[1] = stripslashes(trim($t[1], '\'"')); return $t; } } ?>