Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 303 lines (282 sloc) 12.084 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";
bf4f0a1 @vrana Replace JSMin by JsShrink
authored
4 include dirname(__FILE__) . "/externals/JsShrink/jsShrink.php";
7f3b4f2 Version checker
jakubvrana authored
5
bf4f0a1 @vrana Replace JSMin by JsShrink
authored
6 if (!function_exists('jsShrink')) {
7 function jsShrink($code) {
8 return $code;
c1f8382 @vrana Internal JSMin if external is not found
authored
9 }
10 }
11
8943678 sprintf() in lang()
jakubvrana authored
12 function add_apo_slashes($s) {
13 return addcslashes($s, "\\'");
14 }
15
0970a58 Prepare for single language version
jakubvrana authored
16 function remove_lang($match) {
bba76d8 Flatten $translations
jakubvrana authored
17 global $translations;
438ca05 Separate languages
jakubvrana authored
18 $idf = strtr($match[2], array("\\'" => "'", "\\\\" => "\\"));
bba76d8 Flatten $translations
jakubvrana authored
19 $s = ($translations[$idf] ? $translations[$idf] : $idf);
64ba924 Comments
jakubvrana authored
20 if ($match[3] == ",") { // lang() has parameters
8943678 sprintf() in lang()
jakubvrana authored
21 return "$match[1]" . (is_array($s) ? "lang(array('" . implode("', '", array_map('add_apo_slashes', $s)) . "')," : "sprintf('" . add_apo_slashes($s) . "',");
22 }
23 return ($match[1] && $match[4] ? $s : "$match[1]'" . add_apo_slashes($s) . "'$match[4]");
0970a58 Prepare for single language version
jakubvrana authored
24 }
25
4738060 Use numeric language IDs to save bytes
jakubvrana authored
26 function lang_ids($match) {
27 global $lang_ids;
c16c57b E-mail sending
jakubvrana authored
28 $lang_id = &$lang_ids[stripslashes($match[1])];
6591d48 @vrana Replace isset($var) by $var !== null
authored
29 if ($lang_id === null) {
c16c57b E-mail sending
jakubvrana authored
30 $lang_id = count($lang_ids) - 1;
31 }
0116b9d Don't set cookie in compile scripts
jakubvrana authored
32 return ($_SESSION["lang"] ? $match[0] : "lang($lang_id$match[2]");
4738060 Use numeric language IDs to save bytes
jakubvrana authored
33 }
34
667bfec Decomposition
jakubvrana authored
35 function put_file($match) {
c16c57b E-mail sending
jakubvrana authored
36 global $project;
b95f24e Editor: User friendly data editor
jakubvrana authored
37 if (basename($match[2]) == '$LANG.inc.php') {
c16c57b E-mail sending
jakubvrana authored
38 return $match[0]; // processed later
438ca05 Separate languages
jakubvrana authored
39 }
b95f24e Editor: User friendly data editor
jakubvrana authored
40 $return = file_get_contents(dirname(__FILE__) . "/$project/$match[2]");
0116b9d Don't set cookie in compile scripts
jakubvrana authored
41 if (basename($match[2]) != "lang.inc.php" || !$_SESSION["lang"]) {
64ba924 Comments
jakubvrana authored
42 $tokens = token_get_all($return); // to find out the last token
6bb1401 Remove ?><?php
jakubvrana authored
43 return "?>\n$return" . (in_array($tokens[count($tokens) - 1][0], array(T_CLOSE_TAG, T_INLINE_HTML), true) ? "<?php" : "");
9a4cabe @vrana Simplify single language version
authored
44 } elseif (preg_match('~\\s*(\\$pos = (.+\n).+;)~sU', $return, $match2)) {
64ba924 Comments
jakubvrana authored
45 // single language lang() is used for plural
e37c427 @vrana Function get_lang useful for customization
authored
46 return "function get_lang() {
47 return '$_SESSION[lang]';
48 }
49
50 function lang(\$translation, \$number) {
9a4cabe @vrana Simplify single language version
authored
51 \$pos = $match2[2]\t\t: " . (preg_match("~\\\$LANG == '$_SESSION[lang]'.* \\? (.+)\n~U", $match2[1], $match3) ? $match3[1] : "1") . '
52 );
e37c427 @vrana Function get_lang useful for customization
authored
53 return sprintf($translation[$pos], $number);
54 }
55 ';
6bb1401 Remove ?><?php
jakubvrana authored
56 } else {
57 echo "lang() not found\n";
667bfec Decomposition
jakubvrana authored
58 }
59 }
60
c16c57b E-mail sending
jakubvrana authored
61 function put_file_lang($match) {
b4b5977 @vrana Include only active translations
authored
62 global $lang_ids, $project, $langs;
0116b9d Don't set cookie in compile scripts
jakubvrana authored
63 if ($_SESSION["lang"]) {
c16c57b E-mail sending
jakubvrana authored
64 return "";
65 }
66 $return = "";
b4b5977 @vrana Include only active translations
authored
67 foreach ($langs as $lang => $val) {
68 include dirname(__FILE__) . "/adminer/lang/$lang.inc.php"; // assign $translations
c16c57b E-mail sending
jakubvrana authored
69 $translation_ids = array_flip($lang_ids); // default translation
70 foreach ($translations as $key => $val) {
6591d48 @vrana Replace isset($var) by $var !== null
authored
71 if ($val !== null) {
c16c57b E-mail sending
jakubvrana authored
72 $translation_ids[$lang_ids[$key]] = $val;
73 }
74 }
b4b5977 @vrana Include only active translations
authored
75 $return .= "\tcase \"$lang\": \$translations = array(";
c16c57b E-mail sending
jakubvrana authored
76 foreach ($translation_ids as $val) {
77 $return .= (is_array($val) ? "array('" . implode("', '", array_map('add_apo_slashes', $val)) . "')" : "'" . add_apo_slashes($val) . "'") . ", ";
78 }
79 $return = substr($return, 0, -2) . "); break;\n";
80 }
81 return "switch (\$LANG) {\n$return}\n";
82 }
83
16f4210 Function minification
jakubvrana authored
84 function short_identifier($number, $chars) {
85 $return = '';
a06f4c1 Size reduction by minification of variables
jakubvrana authored
86 while ($number >= 0) {
b0666e5 @vrana Remove unnecessary { } in compile
authored
87 $return .= $chars[$number % strlen($chars)];
a06f4c1 Size reduction by minification of variables
jakubvrana authored
88 $number = floor($number / strlen($chars)) - 1;
89 }
90 return $return;
91 }
92
004d7a9 Link
jakubvrana authored
93 // based on http://latrine.dgx.cz/jak-zredukovat-php-skripty
794192d php_shrink()
jakubvrana authored
94 function php_shrink($input) {
cbdf09d @vrana Show version in comment (thanks to David Grudl)
authored
95 global $VERSION;
815eb26 Use one token for all
jakubvrana authored
96 $special_variables = array_flip(array('$this', '$GLOBALS', '$_GET', '$_POST', '$_FILES', '$_COOKIE', '$_SESSION', '$_SERVER'));
12d2c6d Build Adminer and Editor together
jakubvrana authored
97 $short_variables = array();
a06f4c1 Size reduction by minification of variables
jakubvrana authored
98 $shortening = true;
16f4210 Function minification
jakubvrana authored
99 $tokens = token_get_all($input);
100
b0666e5 @vrana Remove unnecessary { } in compile
authored
101 // remove unnecessary { }
102 //! change also `while () { if () {;} }` to `while () if () ;` but be careful about `if () { if () { } } else { }
103 $shorten = 0;
104 $opening = -1;
105 foreach ($tokens as $i => $token) {
106 if (in_array($token[0], array(T_IF, T_ELSE, T_ELSEIF, T_WHILE, T_DO, T_FOR, T_FOREACH), true)) {
107 $shorten = ($token[0] == T_FOR ? 4 : 2);
108 $opening = -1;
109 } elseif (in_array($token[0], array(T_SWITCH, T_FUNCTION, T_CLASS, T_CLOSE_TAG), true)) {
110 $shorten = 0;
111 } elseif ($token === ';') {
112 $shorten--;
113 } elseif ($token === '{') {
114 if ($opening < 0) {
115 $opening = $i;
116 } elseif ($shorten > 1) {
117 $shorten = 0;
118 }
119 } elseif ($token === '}' && $opening >= 0 && $shorten == 1) {
120 unset($tokens[$opening]);
121 unset($tokens[$i]);
122 $shorten = 0;
123 $opening = -1;
124 }
125 }
126 $tokens = array_values($tokens);
127
16f4210 Function minification
jakubvrana authored
128 foreach ($tokens as $i => $token) {
129 if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
130 $short_variables[$token[1]]++;
131 }
132 }
c27a877 Minify defined functions only
jakubvrana authored
133
16f4210 Function minification
jakubvrana authored
134 arsort($short_variables);
0ced6d3 @vrana Preserve short variable names between versions if possible
authored
135 $chars = implode(range('a', 'z')) . '_' . implode(range('A', 'Z'));
136 // preserve variable names between versions if possible
137 $short_variables2 = array_splice($short_variables, strlen($chars));
138 ksort($short_variables);
139 ksort($short_variables2);
140 $short_variables += $short_variables2;
16f4210 Function minification
jakubvrana authored
141 foreach (array_keys($short_variables) as $number => $key) {
0ced6d3 @vrana Preserve short variable names between versions if possible
authored
142 $short_variables[$key] = short_identifier($number, $chars); // could use also numbers and \x7f-\xff
16f4210 Function minification
jakubvrana authored
143 }
a06f4c1 Size reduction by minification of variables
jakubvrana authored
144
794192d php_shrink()
jakubvrana authored
145 $set = array_flip(preg_split('//', '!"#$&\'()*+,-./:;<=>?@[\]^`{|}'));
146 $space = '';
147 $output = '';
ff85f12 Join echos
jakubvrana authored
148 $in_echo = false;
c16c57b E-mail sending
jakubvrana authored
149 $doc_comment = false; // include only first /**
ff85f12 Join echos
jakubvrana authored
150 for (reset($tokens); list($i, $token) = each($tokens); ) {
794192d php_shrink()
jakubvrana authored
151 if (!is_array($token)) {
152 $token = array(0, $token);
153 }
dbf9566 Better consecutive echo handling
jakubvrana authored
154 if ($tokens[$i+2][0] === T_CLOSE_TAG && $tokens[$i+3][0] === T_INLINE_HTML && $tokens[$i+4][0] === T_OPEN_TAG
fc3b652 Whitespace
jakubvrana authored
155 && strlen(addcslashes($tokens[$i+3][1], "'\\")) < strlen($tokens[$i+3][1]) + 3
dbf9566 Better consecutive echo handling
jakubvrana authored
156 ) {
157 $tokens[$i+2] = array(T_ECHO, 'echo');
158 $tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . addcslashes($tokens[$i+3][1], "'\\") . "'");
159 $tokens[$i+4] = array(0, ';');
160 }
c16c57b E-mail sending
jakubvrana authored
161 if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
794192d php_shrink()
jakubvrana authored
162 $space = "\n";
163 } else {
c16c57b E-mail sending
jakubvrana authored
164 if ($token[0] == T_DOC_COMMENT) {
165 $doc_comment = true;
cbdf09d @vrana Show version in comment (thanks to David Grudl)
authored
166 $token[1] = substr_replace($token[1], "* @version $VERSION\n", -2, 0);
c16c57b E-mail sending
jakubvrana authored
167 }
a06f4c1 Size reduction by minification of variables
jakubvrana authored
168 if ($token[0] == T_VAR) {
169 $shortening = false;
170 } elseif (!$shortening) {
171 if ($token[1] == ';') {
172 $shortening = true;
173 }
ff85f12 Join echos
jakubvrana authored
174 } elseif ($token[0] == T_ECHO) {
175 $in_echo = true;
176 } elseif ($token[1] == ';' && $in_echo) {
e2bc1da No comments without whitespace
jakubvrana authored
177 if ($tokens[$i+1][0] === T_WHITESPACE && $tokens[$i+2][0] === T_ECHO) {
ff85f12 Join echos
jakubvrana authored
178 next($tokens);
c030c16 Compile inline HTML to echo
jakubvrana authored
179 $i++;
180 }
181 if ($tokens[$i+1][0] === T_ECHO) {
182 // join two consecutive echos
ff85f12 Join echos
jakubvrana authored
183 next($tokens);
02046d6 Windows support in e-mail attachments
jakubvrana authored
184 $token[1] = ','; // '.' would conflict with "a".1+2 and would use more memory //! remove ',' and "," but not $var","
dbf9566 Better consecutive echo handling
jakubvrana authored
185 } else {
186 $in_echo = false;
ff85f12 Join echos
jakubvrana authored
187 }
16f4210 Function minification
jakubvrana authored
188 } elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
189 $token[1] = '$' . $short_variables[$token[1]];
a06f4c1 Size reduction by minification of variables
jakubvrana authored
190 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
191 if (isset($set[substr($output, -1)]) || isset($set[$token[1][0]])) {
794192d php_shrink()
jakubvrana authored
192 $space = '';
193 }
194 $output .= $space . $token[1];
195 $space = '';
196 }
197 }
198 return $output;
199 }
200
9ee9cf0 Remove code generation
jakubvrana authored
201 function minify_css($file) {
1be289e @vrana Optimize compiling files
authored
202 return preg_replace('~\\s*([:;{},])\\s*~', '\\1', preg_replace('~/\\*.*\\*/~sU', '', $file));
9ee9cf0 Remove code generation
jakubvrana authored
203 }
204
205 function compile_file($match) {
df03f4f Join editing.js in compilation
jakubvrana authored
206 global $project;
207 return call_user_func($match[2], file_get_contents(dirname(__FILE__) . "/$project/$match[1]"));
9ee9cf0 Remove code generation
jakubvrana authored
208 }
209
e672694 @vrana Rename $driver to $jush
authored
210 $driver = "";
3f5b683 Reintegrate sqlite branch
jakubvrana authored
211 if (file_exists(dirname(__FILE__) . "/adminer/drivers/" . $_SERVER["argv"][1] . ".inc.php")) {
e672694 @vrana Rename $driver to $jush
authored
212 $driver = $_SERVER["argv"][1];
3f5b683 Reintegrate sqlite branch
jakubvrana authored
213 array_shift($_SERVER["argv"]);
214 }
215
0116b9d Don't set cookie in compile scripts
jakubvrana authored
216 unset($_COOKIE["adminer_lang"]);
217 $_SESSION["lang"] = $_SERVER["argv"][1]; // Adminer functions read language from session
3f5b683 Reintegrate sqlite branch
jakubvrana authored
218 include dirname(__FILE__) . "/adminer/include/lang.inc.php";
0116b9d Don't set cookie in compile scripts
jakubvrana authored
219 if (isset($_SESSION["lang"])) {
220 if (isset($_SERVER["argv"][2]) || !isset($langs[$_SESSION["lang"]])) {
7e97fcd Compile usage
Jakub Vrana authored
221 echo "Usage: php compile.php [driver] [lang]\nPurpose: Compile adminer[-driver][-lang].php and editor[-driver][-lang].php.\n";
7418af0 Czech translation
jakubvrana authored
222 exit(1);
223 }
0116b9d Don't set cookie in compile scripts
jakubvrana authored
224 include dirname(__FILE__) . "/adminer/lang/$_SESSION[lang].inc.php";
7418af0 Czech translation
jakubvrana authored
225 }
bba76d8 Flatten $translations
jakubvrana authored
226
3f5b683 Reintegrate sqlite branch
jakubvrana authored
227 // check function definition in drivers
228 $filename = dirname(__FILE__) . "/adminer/drivers/mysql.inc.php";
229 preg_match_all('~\\bfunction ([^(]+)~', file_get_contents($filename), $matches); //! respect context (extension, class)
230 $functions = array_combine($matches[1], $matches[0]);
231 unset($functions["__destruct"], $functions["Min_DB"], $functions["Min_Result"]);
e672694 @vrana Rename $driver to $jush
authored
232 foreach (glob(dirname(__FILE__) . "/adminer/drivers/" . ($driver ? $driver : "*") . ".inc.php") as $filename) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
233 if ($filename != "mysql.inc.php") {
234 $file = file_get_contents($filename);
235 foreach ($functions as $val) {
236 if (!strpos($file, "$val(")) {
237 echo "Missing $val in $filename\n";
238 }
239 }
240 }
241 }
242
e672694 @vrana Rename $driver to $jush
authored
243 include dirname(__FILE__) . "/adminer/include/pdo.inc.php";
955e6b4 @vrana PostgreSQL supports only functions
authored
244 $features = array("call" => "routine", "dump", "event", "privileges", "procedure" => "routine", "processlist", "routine", "scheme", "sequence", "status", "trigger", "type", "user" => "privileges", "variables", "view");
12d2c6d Build Adminer and Editor together
jakubvrana authored
245 foreach (array("adminer", "editor") as $project) {
246 $lang_ids = array(); // global variable simplifies usage in a callback function
247 $file = file_get_contents(dirname(__FILE__) . "/$project/index.php");
e672694 @vrana Rename $driver to $jush
authored
248 if ($driver) {
6420c58 Schema support for PostgreSQL
jakubvrana authored
249 $connection = (object) array("server_info" => 5.1); // MySQL support is version specific
e672694 @vrana Rename $driver to $jush
authored
250 $_GET[$driver] = true; // to load the driver
251 include_once dirname(__FILE__) . "/adminer/drivers/$driver.inc.php";
955e6b4 @vrana PostgreSQL supports only functions
authored
252 foreach ($features as $key => $feature) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
253 if (!support($feature)) {
955e6b4 @vrana PostgreSQL supports only functions
authored
254 if (!is_int($key)) {
255 $feature = $key;
256 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
257 $file = str_replace("} elseif (isset(\$_GET[\"$feature\"])) {\n\tinclude \"./$feature.inc.php\";\n", "", $file);
258 }
259 }
260 if (!support("routine")) {
261 $file = str_replace("if (isset(\$_GET[\"callf\"])) {\n\t\$_GET[\"call\"] = \$_GET[\"callf\"];\n}\nif (isset(\$_GET[\"function\"])) {\n\t\$_GET[\"procedure\"] = \$_GET[\"function\"];\n}\n", "", $file);
262 }
263 }
12d2c6d Build Adminer and Editor together
jakubvrana authored
264 $file = preg_replace_callback('~\\b(include|require) "([^"]*)";~', 'put_file', $file);
265 $file = str_replace('include "../adminer/include/coverage.inc.php";', '', $file);
e672694 @vrana Rename $driver to $jush
authored
266 if ($driver) {
267 $file = preg_replace('(include "../adminer/drivers/(?!' . preg_quote($driver) . ').*\\s*)', '', $file);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
268 }
12d2c6d Build Adminer and Editor together
jakubvrana authored
269 $file = preg_replace_callback('~\\b(include|require) "([^"]*)";~', 'put_file', $file); // bootstrap.inc.php
e678e46 @vrana Remove unsupported features in single driver version
authored
270 if ($driver) {
271 foreach ($features as $feature) {
272 if (!support($feature)) {
273 $file = preg_replace("((\t*)" . preg_quote('if (support("' . $feature . '")') . ".*\n\\1\\})sU", '', $file);
274 }
275 }
4b9d451 @vrana SQLite version supports two systems
authored
276 if (count($drivers) == 1) {
30cfa61 @vrana Fix MySQL only version
authored
277 $file = str_replace('<?php echo html_select("driver", $drivers, DRIVER); ?>', "<input type='hidden' name='driver' value='" . ($driver == "mysql" ? "server" : $driver) . "'>" . reset($drivers), $file);
4b9d451 @vrana SQLite version supports two systems
authored
278 }
e678e46 @vrana Remove unsupported features in single driver version
authored
279 }
12d2c6d Build Adminer and Editor together
jakubvrana authored
280 $file = preg_replace_callback("~lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])~s", 'lang_ids', $file);
281 $file = preg_replace_callback('~\\b(include|require) "([^"]*\\$LANG.inc.php)";~', 'put_file_lang', $file);
53804a2 @vrana Immunity against CRLF
authored
282 $file = str_replace("\r", "", $file);
12d2c6d Build Adminer and Editor together
jakubvrana authored
283 if ($_SESSION["lang"]) {
284 // single language version
285 $file = preg_replace_callback("~(<\\?php\\s*echo )?lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])(;\\s*\\?>)?~s", 'remove_lang', $file);
286 $file = str_replace("<?php switch_lang(); ?>\n", "", $file);
287 $file = str_replace('<?php echo $LANG; ?>', $_SESSION["lang"], $file);
288 }
289 $file = str_replace('<script type="text/javascript" src="static/editing.js"></script>' . "\n", "", $file);
290 $file = preg_replace_callback("~compile_file\\('([^']+)', '([^']+)'\\);~", 'compile_file', $file); // integrate static files
1be289e @vrana Optimize compiling files
authored
291 $replace = 'h(preg_replace("~\\\\\\\\?.*~", "", ME)) . "?file=\\1&amp;version=' . $VERSION;
4815c7d @vrana Don't use AJAX links and forms
authored
292 $file = preg_replace('~\\.\\./adminer/static/(default\\.css|functions\\.js|favicon\\.ico)~', '<?php echo ' . $replace . '"; ?>', $file);
12d2c6d Build Adminer and Editor together
jakubvrana authored
293 $file = preg_replace('~\\.\\./adminer/static/([^\'"]*)~', '" . ' . $replace, $file);
e4deeb6 @vrana Utilize location.protocol
authored
294 $file = str_replace("'../externals/jush/'", "location.protocol + '//www.adminer.org/static/'", $file);
bf54c13 @vrana Highlight code in textarea by CodeMirror
authored
295 $file = str_replace('"../externals/CodeMirror2"', '($_SERVER["HTTPS"] ? "https" : "http") . "://www.adminer.org/static/CodeMirror2"', $file);
12d2c6d Build Adminer and Editor together
jakubvrana authored
296 $file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
297 $file = php_shrink($file);
c02bd44 Use $filename
jakubvrana authored
298
e672694 @vrana Rename $driver to $jush
authored
299 $filename = $project . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";
12d2c6d Build Adminer and Editor together
jakubvrana authored
300 fwrite(fopen($filename, "w"), $file); // file_put_contents() since PHP 5
3f5b683 Reintegrate sqlite branch
jakubvrana authored
301 echo "$filename created (" . strlen($file) . " B).\n";
12d2c6d Build Adminer and Editor together
jakubvrana authored
302 }
Something went wrong with that request. Please try again.