Initial Commit
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
namespace Gettext\Utils;
|
||||
|
||||
use Exception;
|
||||
use Gettext\Translations;
|
||||
|
||||
abstract class FunctionsScanner
|
||||
{
|
||||
/**
|
||||
* Scan and returns the functions and the arguments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getFunctions();
|
||||
|
||||
/**
|
||||
* Search for specific functions and create translations
|
||||
*
|
||||
* @param array $functions The gettext functions to search
|
||||
* @param Translations $translations The translations instance where save the values
|
||||
* @param string $file The filename used to the reference
|
||||
*/
|
||||
public function saveGettextFunctions(array $functions, Translations $translations, $file = '')
|
||||
{
|
||||
foreach ($this->getFunctions() as $function) {
|
||||
list($name, $line, $args) = $function;
|
||||
|
||||
if (!isset($functions[$name])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ($functions[$name]) {
|
||||
case '__':
|
||||
if (!isset($args[0])) {
|
||||
continue 2;
|
||||
}
|
||||
$original = $args[0];
|
||||
$translation = $translations->insert('', $original);
|
||||
break;
|
||||
|
||||
case 'n__':
|
||||
if (!isset($args[1])) {
|
||||
continue 2;
|
||||
}
|
||||
$original = $args[0];
|
||||
$plural = $args[1];
|
||||
$translation = $translations->insert('', $original, $plural);
|
||||
break;
|
||||
|
||||
case 'p__':
|
||||
if (!isset($args[1])) {
|
||||
continue 2;
|
||||
}
|
||||
$context = $args[0];
|
||||
$original = $args[1];
|
||||
$translation = $translations->insert($context, $original);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception('Not valid functions');
|
||||
}
|
||||
|
||||
$translation->addReference($file, $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
namespace Gettext\Utils;
|
||||
|
||||
class JsFunctionsScanner extends FunctionsScanner
|
||||
{
|
||||
protected $code;
|
||||
protected $status = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $code The php code to scan
|
||||
*/
|
||||
public function __construct($code)
|
||||
{
|
||||
$this->code = $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
$length = strlen($this->code);
|
||||
$line = 1;
|
||||
$buffer = '';
|
||||
$functions = array();
|
||||
$bufferFunctions = array();
|
||||
$char = null;
|
||||
|
||||
for ($pos = 0; $pos < $length; $pos++) {
|
||||
$prev = $char;
|
||||
$char = $this->code[$pos];
|
||||
$next = isset($this->code[$pos]) ? $this->code[$pos] : null;
|
||||
|
||||
switch ($char) {
|
||||
case "\n":
|
||||
++$line;
|
||||
|
||||
if ($this->status('line-comment')) {
|
||||
$this->upStatus();
|
||||
}
|
||||
break;
|
||||
|
||||
case "/":
|
||||
switch ($this->status()) {
|
||||
case 'simple-quote':
|
||||
case 'double-quote':
|
||||
case 'line-comment':
|
||||
break;
|
||||
|
||||
case 'block-comment':
|
||||
if ($prev === '*') {
|
||||
$this->upStatus();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($next === '/') {
|
||||
$this->downStatus('line-comment');
|
||||
} elseif ($next === '*') {
|
||||
$this->downStatus('block-comment');
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case "'":
|
||||
switch ($this->status()) {
|
||||
case 'simple-quote':
|
||||
$this->upStatus();
|
||||
break;
|
||||
|
||||
case 'line-comment':
|
||||
case 'block-comment':
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->downStatus('simple-quote');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case '"':
|
||||
switch ($this->status()) {
|
||||
case 'double-quote':
|
||||
$this->upStatus();
|
||||
break;
|
||||
|
||||
case 'line-comment':
|
||||
case 'block-comment':
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->downStatus('double-quote');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
switch ($this->status()) {
|
||||
case 'double-quote':
|
||||
case 'line-comment':
|
||||
case 'block-comment':
|
||||
break;
|
||||
|
||||
default:
|
||||
if ($buffer && preg_match('/(\w+)$/', $buffer, $matches)) {
|
||||
$this->downStatus('function');
|
||||
array_unshift($bufferFunctions, array($matches[1], $line, array()));
|
||||
$buffer = '';
|
||||
continue 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ')':
|
||||
switch ($this->status()) {
|
||||
case 'function':
|
||||
if (($argument = self::prepareArgument($buffer))) {
|
||||
$bufferFunctions[0][2][] = $argument;
|
||||
}
|
||||
|
||||
if ($bufferFunctions) {
|
||||
$functions[] = array_shift($bufferFunctions);
|
||||
}
|
||||
|
||||
$buffer = '';
|
||||
continue 3;
|
||||
}
|
||||
|
||||
case ',':
|
||||
switch ($this->status()) {
|
||||
case 'function':
|
||||
if (($argument = self::prepareArgument($buffer))) {
|
||||
$bufferFunctions[0][2][] = $argument;
|
||||
}
|
||||
|
||||
$buffer = '';
|
||||
continue 3;
|
||||
}
|
||||
}
|
||||
|
||||
switch ($this->status()) {
|
||||
case 'line-comment':
|
||||
case 'block-comment':
|
||||
break;
|
||||
|
||||
default:
|
||||
$buffer .= $char;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $functions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current context of the scan
|
||||
*
|
||||
* @param null|string $match To check whether the current status is this value
|
||||
*
|
||||
* @return string|boolean
|
||||
*/
|
||||
protected function status($match = null)
|
||||
{
|
||||
$status = isset($this->status[0]) ? $this->status[0] : null;
|
||||
|
||||
if ($match) {
|
||||
return ($status === $match);
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new status to the stack
|
||||
*
|
||||
* @param string $status
|
||||
*/
|
||||
protected function downStatus($status)
|
||||
{
|
||||
array_unshift($this->status, $status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes and return the current status
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function upStatus()
|
||||
{
|
||||
return array_shift($this->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the arguments found in functions
|
||||
*
|
||||
* @param string $argument
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function prepareArgument($argument)
|
||||
{
|
||||
if ($argument && ($argument[0] === '"' || $argument[0] === "'")) {
|
||||
if ($argument[0] === '"') {
|
||||
$argument = str_replace('\\"', '"', $argument);
|
||||
} else {
|
||||
$argument = str_replace("\\'", "'", $argument);
|
||||
}
|
||||
|
||||
return substr($argument, 1, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace Gettext\Utils;
|
||||
|
||||
class PhpFunctionsScanner extends FunctionsScanner
|
||||
{
|
||||
protected $tokens;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $code The php code to scan
|
||||
*/
|
||||
public function __construct($code)
|
||||
{
|
||||
$this->tokens = token_get_all($code);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getFunctions()
|
||||
{
|
||||
$count = count($this->tokens);
|
||||
$bufferFunctions = array();
|
||||
$functions = array();
|
||||
|
||||
for ($k = 0; $k < $count; $k++) {
|
||||
$value = $this->tokens[$k];
|
||||
|
||||
//close the current function
|
||||
if (is_string($value)) {
|
||||
if ($value === ')' && isset($bufferFunctions[0])) {
|
||||
$functions[] = array_shift($bufferFunctions);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
//add an argument to the current function
|
||||
if (isset($bufferFunctions[0]) && ($value[0] === T_CONSTANT_ENCAPSED_STRING)) {
|
||||
$val = $value[1];
|
||||
|
||||
if ($val[0] === '"') {
|
||||
$val = str_replace('\\"', '"', $val);
|
||||
} else {
|
||||
$val = str_replace("\\'", "'", $val);
|
||||
}
|
||||
|
||||
$bufferFunctions[0][2][] = substr($val, 1, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
//new function found
|
||||
if (($value[0] === T_STRING) && is_string($this->tokens[$k + 1]) && ($this->tokens[$k + 1] === '(')) {
|
||||
array_unshift($bufferFunctions, array($value[1], $value[2], array()));
|
||||
$k++;
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $functions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
namespace Gettext\Utils;
|
||||
|
||||
class StringReader
|
||||
{
|
||||
public $pos;
|
||||
public $str;
|
||||
public $strlen;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $str The string to read
|
||||
*/
|
||||
public function __construct($str)
|
||||
{
|
||||
$this->str = $str;
|
||||
$this->strlen = strlen($this->str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and returns a part of the string
|
||||
*
|
||||
* @param int $bytes The number of bytes to read
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function read($bytes)
|
||||
{
|
||||
$data = substr($this->str, $this->pos, $bytes);
|
||||
|
||||
$this->seekto($this->pos + $bytes);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the cursor to a specific position
|
||||
*
|
||||
* @param int $pos The amount of bytes to move
|
||||
*
|
||||
* @return int The new position
|
||||
*/
|
||||
public function seekto($pos)
|
||||
{
|
||||
$this->pos = ($this->strlen < $pos) ? $this->strlen : $pos;
|
||||
|
||||
return $this->pos;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user