Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 202 lines (185 sloc) 8.157 kb
667bfec Decomposition
jakubvrana authored
1 <?php
1bc77f8 Report user errors
jakubvrana authored
2 error_reporting(6135); // errors and warnings
e1bc7af Change directory structure
jakubvrana authored
3 include dirname(__FILE__) . "/adminer/include/version.inc.php";
b8b4548 Utilize JSMin
jakubvrana authored
4 include dirname(__FILE__) . "/externals/jsmin-php/jsmin.php";
7f3b4f2 Version checker
jakubvrana authored
5
8943678 sprintf() in lang()
jakubvrana authored
6 function add_apo_slashes($s) {
7 return addcslashes($s, "\\'");
8 }
9
0970a58 Prepare for single language version
jakubvrana authored
10 function remove_lang($match) {
bba76d8 Flatten $translations
jakubvrana authored
11 global $translations;
438ca05 Separate languages
jakubvrana authored
12 $idf = strtr($match[2], array("\\'" => "'", "\\\\" => "\\"));
bba76d8 Flatten $translations
jakubvrana authored
13 $s = ($translations[$idf] ? $translations[$idf] : $idf);
64ba924 Comments
jakubvrana authored
14 if ($match[3] == ",") { // lang() has parameters
8943678 sprintf() in lang()
jakubvrana authored
15 return "$match[1]" . (is_array($s) ? "lang(array('" . implode("', '", array_map('add_apo_slashes', $s)) . "')," : "sprintf('" . add_apo_slashes($s) . "',");
16 }
17 return ($match[1] && $match[4] ? $s : "$match[1]'" . add_apo_slashes($s) . "'$match[4]");
0970a58 Prepare for single language version
jakubvrana authored
18 }
19
64ba924 Comments
jakubvrana authored
20 $lang_ids = array(); // global variable simplifies usage in a callback function
c16c57b E-mail sending
jakubvrana authored
21
4738060 Use numeric language IDs to save bytes
jakubvrana authored
22 function lang_ids($match) {
23 global $lang_ids;
c16c57b E-mail sending
jakubvrana authored
24 $lang_id = &$lang_ids[stripslashes($match[1])];
25 if (!isset($lang_id)) {
26 $lang_id = count($lang_ids) - 1;
27 }
0116b9d Don't set cookie in compile scripts
jakubvrana authored
28 return ($_SESSION["lang"] ? $match[0] : "lang($lang_id$match[2]");
4738060 Use numeric language IDs to save bytes
jakubvrana authored
29 }
30
667bfec Decomposition
jakubvrana authored
31 function put_file($match) {
c16c57b E-mail sending
jakubvrana authored
32 global $project;
b95f24e Editor: User friendly data editor
jakubvrana authored
33 if (basename($match[2]) == '$LANG.inc.php') {
c16c57b E-mail sending
jakubvrana authored
34 return $match[0]; // processed later
438ca05 Separate languages
jakubvrana authored
35 }
b95f24e Editor: User friendly data editor
jakubvrana authored
36 $return = file_get_contents(dirname(__FILE__) . "/$project/$match[2]");
0116b9d Don't set cookie in compile scripts
jakubvrana authored
37 if (basename($match[2]) != "lang.inc.php" || !$_SESSION["lang"]) {
64ba924 Comments
jakubvrana authored
38 $tokens = token_get_all($return); // to find out the last token
6bb1401 Remove ?><?php
jakubvrana authored
39 return "?>\n$return" . (in_array($tokens[count($tokens) - 1][0], array(T_CLOSE_TAG, T_INLINE_HTML), true) ? "<?php" : "");
40 } elseif (preg_match('~\\s*(\\$pos = .*)~', $return, $match2)) {
64ba924 Comments
jakubvrana authored
41 // single language lang() is used for plural
0116b9d Don't set cookie in compile scripts
jakubvrana authored
42 return "function lang(\$translation, \$number) {\n\t" . str_replace('$LANG', "'$_SESSION[lang]'", $match2[1]) . "\n\treturn sprintf(\$translation[\$pos], \$number);\n}\n";
6bb1401 Remove ?><?php
jakubvrana authored
43 } else {
44 echo "lang() not found\n";
667bfec Decomposition
jakubvrana authored
45 }
46 }
47
c16c57b E-mail sending
jakubvrana authored
48 function put_file_lang($match) {
49 global $lang_ids, $project;
0116b9d Don't set cookie in compile scripts
jakubvrana authored
50 if ($_SESSION["lang"]) {
c16c57b E-mail sending
jakubvrana authored
51 return "";
52 }
53 $return = "";
ea4fd61 Join translations
jakubvrana authored
54 foreach (glob(dirname(__FILE__) . "/adminer/lang/*.inc.php") as $filename) {
c16c57b E-mail sending
jakubvrana authored
55 include $filename; // assign $translations
56 $translation_ids = array_flip($lang_ids); // default translation
57 foreach ($translations as $key => $val) {
58 if (isset($val)) {
59 $translation_ids[$lang_ids[$key]] = $val;
60 }
61 }
62 $return .= "\tcase \"" . basename($filename, '.inc.php') . '": $translations = array(';
63 foreach ($translation_ids as $val) {
64 $return .= (is_array($val) ? "array('" . implode("', '", array_map('add_apo_slashes', $val)) . "')" : "'" . add_apo_slashes($val) . "'") . ", ";
65 }
66 $return = substr($return, 0, -2) . "); break;\n";
67 }
68 return "switch (\$LANG) {\n$return}\n";
69 }
70
16f4210 Function minification
jakubvrana authored
71 function short_identifier($number, $chars) {
72 $return = '';
a06f4c1 Size reduction by minification of variables
jakubvrana authored
73 while ($number >= 0) {
74 $return .= $chars{$number % strlen($chars)};
75 $number = floor($number / strlen($chars)) - 1;
76 }
77 return $return;
78 }
79
004d7a9 Link
jakubvrana authored
80 // based on http://latrine.dgx.cz/jak-zredukovat-php-skripty
794192d php_shrink()
jakubvrana authored
81 function php_shrink($input) {
815eb26 Use one token for all
jakubvrana authored
82 $special_variables = array_flip(array('$this', '$GLOBALS', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_SERVER'));
a06f4c1 Size reduction by minification of variables
jakubvrana authored
83 static $short_variables = array();
84 $shortening = true;
16f4210 Function minification
jakubvrana authored
85 $tokens = token_get_all($input);
86
87 foreach ($tokens as $i => $token) {
88 if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
89 $short_variables[$token[1]]++;
90 }
91 }
c27a877 Minify defined functions only
jakubvrana authored
92
16f4210 Function minification
jakubvrana authored
93 arsort($short_variables);
94 foreach (array_keys($short_variables) as $number => $key) {
95 $short_variables[$key] = short_identifier($number, implode("", range('a', 'z')) . '_' . implode("", range('A', 'Z'))); // could use also numbers and \x7f-\xff
96 }
a06f4c1 Size reduction by minification of variables
jakubvrana authored
97
794192d php_shrink()
jakubvrana authored
98 $set = array_flip(preg_split('//', '!"#$&\'()*+,-./:;<=>?@[\]^`{|}'));
99 $space = '';
100 $output = '';
ff85f12 Join echos
jakubvrana authored
101 $in_echo = false;
c16c57b E-mail sending
jakubvrana authored
102 $doc_comment = false; // include only first /**
ff85f12 Join echos
jakubvrana authored
103 for (reset($tokens); list($i, $token) = each($tokens); ) {
794192d php_shrink()
jakubvrana authored
104 if (!is_array($token)) {
105 $token = array(0, $token);
106 }
dbf9566 Better consecutive echo handling
jakubvrana authored
107 if ($tokens[$i+2][0] === T_CLOSE_TAG && $tokens[$i+3][0] === T_INLINE_HTML && $tokens[$i+4][0] === T_OPEN_TAG
108 && strlen(addcslashes($tokens[$i+3][1], "'\\")) < strlen($tokens[$i+3][1]) + 3
109 ) {
110 $tokens[$i+2] = array(T_ECHO, 'echo');
111 $tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . addcslashes($tokens[$i+3][1], "'\\") . "'");
112 $tokens[$i+4] = array(0, ';');
113 }
c16c57b E-mail sending
jakubvrana authored
114 if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
794192d php_shrink()
jakubvrana authored
115 $space = "\n";
116 } else {
c16c57b E-mail sending
jakubvrana authored
117 if ($token[0] == T_DOC_COMMENT) {
118 $doc_comment = true;
119 }
a06f4c1 Size reduction by minification of variables
jakubvrana authored
120 if ($token[0] == T_VAR) {
121 $shortening = false;
122 } elseif (!$shortening) {
123 if ($token[1] == ';') {
124 $shortening = true;
125 }
ff85f12 Join echos
jakubvrana authored
126 } elseif ($token[0] == T_ECHO) {
127 $in_echo = true;
128 } elseif ($token[1] == ';' && $in_echo) {
e2bc1da No comments without whitespace
jakubvrana authored
129 if ($tokens[$i+1][0] === T_WHITESPACE && $tokens[$i+2][0] === T_ECHO) {
ff85f12 Join echos
jakubvrana authored
130 next($tokens);
c030c16 Compile inline HTML to echo
jakubvrana authored
131 $i++;
132 }
133 if ($tokens[$i+1][0] === T_ECHO) {
134 // join two consecutive echos
ff85f12 Join echos
jakubvrana authored
135 next($tokens);
058e101 Resolve conflict
jakubvrana authored
136 $token[1] = ','; // '.' would conflict with "a".1+2 and would use more memory //! remove ',' and ","
dbf9566 Better consecutive echo handling
jakubvrana authored
137 } else {
138 $in_echo = false;
ff85f12 Join echos
jakubvrana authored
139 }
16f4210 Function minification
jakubvrana authored
140 } elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
141 $token[1] = '$' . $short_variables[$token[1]];
a06f4c1 Size reduction by minification of variables
jakubvrana authored
142 }
794192d php_shrink()
jakubvrana authored
143 if (isset($set[substr($output, -1)]) || isset($set[$token[1]{0}])) {
144 $space = '';
145 }
146 $output .= $space . $token[1];
147 $space = '';
148 }
149 }
150 return $output;
151 }
152
9ee9cf0 Remove code generation
jakubvrana authored
153 function minify_css($file) {
154 return preg_replace('~\\s*([:;{},])\\s*~', '\\1', $file);
155 }
156
157 function compile_file($match) {
df03f4f Join editing.js in compilation
jakubvrana authored
158 global $project;
159 return call_user_func($match[2], file_get_contents(dirname(__FILE__) . "/$project/$match[1]"));
9ee9cf0 Remove code generation
jakubvrana authored
160 }
161
b95f24e Editor: User friendly data editor
jakubvrana authored
162 $project = "adminer";
943a3e8 Find adminer/ in compile.php directory
jakubvrana authored
163 if (file_exists(dirname(__FILE__) . "/" . $_SERVER["argv"][1] . "/index.php")) {
0f850a6 Allow compilation of all languages Editor
jakubvrana authored
164 $project = $_SERVER["argv"][1];
165 array_shift($_SERVER["argv"]);
166 }
0116b9d Don't set cookie in compile scripts
jakubvrana authored
167 unset($_COOKIE["adminer_lang"]);
168 $_SESSION["lang"] = $_SERVER["argv"][1]; // Adminer functions read language from session
169 if (isset($_SESSION["lang"])) {
e1bc7af Change directory structure
jakubvrana authored
170 include dirname(__FILE__) . "/adminer/include/lang.inc.php";
0116b9d Don't set cookie in compile scripts
jakubvrana authored
171 if (isset($_SERVER["argv"][2]) || !isset($langs[$_SESSION["lang"]])) {
0f850a6 Allow compilation of all languages Editor
jakubvrana authored
172 echo "Usage: php compile.php [adminer] [lang]\nPurpose: Compile adminer[-lang].php from adminer/index.php.\n";
7418af0 Czech translation
jakubvrana authored
173 exit(1);
174 }
0116b9d Don't set cookie in compile scripts
jakubvrana authored
175 include dirname(__FILE__) . "/adminer/lang/$_SESSION[lang].inc.php";
7418af0 Czech translation
jakubvrana authored
176 }
bba76d8 Flatten $translations
jakubvrana authored
177
b95f24e Editor: User friendly data editor
jakubvrana authored
178 $file = file_get_contents(dirname(__FILE__) . "/$project/index.php");
6bb1401 Remove ?><?php
jakubvrana authored
179 $file = preg_replace_callback('~\\b(include|require) "([^"]*)";~', 'put_file', $file);
70c8343 Save coverage to database
jakubvrana authored
180 $file = str_replace('include "../adminer/include/coverage.inc.php";', '', $file);
c16c57b E-mail sending
jakubvrana authored
181 $file = preg_replace_callback('~\\b(include|require) "([^"]*)";~', 'put_file', $file); // bootstrap.inc.php
182 $file = preg_replace_callback("~lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])~s", 'lang_ids', $file);
183 $file = preg_replace_callback('~\\b(include|require) "([^"]*\\$LANG.inc.php)";~', 'put_file_lang', $file);
0116b9d Don't set cookie in compile scripts
jakubvrana authored
184 if ($_SESSION["lang"]) {
64ba924 Comments
jakubvrana authored
185 // single language version
a9907f1 Greedy expressions
jakubvrana authored
186 $file = preg_replace_callback("~(<\\?php\\s*echo )?lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])(;\\s*\\?>)?~s", 'remove_lang', $file);
7418af0 Czech translation
jakubvrana authored
187 $file = str_replace("<?php switch_lang(); ?>\n", "", $file);
0116b9d Don't set cookie in compile scripts
jakubvrana authored
188 $file = str_replace('<?php echo $LANG; ?>', $_SESSION["lang"], $file);
0970a58 Prepare for single language version
jakubvrana authored
189 }
df03f4f Join editing.js in compilation
jakubvrana authored
190 $file = str_replace('<script type="text/javascript" src="editing.js"></script>' . "\n", "", $file);
191 $file = preg_replace_callback("~compile_file\\('([^']+)', '([^']+)'\\);~", 'compile_file', $file); // integrate static files
689699a Shortcut for htmlspecialchars
jakubvrana authored
192 $replace = 'h(preg_replace("~\\\\\\\\?.*~", "", $_SERVER["REQUEST_URI"])) . "?file=\\1&amp;version=' . $VERSION;
e1abcda Treat tinyint(1) as boolean
jakubvrana authored
193 $file = preg_replace('~\\.\\./adminer/(default\\.css|functions\\.js|favicon\\.ico)~', '<?php echo ' . $replace . '"; ?>', $file);
b95f24e Editor: User friendly data editor
jakubvrana authored
194 $file = preg_replace('~\\.\\./adminer/((plus|cross|up|down|arrow)\\.gif)~', '" . ' . $replace, $file);
b3fc4c0 Download externals from HTTPS
jakubvrana authored
195 $file = str_replace("../externals/jush/", "https://jush.svn.sourceforge.net/svnroot/jush/trunk/", $file); // mixed-content warning if Adminer runs on HTTPS and external files on HTTP
35bca85 Fix XSS (thanks to Synopsi)
jakubvrana authored
196 $file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
794192d php_shrink()
jakubvrana authored
197 $file = php_shrink($file);
c02bd44 Use $filename
jakubvrana authored
198
0116b9d Don't set cookie in compile scripts
jakubvrana authored
199 $filename = $project . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";
c02bd44 Use $filename
jakubvrana authored
200 fwrite(fopen($filename, "w"), $file); // file_put_contents() since PHP 5
7418af0 Czech translation
jakubvrana authored
201 echo "$filename created.\n";
Something went wrong with that request. Please try again.