mirror of
https://github.com/godotengine/godot-question2answer.git
synced 2026-01-01 01:48:37 +03:00
This project lived only on the server without version control. This is now the starting point for the repository.
284 lines
8.3 KiB
PHP
284 lines
8.3 KiB
PHP
<?php
|
|
/*
|
|
Question2Answer by Gideon Greenspan and contributors
|
|
http://www.question2answer.org/
|
|
|
|
Description: Development tool to see which language phrases are missing or unused
|
|
|
|
|
|
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.
|
|
|
|
More about this license: http://www.question2answer.org/license.php
|
|
*/
|
|
|
|
define('QA_BASE_DIR', dirname(dirname(empty($_SERVER['SCRIPT_FILENAME']) ? __FILE__ : $_SERVER['SCRIPT_FILENAME'])) . '/');
|
|
|
|
require 'qa-base.php';
|
|
require_once QA_INCLUDE_DIR . 'app/users.php';
|
|
|
|
if (qa_get_logged_in_level() < QA_USER_LEVEL_ADMIN)
|
|
qa_redirect('admin/general', null, qa_opt('site_url'));
|
|
|
|
header('Content-type: text/html; charset=utf-8');
|
|
|
|
?><!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
|
|
<title>Question2Answer Language Check</title>
|
|
<style>
|
|
body {
|
|
font-family: arial;
|
|
font-size: 12px;
|
|
}
|
|
code {font-size: 125%;}
|
|
.severe {color: #b83939;}
|
|
.warning {color: #d2930d;}
|
|
.includes {color: #999;}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<?php
|
|
|
|
function get_phrase_substitutions($phrase)
|
|
{
|
|
$substitutions = array();
|
|
|
|
if (preg_match_all('/\^(([0-9]+)|([a-z_]+)|)/', $phrase, $matches)) {
|
|
foreach ($matches[0] as $match) {
|
|
@$substitutions[$match]++;
|
|
}
|
|
}
|
|
|
|
return $substitutions;
|
|
}
|
|
|
|
echo '<code class="severe">Red = important to review.</code><br>';
|
|
echo '<code class="warning">Orange = probably safe to ignore.</code>';
|
|
|
|
echo '<h1>Checking US English files in <code>qa-include</code>...</h1>';
|
|
|
|
$includefiles = array_merge(glob(QA_INCLUDE_DIR . 'qa-*.php'), glob(QA_INCLUDE_DIR . '*/qa-*.php'), glob(QA_PLUGIN_DIR . '*/qa-*.php'));
|
|
|
|
$definite = array();
|
|
$probable = array();
|
|
$possible = array();
|
|
$defined = array();
|
|
$english = array();
|
|
$backmap = array();
|
|
$substitutions = array();
|
|
|
|
output_start_includes();
|
|
|
|
foreach ($includefiles as $includefile) {
|
|
$contents = file_get_contents($includefile);
|
|
|
|
preg_match_all('/qa_lang[a-z_]*\s*\(\s*[\'\"]([a-z]+)\/([0-9a-z_]+)[\'\"]/', $contents, $matches, PREG_SET_ORDER);
|
|
|
|
foreach ($matches as $matchparts) {
|
|
if ($matchparts[2] == 'date_month_') { // special case for month names
|
|
for ($month = 1; $month <= 12; $month++) {
|
|
@$definite[$matchparts[1]][$matchparts[2] . $month]++;
|
|
}
|
|
|
|
} else
|
|
@$definite[$matchparts[1]][$matchparts[2]]++;
|
|
}
|
|
|
|
preg_match_all('/[\'\"]([a-z]+)\/([0-9a-z_]+)[\'\"]/', $contents, $matches, PREG_SET_ORDER);
|
|
|
|
foreach ($matches as $matchparts) {
|
|
@$probable[$matchparts[1]][$matchparts[2]]++;
|
|
}
|
|
|
|
if (preg_match('|/qa-include/qa-lang-([a-z]+)\.php$|', $includefile, $matches)) { // it's a lang file
|
|
$prefix = $matches[1];
|
|
|
|
output_reading_include($includefile);
|
|
$phrases = @include $includefile;
|
|
|
|
foreach ($phrases as $key => $value) {
|
|
@$defined[$prefix][$key]++;
|
|
$english[$prefix][$key] = $value;
|
|
$backmap[$value][] = array('prefix' => $prefix, 'key' => $key);
|
|
$substitutions[$prefix][$key] = get_phrase_substitutions($value);
|
|
}
|
|
|
|
} else { // it's a different file
|
|
preg_match_all('/[\'\"\/]([0-9a-z_]+)[\'\"]/', $contents, $matches, PREG_SET_ORDER);
|
|
|
|
foreach ($matches as $matchparts) {
|
|
@$possible[$matchparts[1]]++;
|
|
}
|
|
}
|
|
}
|
|
|
|
output_finish_includes();
|
|
|
|
foreach ($definite as $key => $valuecount) {
|
|
foreach ($valuecount as $value => $count) {
|
|
if (!@$defined[$key][$value]) {
|
|
output_lang_issue($key, $value, 'used by ' . $count . ' file/s but not defined');
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ($defined as $key => $valuecount) {
|
|
foreach ($valuecount as $value => $count) {
|
|
if (!@$definite[$key][$value] && !@$probable[$key][$value] && !@$possible[$value]) {
|
|
output_lang_issue($key, $value, 'defined but apparently not used');
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ($backmap as $phrase => $where) {
|
|
if (count($where) > 1) {
|
|
foreach ($where as $onewhere) {
|
|
output_lang_issue($onewhere['prefix'], $onewhere['key'], 'contains the shared phrase "' . $phrase . '"', false);
|
|
}
|
|
}
|
|
}
|
|
|
|
require_once QA_INCLUDE_DIR . 'app/admin.php';
|
|
|
|
$languages = qa_admin_language_options();
|
|
unset($languages['']);
|
|
|
|
foreach ($languages as $code => $language) {
|
|
echo '<h1>Checking ' . $language . ' files in <code>qa-lang/' . $code . '</code>...</h1>';
|
|
|
|
$langdefined = array();
|
|
$langdifferent = array();
|
|
$langsubstitutions = array();
|
|
$langincludefiles = glob(QA_LANG_DIR . $code . '/qa-*.php');
|
|
$langnewphrases = array();
|
|
|
|
output_start_includes();
|
|
|
|
foreach ($langincludefiles as $langincludefile) {
|
|
if (preg_match('/qa-lang-([a-z]+)\.php$/', $langincludefile, $matches)) { // it's a lang file
|
|
$prefix = $matches[1];
|
|
|
|
output_reading_include($langincludefile);
|
|
$phrases = @include $langincludefile;
|
|
|
|
foreach ($phrases as $key => $value) {
|
|
@$langdefined[$prefix][$key]++;
|
|
$langdifferent[$prefix][$key] = ($value != @$english[$prefix][$key]);
|
|
$langsubstitutions[$prefix][$key] = get_phrase_substitutions($value);
|
|
}
|
|
}
|
|
}
|
|
|
|
output_finish_includes();
|
|
|
|
foreach ($langdefined as $key => $valuecount) {
|
|
foreach ($valuecount as $value => $count) {
|
|
if (!@$defined[$key][$value]) {
|
|
output_lang_issue($key, $value, 'defined but not in US English files');
|
|
|
|
} elseif (!$langdifferent[$key][$value]) {
|
|
output_lang_issue($key, $value, 'identical to US English files', false);
|
|
|
|
} else {
|
|
foreach ($substitutions[$key][$value] as $substitution => $subcount) {
|
|
if (!@$langsubstitutions[$key][$value][$substitution])
|
|
output_lang_issue($key, $value, 'omitted the substitution ' . $substitution);
|
|
elseif ($subcount > @$langsubstitutions[$key][$value][$substitution])
|
|
output_lang_issue($key, $value, 'has fewer of the substitution ' . $substitution);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ($defined as $key => $valuecount) {
|
|
$showaserror = !(($key == 'admin') || ($key == 'options') || ($code == 'en-GB'));
|
|
|
|
if (@$langdefined[$key]) {
|
|
if (count($langdefined[$key]) < (count($valuecount) / 2)) { // only a few phrases defined
|
|
output_lang_issue($key, null, 'few translations provided so will use US English defaults', $showaserror);
|
|
|
|
} else {
|
|
foreach ($valuecount as $value => $count) {
|
|
if (!@$langdefined[$key][$value]) {
|
|
output_lang_issue($key, $value, 'undefined so will use US English defaults', $showaserror);
|
|
$langnewphrases[$key][$value] = $english[$key][$value];
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
output_lang_issue($key, null, 'no translations provided so will use US English defaults', $showaserror);
|
|
}
|
|
}
|
|
|
|
foreach ($langnewphrases as $prefix => $phrases) {
|
|
echo '<h2>' . $language . ' phrases to add to <code>qa-lang/' . $code . '/qa-lang-' . $prefix . '.php</code>:</h2>';
|
|
|
|
echo 'Copy and paste this into the middle of <code>qa-lang/' . $code . '/qa-lang-' . $prefix . '.php</code> then translate the right-hand side after the <code>=></code> symbol.';
|
|
|
|
echo '<pre>';
|
|
|
|
foreach ($phrases as $key => $value) {
|
|
echo '<span style="font-size:25%;">' . "\t\t</span>'" . $key . "' => \"" . strtr($value, array('\\' => '\\\\', '"' => '\"', '$' => '\$', "\n" => '\n', "\t" => '\t')) . "\",\n";
|
|
}
|
|
|
|
echo '</pre>';
|
|
}
|
|
}
|
|
|
|
|
|
function output_lang_issue($prefix, $key, $issue, $error = true)
|
|
{
|
|
$colorClass = $error ? 'severe' : 'warning';
|
|
|
|
$htmlKey = strlen($key) > 0 ? "'<strong>" . qa_html($key) . "</strong>'" : '';
|
|
|
|
echo sprintf(
|
|
'<code class="%s">qa-lang-<strong>%s</strong>.php:%s</code> %s<br>',
|
|
$colorClass, qa_html($prefix), $htmlKey, qa_html($issue)
|
|
);
|
|
}
|
|
|
|
|
|
function output_start_includes()
|
|
{
|
|
global $oneread;
|
|
|
|
$oneread = false;
|
|
|
|
echo '<p class="includes">Reading: ';
|
|
}
|
|
|
|
|
|
function output_reading_include($file)
|
|
{
|
|
global $oneread;
|
|
|
|
echo ($oneread ? ', ' : '') . htmlspecialchars(basename($file));
|
|
flush();
|
|
|
|
$oneread = true;
|
|
}
|
|
|
|
|
|
function output_finish_includes()
|
|
{
|
|
echo '</p>';
|
|
}
|
|
|
|
|
|
echo '<h1>Finished scanning for problems!</h1>';
|
|
|
|
?>
|
|
|
|
</body>
|
|
</html>
|