Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 266 lines (246 sloc) 11.081 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
c1f8382 @vrana Internal JSMin if external is not found
authored
6 if (!class_exists("JSMin")) {
7 /** Simple JS minifier without full support for regex literals
8 * @link http://pastebin.com/2Jc2swSr
9 */
10 class JSMin {
11 /*private static*/ function callback($match) {
12 $s = trim($match[0]);
13 return ($s === "" ? "\n" : ($s[0] === "/" && ($s[1] === "*" || $s[1] === "/") ? "" : $s));
14 }
15
16 /*static*/ function minify($input) {
17 return preg_replace_callback('~//[^\n]*|/\*.*?\*/|/(?!\s)(?:\\\\.|[^/\\\\])*/|\'(?:\\\\.|[^\'\\\\])*\'|"(?:\\\\.|[^"\\\\])*"|\s*[^0-9a-z_$\'"/\s]\s*|\s+~si', array('JSMin', 'callback'), $input);
18 }
19 }
20 }
21
8943678 sprintf() in lang()
jakubvrana authored
22 function add_apo_slashes($s) {
23 return addcslashes($s, "\\'");
24 }
25
0970a58 Prepare for single language version
jakubvrana authored
26 function remove_lang($match) {
bba76d8 Flatten $translations
jakubvrana authored
27 global $translations;
438ca05 Separate languages
jakubvrana authored
28 $idf = strtr($match[2], array("\\'" => "'", "\\\\" => "\\"));
bba76d8 Flatten $translations
jakubvrana authored
29 $s = ($translations[$idf] ? $translations[$idf] : $idf);
64ba924 Comments
jakubvrana authored
30 if ($match[3] == ",") { // lang() has parameters
8943678 sprintf() in lang()
jakubvrana authored
31 return "$match[1]" . (is_array($s) ? "lang(array('" . implode("', '", array_map('add_apo_slashes', $s)) . "')," : "sprintf('" . add_apo_slashes($s) . "',");
32 }
33 return ($match[1] && $match[4] ? $s : "$match[1]'" . add_apo_slashes($s) . "'$match[4]");
0970a58 Prepare for single language version
jakubvrana authored
34 }
35
4738060 Use numeric language IDs to save bytes
jakubvrana authored
36 function lang_ids($match) {
37 global $lang_ids;
c16c57b E-mail sending
jakubvrana authored
38 $lang_id = &$lang_ids[stripslashes($match[1])];
39 if (!isset($lang_id)) {
40 $lang_id = count($lang_ids) - 1;
41 }
0116b9d Don't set cookie in compile scripts
jakubvrana authored
42 return ($_SESSION["lang"] ? $match[0] : "lang($lang_id$match[2]");
4738060 Use numeric language IDs to save bytes
jakubvrana authored
43 }
44
667bfec Decomposition
jakubvrana authored
45 function put_file($match) {
c16c57b E-mail sending
jakubvrana authored
46 global $project;
b95f24e Editor: User friendly data editor
jakubvrana authored
47 if (basename($match[2]) == '$LANG.inc.php') {
c16c57b E-mail sending
jakubvrana authored
48 return $match[0]; // processed later
438ca05 Separate languages
jakubvrana authored
49 }
b95f24e Editor: User friendly data editor
jakubvrana authored
50 $return = file_get_contents(dirname(__FILE__) . "/$project/$match[2]");
0116b9d Don't set cookie in compile scripts
jakubvrana authored
51 if (basename($match[2]) != "lang.inc.php" || !$_SESSION["lang"]) {
64ba924 Comments
jakubvrana authored
52 $tokens = token_get_all($return); // to find out the last token
6bb1401 Remove ?><?php
jakubvrana authored
53 return "?>\n$return" . (in_array($tokens[count($tokens) - 1][0], array(T_CLOSE_TAG, T_INLINE_HTML), true) ? "<?php" : "");
54 } elseif (preg_match('~\\s*(\\$pos = .*)~', $return, $match2)) {
64ba924 Comments
jakubvrana authored
55 // single language lang() is used for plural
0116b9d Don't set cookie in compile scripts
jakubvrana authored
56 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
57 } else {
58 echo "lang() not found\n";
667bfec Decomposition
jakubvrana authored
59 }
60 }
61
c16c57b E-mail sending
jakubvrana authored
62 function put_file_lang($match) {
63 global $lang_ids, $project;
0116b9d Don't set cookie in compile scripts
jakubvrana authored
64 if ($_SESSION["lang"]) {
c16c57b E-mail sending
jakubvrana authored
65 return "";
66 }
67 $return = "";
ea4fd61 Join translations
jakubvrana authored
68 foreach (glob(dirname(__FILE__) . "/adminer/lang/*.inc.php") as $filename) {
c16c57b E-mail sending
jakubvrana authored
69 include $filename; // assign $translations
70 $translation_ids = array_flip($lang_ids); // default translation
71 foreach ($translations as $key => $val) {
72 if (isset($val)) {
73 $translation_ids[$lang_ids[$key]] = $val;
74 }
75 }
76 $return .= "\tcase \"" . basename($filename, '.inc.php') . '": $translations = array(';
77 foreach ($translation_ids as $val) {
78 $return .= (is_array($val) ? "array('" . implode("', '", array_map('add_apo_slashes', $val)) . "')" : "'" . add_apo_slashes($val) . "'") . ", ";
79 }
80 $return = substr($return, 0, -2) . "); break;\n";
81 }
82 return "switch (\$LANG) {\n$return}\n";
83 }
84
16f4210 Function minification
jakubvrana authored
85 function short_identifier($number, $chars) {
86 $return = '';
a06f4c1 Size reduction by minification of variables
jakubvrana authored
87 while ($number >= 0) {
88 $return .= $chars{$number % strlen($chars)};
89 $number = floor($number / strlen($chars)) - 1;
90 }
91 return $return;
92 }
93
004d7a9 Link
jakubvrana authored
94 // based on http://latrine.dgx.cz/jak-zredukovat-php-skripty
794192d php_shrink()
jakubvrana authored
95 function php_shrink($input) {
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
101 foreach ($tokens as $i => $token) {
102 if ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
103 $short_variables[$token[1]]++;
104 }
105 }
c27a877 Minify defined functions only
jakubvrana authored
106
16f4210 Function minification
jakubvrana authored
107 arsort($short_variables);
108 foreach (array_keys($short_variables) as $number => $key) {
7f3ccd3 @vrana Utilize single parameter implode
authored
109 $short_variables[$key] = short_identifier($number, implode(range('a', 'z')) . '_' . implode(range('A', 'Z'))); // could use also numbers and \x7f-\xff
16f4210 Function minification
jakubvrana authored
110 }
a06f4c1 Size reduction by minification of variables
jakubvrana authored
111
794192d php_shrink()
jakubvrana authored
112 $set = array_flip(preg_split('//', '!"#$&\'()*+,-./:;<=>?@[\]^`{|}'));
113 $space = '';
114 $output = '';
ff85f12 Join echos
jakubvrana authored
115 $in_echo = false;
c16c57b E-mail sending
jakubvrana authored
116 $doc_comment = false; // include only first /**
ff85f12 Join echos
jakubvrana authored
117 for (reset($tokens); list($i, $token) = each($tokens); ) {
794192d php_shrink()
jakubvrana authored
118 if (!is_array($token)) {
119 $token = array(0, $token);
120 }
dbf9566 Better consecutive echo handling
jakubvrana authored
121 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
122 && strlen(addcslashes($tokens[$i+3][1], "'\\")) < strlen($tokens[$i+3][1]) + 3
dbf9566 Better consecutive echo handling
jakubvrana authored
123 ) {
124 $tokens[$i+2] = array(T_ECHO, 'echo');
125 $tokens[$i+3] = array(T_CONSTANT_ENCAPSED_STRING, "'" . addcslashes($tokens[$i+3][1], "'\\") . "'");
126 $tokens[$i+4] = array(0, ';');
127 }
c16c57b E-mail sending
jakubvrana authored
128 if ($token[0] == T_COMMENT || $token[0] == T_WHITESPACE || ($token[0] == T_DOC_COMMENT && $doc_comment)) {
794192d php_shrink()
jakubvrana authored
129 $space = "\n";
130 } else {
c16c57b E-mail sending
jakubvrana authored
131 if ($token[0] == T_DOC_COMMENT) {
132 $doc_comment = true;
133 }
a06f4c1 Size reduction by minification of variables
jakubvrana authored
134 if ($token[0] == T_VAR) {
135 $shortening = false;
136 } elseif (!$shortening) {
137 if ($token[1] == ';') {
138 $shortening = true;
139 }
ff85f12 Join echos
jakubvrana authored
140 } elseif ($token[0] == T_ECHO) {
141 $in_echo = true;
142 } elseif ($token[1] == ';' && $in_echo) {
e2bc1da No comments without whitespace
jakubvrana authored
143 if ($tokens[$i+1][0] === T_WHITESPACE && $tokens[$i+2][0] === T_ECHO) {
ff85f12 Join echos
jakubvrana authored
144 next($tokens);
c030c16 Compile inline HTML to echo
jakubvrana authored
145 $i++;
146 }
147 if ($tokens[$i+1][0] === T_ECHO) {
148 // join two consecutive echos
ff85f12 Join echos
jakubvrana authored
149 next($tokens);
02046d6 Windows support in e-mail attachments
jakubvrana authored
150 $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
151 } else {
152 $in_echo = false;
ff85f12 Join echos
jakubvrana authored
153 }
16f4210 Function minification
jakubvrana authored
154 } elseif ($token[0] === T_VARIABLE && !isset($special_variables[$token[1]])) {
155 $token[1] = '$' . $short_variables[$token[1]];
a06f4c1 Size reduction by minification of variables
jakubvrana authored
156 }
3f5b683 Reintegrate sqlite branch
jakubvrana authored
157 if (isset($set[substr($output, -1)]) || isset($set[$token[1][0]])) {
794192d php_shrink()
jakubvrana authored
158 $space = '';
159 }
160 $output .= $space . $token[1];
161 $space = '';
162 }
163 }
164 return $output;
165 }
166
9ee9cf0 Remove code generation
jakubvrana authored
167 function minify_css($file) {
168 return preg_replace('~\\s*([:;{},])\\s*~', '\\1', $file);
169 }
170
171 function compile_file($match) {
df03f4f Join editing.js in compilation
jakubvrana authored
172 global $project;
173 return call_user_func($match[2], file_get_contents(dirname(__FILE__) . "/$project/$match[1]"));
9ee9cf0 Remove code generation
jakubvrana authored
174 }
175
e672694 @vrana Rename $driver to $jush
authored
176 $driver = "";
3f5b683 Reintegrate sqlite branch
jakubvrana authored
177 if (file_exists(dirname(__FILE__) . "/adminer/drivers/" . $_SERVER["argv"][1] . ".inc.php")) {
e672694 @vrana Rename $driver to $jush
authored
178 $driver = $_SERVER["argv"][1];
3f5b683 Reintegrate sqlite branch
jakubvrana authored
179 array_shift($_SERVER["argv"]);
180 }
181
0116b9d Don't set cookie in compile scripts
jakubvrana authored
182 unset($_COOKIE["adminer_lang"]);
183 $_SESSION["lang"] = $_SERVER["argv"][1]; // Adminer functions read language from session
3f5b683 Reintegrate sqlite branch
jakubvrana authored
184 include dirname(__FILE__) . "/adminer/include/lang.inc.php";
0116b9d Don't set cookie in compile scripts
jakubvrana authored
185 if (isset($_SESSION["lang"])) {
186 if (isset($_SERVER["argv"][2]) || !isset($langs[$_SESSION["lang"]])) {
12d2c6d Build Adminer and Editor together
jakubvrana authored
187 echo "Usage: php compile.php [lang]\nPurpose: Compile adminer[-lang].php and editor[-lang].php.\n";
7418af0 Czech translation
jakubvrana authored
188 exit(1);
189 }
0116b9d Don't set cookie in compile scripts
jakubvrana authored
190 include dirname(__FILE__) . "/adminer/lang/$_SESSION[lang].inc.php";
7418af0 Czech translation
jakubvrana authored
191 }
bba76d8 Flatten $translations
jakubvrana authored
192
3f5b683 Reintegrate sqlite branch
jakubvrana authored
193 // check function definition in drivers
194 $filename = dirname(__FILE__) . "/adminer/drivers/mysql.inc.php";
195 preg_match_all('~\\bfunction ([^(]+)~', file_get_contents($filename), $matches); //! respect context (extension, class)
196 $functions = array_combine($matches[1], $matches[0]);
197 unset($functions["__destruct"], $functions["Min_DB"], $functions["Min_Result"]);
e672694 @vrana Rename $driver to $jush
authored
198 foreach (glob(dirname(__FILE__) . "/adminer/drivers/" . ($driver ? $driver : "*") . ".inc.php") as $filename) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
199 if ($filename != "mysql.inc.php") {
200 $file = file_get_contents($filename);
201 foreach ($functions as $val) {
202 if (!strpos($file, "$val(")) {
203 echo "Missing $val in $filename\n";
204 }
205 }
206 }
207 }
208
e672694 @vrana Rename $driver to $jush
authored
209 include dirname(__FILE__) . "/adminer/include/pdo.inc.php";
e678e46 @vrana Remove unsupported features in single driver version
authored
210 $features = array("view", "event", "privileges", "user", "processlist", "variables", "trigger", "scheme", "sequence");
12d2c6d Build Adminer and Editor together
jakubvrana authored
211 foreach (array("adminer", "editor") as $project) {
212 $lang_ids = array(); // global variable simplifies usage in a callback function
213 $file = file_get_contents(dirname(__FILE__) . "/$project/index.php");
e672694 @vrana Rename $driver to $jush
authored
214 if ($driver) {
6420c58 Schema support for PostgreSQL
jakubvrana authored
215 $connection = (object) array("server_info" => 5.1); // MySQL support is version specific
e672694 @vrana Rename $driver to $jush
authored
216 $_GET[$driver] = true; // to load the driver
217 include_once dirname(__FILE__) . "/adminer/drivers/$driver.inc.php";
e678e46 @vrana Remove unsupported features in single driver version
authored
218 foreach ($features as $feature) {
3f5b683 Reintegrate sqlite branch
jakubvrana authored
219 if (!support($feature)) {
220 $file = str_replace("} elseif (isset(\$_GET[\"$feature\"])) {\n\tinclude \"./$feature.inc.php\";\n", "", $file);
221 }
222 }
223 if (!support("routine")) {
224 $file = str_replace("} elseif (isset(\$_GET[\"procedure\"])) {\n\tinclude \"./procedure.inc.php\";\n", "", $file);
225 $file = str_replace("} elseif (isset(\$_GET[\"call\"])) {\n\tinclude \"./call.inc.php\";\n", "", $file);
226 $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);
227 }
228 }
12d2c6d Build Adminer and Editor together
jakubvrana authored
229 $file = preg_replace_callback('~\\b(include|require) "([^"]*)";~', 'put_file', $file);
230 $file = str_replace('include "../adminer/include/coverage.inc.php";', '', $file);
e672694 @vrana Rename $driver to $jush
authored
231 if ($driver) {
232 $file = preg_replace('(include "../adminer/drivers/(?!' . preg_quote($driver) . ').*\\s*)', '', $file);
3f5b683 Reintegrate sqlite branch
jakubvrana authored
233 }
12d2c6d Build Adminer and Editor together
jakubvrana authored
234 $file = preg_replace_callback('~\\b(include|require) "([^"]*)";~', 'put_file', $file); // bootstrap.inc.php
e678e46 @vrana Remove unsupported features in single driver version
authored
235 if ($driver) {
236 foreach ($features as $feature) {
237 if (!support($feature)) {
238 $file = preg_replace("((\t*)" . preg_quote('if (support("' . $feature . '")') . ".*\n\\1\\})sU", '', $file);
239 }
240 }
4b9d451 @vrana SQLite version supports two systems
authored
241 if (count($drivers) == 1) {
242 $file = str_replace('<?php echo html_select("driver", $drivers, DRIVER); ?>', "<input type='hidden' name='driver' value='$driver'>" . reset($drivers), $file);
243 }
e678e46 @vrana Remove unsupported features in single driver version
authored
244 }
12d2c6d Build Adminer and Editor together
jakubvrana authored
245 $file = preg_replace_callback("~lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])~s", 'lang_ids', $file);
246 $file = preg_replace_callback('~\\b(include|require) "([^"]*\\$LANG.inc.php)";~', 'put_file_lang', $file);
247 if ($_SESSION["lang"]) {
248 // single language version
249 $file = preg_replace_callback("~(<\\?php\\s*echo )?lang\\('((?:[^\\\\']+|\\\\.)*)'([,)])(;\\s*\\?>)?~s", 'remove_lang', $file);
250 $file = str_replace("<?php switch_lang(); ?>\n", "", $file);
251 $file = str_replace('<?php echo $LANG; ?>', $_SESSION["lang"], $file);
252 }
253 $file = str_replace('<script type="text/javascript" src="static/editing.js"></script>' . "\n", "", $file);
254 $file = preg_replace_callback("~compile_file\\('([^']+)', '([^']+)'\\);~", 'compile_file', $file); // integrate static files
255 $replace = 'h(preg_replace("~\\\\\\\\?.*~", "", $_SERVER["REQUEST_URI"])) . "?file=\\1&amp;version=' . $VERSION;
256 $file = preg_replace('~\\.\\./adminer/static/(default\\.css|functions\\.js|favicon\\.ico)~', '<?php echo ' . $replace . '"; ?>', $file);
257 $file = preg_replace('~\\.\\./adminer/static/([^\'"]*)~', '" . ' . $replace, $file);
4c47d35 @vrana Use HTTP protocol if possible - adminer.org certificate is missing in Op...
authored
258 $file = str_replace("'../externals/jush/'", "protocol + '://www.adminer.org/static/'", $file);
12d2c6d Build Adminer and Editor together
jakubvrana authored
259 $file = preg_replace("~<\\?php\\s*\\?>\n?|\\?>\n?<\\?php~", '', $file);
260 $file = php_shrink($file);
c02bd44 Use $filename
jakubvrana authored
261
e672694 @vrana Rename $driver to $jush
authored
262 $filename = $project . (preg_match('~-dev$~', $VERSION) ? "" : "-$VERSION") . ($driver ? "-$driver" : "") . ($_SESSION["lang"] ? "-$_SESSION[lang]" : "") . ".php";
12d2c6d Build Adminer and Editor together
jakubvrana authored
263 fwrite(fopen($filename, "w"), $file); // file_put_contents() since PHP 5
3f5b683 Reintegrate sqlite branch
jakubvrana authored
264 echo "$filename created (" . strlen($file) . " B).\n";
12d2c6d Build Adminer and Editor together
jakubvrana authored
265 }
Something went wrong with that request. Please try again.