* @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.2.0 * @package WB * @subpackage nls */ class WBNLS_Extractor_PHPSystem extends WBNLS_Extractor { /** * List of files to ignore * @var array */ private $ignoreFile = array(); /** * Locale Settings * @var WBConfig */ private $locale; /** * Origin Lanauge Code * @var string */ private $origin = ''; /** * Constructor * * Start importer */ public function __construct() { parent::__construct(); $this->locale = WBClass::create('WBConfig'); $this->locale->load('locale'); } /** * actually extract messages * * Extract messages from well known system PHP folders: * include/WB/*, include/patForms/patForms/* * * @return int $total */ protected function extract() { // set origin language $this->origin = $this->locale->get('locale/languages/origin'); $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); } $this->translateOrigin($id, $t[1]); break; case 'dngettext': $d = $this->getNextString($i, $tokens); $domain = $d[1]; // fall through case 'ngettext': echo "NOT IMPLEMENTED, YET! \n"; die(__FILE__ . ':' . __LINE__ . "\n"); $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); } $this->translateOrigin($id, $t[1]); break; default: continue 2; 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; } /** * Save Origin as Translation * * System file have en_GB as origin language. If project's origin language differs from en_* * add system's origin message as en_* translation in project. * * @param string message id * @param string origin text */ private function translateOrigin($id, $string) { if (empty($this->origin)) { return; } if (0 == strncmp('en_', $this->origin, 3)) { return; } $available = $this->locale->get('locale/languages/available', array()); foreach ($available as $lang) { if (0 != strncmp('en_', $this->origin, 3)) { continue; } try { $this->imp->addTranslation($id, $string, $l); } catch (Exception $e) { $err = array( 'msg' => $e->getMessage(), 'type' => 'exception' ); $this->addError($err); } } } } ?>