179 lines
6.3 KiB
PHP
179 lines
6.3 KiB
PHP
<?php defined("SYSPATH") or die("No direct script access.");
|
||
/**
|
||
* Gallery - a web based photo album viewer and editor
|
||
* Copyright (C) 2000-2011 Bharat Mediratta
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify
|
||
* it under the terms of the GNU General Public License as published by
|
||
* the Free Software Foundation; either version 2 of the License, or (at
|
||
* your option) any later version.
|
||
*
|
||
* This program is distributed in the hope that it will be useful, but
|
||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
* General Public License for more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License
|
||
* along with this program; if not, write to the Free Software
|
||
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
|
||
*/
|
||
|
||
/**
|
||
* Scans all source code for messages that need to be localized.
|
||
*/
|
||
class l10n_scanner_Core {
|
||
// Based on Drupal's potx module, originally written by:
|
||
// Gbor Hojtsy http://drupal.org/user/4166
|
||
public static $cache;
|
||
|
||
static function process_message($message, &$cache) {
|
||
if (empty($cache)) {
|
||
foreach (db::build()
|
||
->select("key")
|
||
->from("incoming_translations")
|
||
->where("locale", "=", "root")
|
||
->execute() as $row) {
|
||
$cache[$row->key] = true;
|
||
}
|
||
}
|
||
|
||
$key = Gallery_I18n::get_message_key($message);
|
||
if (array_key_exists($key, $cache)) {
|
||
return $cache[$key];
|
||
}
|
||
|
||
$entry = ORM::factory("incoming_translation")->where("key", "=", $key)->find();
|
||
if (!$entry->loaded()) {
|
||
$entry->key = $key;
|
||
$entry->message = serialize($message);
|
||
$entry->locale = "root";
|
||
$entry->save();
|
||
}
|
||
}
|
||
|
||
static function scan_php_file($file, &$cache) {
|
||
$code = file_get_contents($file);
|
||
$raw_tokens = token_get_all($code);
|
||
unset($code);
|
||
|
||
$tokens = array();
|
||
$func_token_list = array("t" => array(), "t2" => array());
|
||
$token_number = 0;
|
||
// Filter out HTML / whitespace, and build a lookup for global function calls.
|
||
foreach ($raw_tokens as $token) {
|
||
if ((!is_array($token)) || (($token[0] != T_WHITESPACE) && ($token[0] != T_INLINE_HTML))) {
|
||
if (is_array($token)) {
|
||
if ($token[0] == T_STRING && in_array($token[1], array("t", "t2"))) {
|
||
$func_token_list[$token[1]][] = $token_number;
|
||
}
|
||
}
|
||
$tokens[] = $token;
|
||
$token_number++;
|
||
}
|
||
}
|
||
unset($raw_tokens);
|
||
|
||
if (!empty($func_token_list["t"])) {
|
||
$errors = l10n_scanner::_parse_t_calls($tokens, $func_token_list["t"], $cache);
|
||
foreach ($errors as $line => $error) {
|
||
Kohana_Log::add(
|
||
"error", "Translation scanner error. " .
|
||
"file: " . substr($file, strlen(DOCROOT)) . ", line: $line, context: $error");
|
||
}
|
||
}
|
||
|
||
if (!empty($func_token_list["t2"])) {
|
||
$errors = l10n_scanner::_parse_plural_calls($tokens, $func_token_list["t2"], $cache);
|
||
foreach ($errors as $line => $error) {
|
||
Kohana_Log::add(
|
||
"error", "Translation scanner error. " .
|
||
"file: " . substr($file, strlen(DOCROOT)) . ", line: $line, context: $error");
|
||
}
|
||
}
|
||
}
|
||
|
||
static function scan_info_file($file, &$cache) {
|
||
$info = new ArrayObject(parse_ini_file($file), ArrayObject::ARRAY_AS_PROPS);
|
||
foreach (array('name', 'description') as $property) {
|
||
if (isset($info->$property)) {
|
||
l10n_scanner::process_message($info->$property, $cache);
|
||
}
|
||
}
|
||
}
|
||
|
||
private static function _parse_t_calls(&$tokens, &$call_list, &$cache) {
|
||
$errors = array();
|
||
foreach ($call_list as $index) {
|
||
$function_name = $tokens[$index++];
|
||
$parens = $tokens[$index++];
|
||
$first_param = $tokens[$index++];
|
||
$next_token = $tokens[$index];
|
||
|
||
if ($parens == "(") {
|
||
if (in_array($next_token, array(")", ","))
|
||
&& (is_array($first_param) && ($first_param[0] == T_CONSTANT_ENCAPSED_STRING))) {
|
||
$message = self::_escape_quoted_string($first_param[1]);
|
||
l10n_scanner::process_message($message, $cache);
|
||
} else {
|
||
if (is_array($first_param) && ($first_param[0] == T_CONSTANT_ENCAPSED_STRING)) {
|
||
// Malformed string literals; escalate this
|
||
$errors[$first_param[2]] =
|
||
var_export(array($function_name, $parens, $first_param, $next_token), 1);
|
||
} else {
|
||
// t() found, but inside is something which is not a string literal. That's fine.
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return $errors;
|
||
}
|
||
|
||
private static function _parse_plural_calls(&$tokens, &$call_list, &$cache) {
|
||
$errors = array();
|
||
foreach ($call_list as $index) {
|
||
$function_name = $tokens[$index++];
|
||
$parens = $tokens[$index++];
|
||
$first_param = $tokens[$index++];
|
||
$first_separator = $tokens[$index++];
|
||
$second_param = $tokens[$index++];
|
||
$next_token = $tokens[$index];
|
||
|
||
if ($parens == "(") {
|
||
if ($first_separator == "," && $next_token == ","
|
||
&& is_array($first_param) && $first_param[0] == T_CONSTANT_ENCAPSED_STRING
|
||
&& is_array($second_param) && $second_param[0] == T_CONSTANT_ENCAPSED_STRING) {
|
||
$singular = self::_escape_quoted_string($first_param[1]);
|
||
$plural = self::_escape_quoted_string($second_param[1]);
|
||
l10n_scanner::process_message(array("one" => $singular, "other" => $plural), $cache);
|
||
} else {
|
||
if (is_array($first_param) && $first_param[0] == T_CONSTANT_ENCAPSED_STRING) {
|
||
$errors[$first_param[2]] = var_export(
|
||
array($function_name, $parens, $first_param,
|
||
$first_separator, $second_param, $next_token), 1);
|
||
} else {
|
||
// t2() found, but inside is something which is not a string literal. That's fine.
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return $errors;
|
||
}
|
||
|
||
/**
|
||
* Escape quotes in a strings depending on the surrounding
|
||
* quote type used.
|
||
*
|
||
* @param $str The strings to escape
|
||
*/
|
||
private static function _escape_quoted_string($str) {
|
||
$quo = substr($str, 0, 1);
|
||
$str = substr($str, 1, -1);
|
||
if ($quo == '"') {
|
||
$str = stripcslashes($str);
|
||
} else {
|
||
$str = strtr($str, array("\\'" => "'", "\\\\" => "\\"));
|
||
}
|
||
return $str;
|
||
}
|
||
}
|