/** * Parses a PHP file for messages marked as translatable. Recognized as message * marking are `$t()` and `$tn()` which are implemented in the `View` class. This * is a rather simple and stupid parser but also fast and easy to grasp. It doesn't * actively attempt to detect and work around syntax errors in marker functions. * * @see lithium\g11n\Message::aliases() * @param string $file Absolute path to a PHP file. * @return array */ protected function _parsePhp($file) { $contents = file_get_contents($file); $contents = Compiler::compile($contents); $defaults = array('ids' => array(), 'context' => null, 'open' => false, 'position' => 0, 'occurrence' => array('file' => $file, 'line' => null)); extract($defaults); $data = array(); if (strpos($contents, '$t(') === false && strpos($contents, '$tn(') === false) { return $data; } $tokens = token_get_all($contents); unset($contents); $findContext = function ($position) use($tokens) { $ignore = array(T_WHITESPACE, '(', ')', T_ARRAY, ','); $open = 1; $options = array(); $depth = 0; while (isset($tokens[$position]) && ($token = $tokens[$position])) { if (!is_array($token)) { $token = array(0 => null, 1 => $token, 2 => null); } if ($token[1] === '(') { $open++; } elseif ($token[1] === ')' && --$open === 0) { break; } if ($token[0] === T_ARRAY || $token[1] === '[') { $depth++; } elseif ($depth > 1 && ($token[1] === ')' || $token[1] === ']')) { $depth--; } if ($depth === 1 && $open === 2) { if (!in_array($token[0] ?: $token[1], $ignore)) { $options[] = $token; } } $position++; } foreach ($options as $i => $token) { if (!(isset($options[$i + 1]) && isset($options[$i + 2]))) { break; } $condition1 = substr($token[1], 1, -1) === 'context'; $condition2 = $options[$i + 1][0] === T_DOUBLE_ARROW; $condition3 = $options[$i + 2][0] === T_CONSTANT_ENCAPSED_STRING; if ($condition1 && $condition2 && $condition3) { return $options[$i + 2][1]; } } return null; }; foreach ($tokens as $key => $token) { if (!is_array($token)) { $token = array(0 => null, 1 => $token, 2 => null); } if ($open) { if ($position >= ($open === 'singular' ? 1 : 2)) { $data = $this->_merge($data, array('id' => $ids['singular'], 'ids' => $ids, 'occurrences' => array($occurrence), 'context' => $context)); extract($defaults, EXTR_OVERWRITE); } elseif ($token[0] === T_CONSTANT_ENCAPSED_STRING) { $ids[$ids ? 'plural' : 'singular'] = $token[1]; $position++; } } else { if (isset($tokens[$key + 1]) && $tokens[$key + 1] === '(') { if ($token[1] === '$t') { $open = 'singular'; } elseif ($token[1] === '$tn') { $open = 'plural'; } else { continue; } $occurrence['line'] = $token[2]; $context = $findContext($key + 2); } } } return $data; }
/** * Parses a PHP file for messages marked as translatable. Recognized as message * marking are `$t()` and `$tn()` which are implemented in the `View` class. This * is a rather simple and stupid parser but also fast and easy to grasp. It doesn't * actively attempt to detect and work around syntax errors in marker functions. * * @see lithium\g11n\Message::aliases() * @param string $file Absolute path to a PHP file. * @return array */ protected function _parsePhp($file) { $contents = file_get_contents($file); $contents = Compiler::compile($contents); $defaults = array('ids' => array(), 'open' => false, 'position' => 0, 'occurrence' => array('file' => $file, 'line' => null)); extract($defaults); $data = array(); if (strpos($contents, '$t(') === false && strpos($contents, '$tn(') == false) { return $data; } $tokens = token_get_all($contents); unset($contents); foreach ($tokens as $key => $token) { if (!is_array($token)) { $token = array(0 => null, 1 => $token, 2 => null); } if ($open) { if ($position >= ($open === 'singular' ? 1 : 2)) { $data = $this->_merge($data, array('id' => $ids['singular'], 'ids' => $ids, 'occurrences' => array($occurrence))); extract($defaults, EXTR_OVERWRITE); } elseif ($token[0] === T_CONSTANT_ENCAPSED_STRING) { $ids[$ids ? 'plural' : 'singular'] = $token[1]; $position++; } } else { if (isset($tokens[$key + 1]) && $tokens[$key + 1] === '(') { if ($token[1] === '$t') { $open = 'singular'; } elseif ($token[1] === '$tn') { $open = 'plural'; } else { continue; } $occurrence['line'] = $token[2]; } } } return $data; }