qa-check-lang.php 8.04 KB
Newer Older
Gideon Greenspan committed
1 2 3 4 5 6 7
<?php

/*
	Question2Answer (c) Gideon Greenspan

	http://www.question2answer.org/

Scott Vivian committed
8

Gideon Greenspan committed
9 10 11 12 13 14 15 16 17
	File: qa-include/qa-check-lang.php
	Version: See define()s at top of qa-include/qa-base.php
	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.
Scott Vivian committed
18

Gideon Greenspan committed
19 20 21 22 23 24 25 26 27 28 29
	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';
Gideon Greenspan committed
30
	require_once QA_INCLUDE_DIR.'qa-app-users.php';
Scott Vivian committed
31

Gideon Greenspan committed
32 33
	if (qa_get_logged_in_level() < QA_USER_LEVEL_ADMIN)
		qa_redirect('admin/general', null, qa_opt('site_url'));
Scott Vivian committed
34

Gideon Greenspan committed
35 36
	header('Content-type: text/html; charset=utf-8');
?>
Gideon Greenspan committed
37 38 39 40 41
<html>
	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
		<title>Question2Answer Language Check</title>
		<style>
Gideon Greenspan committed
42
			code {font-size:125%;}
Gideon Greenspan committed
43 44 45
		</style>
	</head>
	<body style="font-family:arial; font-size:12px;">
Gideon Greenspan committed
46 47 48 49 50 51 52 53 54
<?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]++;
Scott Vivian committed
55

Gideon Greenspan committed
56 57
		return $substitutions;
	}
Scott Vivian committed
58

Gideon Greenspan committed
59 60
	echo '<font color="#cc0000"><code>Dark red = important to review.</code></font><br>';
	echo '<font color="#cc9999"><code>Light red = probably safe to ignore.</code></font>';
Scott Vivian committed
61

Gideon Greenspan committed
62
	echo '<h1>Checking US English files in <code>qa-include</code>...</h1>';
Scott Vivian committed
63

Gideon Greenspan committed
64
	$includefiles=array_merge(glob(QA_INCLUDE_DIR.'qa-*.php'), glob(QA_PLUGIN_DIR.'*/qa-*.php'));
Scott Vivian committed
65

Gideon Greenspan committed
66 67 68 69 70 71 72
	$definite=array();
	$probable=array();
	$possible=array();
	$defined=array();
	$english=array();
	$backmap=array();
	$substitutions=array();
Scott Vivian committed
73

Gideon Greenspan committed
74
	output_start_includes();
Scott Vivian committed
75

Gideon Greenspan committed
76 77
	foreach ($includefiles as $includefile) {
		$contents=file_get_contents($includefile);
Scott Vivian committed
78

Gideon Greenspan committed
79
		preg_match_all('/qa_lang[a-z_]*\s*\(\s*[\'\"]([a-z]+)\/([0-9a-z_]+)[\'\"]/', $contents, $matches, PREG_SET_ORDER);
Scott Vivian committed
80

Gideon Greenspan committed
81 82 83 84 85 86 87
		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]]++;
Scott Vivian committed
88

Gideon Greenspan committed
89 90 91 92 93 94 95
		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];
Scott Vivian committed
96

Gideon Greenspan committed
97 98
			output_reading_include($includefile);
			$phrases=@include $includefile;
Scott Vivian committed
99

Gideon Greenspan committed
100 101 102 103 104 105 106 107 108
			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);
Scott Vivian committed
109

Gideon Greenspan committed
110 111 112 113
			foreach ($matches as $matchparts)
				@$possible[$matchparts[1]]++;
		}
	}
Scott Vivian committed
114

Gideon Greenspan committed
115
	output_finish_includes();
Scott Vivian committed
116

Gideon Greenspan committed
117 118 119 120
	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');
Scott Vivian committed
121

Gideon Greenspan committed
122 123 124 125
	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');
Scott Vivian committed
126

Gideon Greenspan committed
127 128 129 130
	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);
Scott Vivian committed
131

Gideon Greenspan committed
132
	require_once QA_INCLUDE_DIR.'qa-app-admin.php';
Scott Vivian committed
133

Gideon Greenspan committed
134 135
	$languages=qa_admin_language_options();
	unset($languages['']);
Scott Vivian committed
136

Gideon Greenspan committed
137
	foreach ($languages as $code => $language) {
Gideon Greenspan committed
138
		echo '<h1>Checking '.$language.' files in <code>qa-lang/'.$code.'</code>...</h1>';
Scott Vivian committed
139

Gideon Greenspan committed
140 141 142 143 144
		$langdefined=array();
		$langdifferent=array();
		$langsubstitutions=array();
		$langincludefiles=glob(QA_LANG_DIR.$code.'/qa-*.php');
		$langnewphrases=array();
Scott Vivian committed
145

Gideon Greenspan committed
146
		output_start_includes();
Scott Vivian committed
147

Gideon Greenspan committed
148 149 150 151 152 153
		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;
Scott Vivian committed
154

Gideon Greenspan committed
155 156 157 158 159 160
				foreach ($phrases as $key => $value) {
					@$langdefined[$prefix][$key]++;
					$langdifferent[$prefix][$key]=($value!=@$english[$prefix][$key]);
					$langsubstitutions[$prefix][$key]=get_phrase_substitutions($value);
				}
			}
Scott Vivian committed
161

Gideon Greenspan committed
162
		output_finish_includes();
Scott Vivian committed
163

Gideon Greenspan committed
164 165 166 167
		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');
Scott Vivian committed
168

Gideon Greenspan committed
169 170
				elseif (!$langdifferent[$key][$value])
					output_lang_issue($key, $value, 'identical to US English files', false);
Scott Vivian committed
171

Gideon Greenspan committed
172 173 174 175 176 177 178
				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);
			}
Scott Vivian committed
179

Gideon Greenspan committed
180 181
		foreach ($defined as $key => $valuecount) {
			$showaserror=!(($key=='admin') || ($key=='options') || ($code=='en-GB'));
Scott Vivian committed
182

Gideon Greenspan committed
183 184 185 186 187 188 189 190 191 192 193 194 195
			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);
		}
Scott Vivian committed
196

Gideon Greenspan committed
197
		foreach ($langnewphrases as $prefix => $phrases) {
Gideon Greenspan committed
198
			echo '<h2>'.$language.' phrases to add to <code>qa-lang/'.$code.'/qa-lang-'.$prefix.'.php</code>:</h2>';
Scott Vivian committed
199

Gideon Greenspan committed
200
			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.';
Scott Vivian committed
201

Gideon Greenspan committed
202
			echo '<pre>';
Scott Vivian committed
203

Gideon Greenspan committed
204
			foreach ($phrases as $key => $value)
Gideon Greenspan committed
205
				echo '<span style="font-size:25%;">'."\t\t</span>'".$key."' => \"".strtr($value, array('\\' => '\\\\', '"' => '\"', '$' => '\$', "\n" => '\n', "\t" => '\t'))."\",\n";
Scott Vivian committed
206

Gideon Greenspan committed
207
			echo '</pre>';
Gideon Greenspan committed
208 209 210
		}
	}

Scott Vivian committed
211

Gideon Greenspan committed
212 213
	function output_lang_issue($prefix, $key, $issue, $error=true)
	{
Gideon Greenspan committed
214
		echo '<font color="'.($error ? '#cc0000' : '#cc9999').'"><code>';
Gideon Greenspan committed
215

Gideon Greenspan committed
216
		echo 'qa-lang-<b>'.qa_html($prefix).'</b>.php:';
Gideon Greenspan committed
217 218

		if (strlen($key))
Gideon Greenspan committed
219
			echo "'<b>".qa_html($key)."</b>'";
Scott Vivian committed
220

Gideon Greenspan committed
221
		echo '</code></font> &nbsp; '.qa_html($issue).'<br>';
Gideon Greenspan committed
222 223 224 225 226 227
	}


	function output_start_includes()
	{
		global $oneread;
Scott Vivian committed
228

Gideon Greenspan committed
229
		$oneread=false;
Scott Vivian committed
230

Gideon Greenspan committed
231
		echo '<p style="font-size:80%; color:#999;">Reading: ';
Gideon Greenspan committed
232 233
	}

Scott Vivian committed
234

Gideon Greenspan committed
235 236 237
	function output_reading_include($file)
	{
		global $oneread;
Scott Vivian committed
238

Gideon Greenspan committed
239 240
		echo ($oneread ? ', ' : '').htmlspecialchars(basename($file));
		flush();
Scott Vivian committed
241

Gideon Greenspan committed
242 243 244
		$oneread=true;
	}

Scott Vivian committed
245

Gideon Greenspan committed
246 247
	function output_finish_includes()
	{
Gideon Greenspan committed
248
		echo '</p>';
Gideon Greenspan committed
249 250
	}

Scott Vivian committed
251

Gideon Greenspan committed
252
	echo '<h1>Finished scanning for problems!</h1>';
Gideon Greenspan committed
253 254 255

?>

Gideon Greenspan committed
256 257
	</body>
</html>