250 |
kaklik |
1 |
<?php |
|
|
2 |
/* $Id: common.lib.php,v 2.266.2.27.2.2 2006/08/21 11:45:16 lem9 Exp $ */ |
|
|
3 |
// vim: expandtab sw=4 ts=4 sts=4: |
|
|
4 |
|
|
|
5 |
/** |
|
|
6 |
* Misc stuff and functions used by almost all the scripts. |
|
|
7 |
* Among other things, it contains the advanced authentication work. |
|
|
8 |
*/ |
|
|
9 |
|
|
|
10 |
/** |
|
|
11 |
* Order of sections for common.lib.php: |
|
|
12 |
* |
|
|
13 |
* the include of libraries/defines_mysql.lib.php must be after the connection |
|
|
14 |
* to db to get the MySql version |
|
|
15 |
* |
|
|
16 |
* the authentication libraries must be before the connection to db |
|
|
17 |
* |
|
|
18 |
* ... so the required order is: |
|
|
19 |
* |
|
|
20 |
* LABEL_definition_of_functions |
|
|
21 |
* - definition of functions |
|
|
22 |
* LABEL_variables_init |
|
|
23 |
* - init some variables always needed |
|
|
24 |
* LABEL_parsing_config_file |
|
|
25 |
* - parsing of the config file |
|
|
26 |
* LABEL_loading_language_file |
|
|
27 |
* - loading language file |
|
|
28 |
* LABEL_theme_setup |
|
|
29 |
* - setting up themes |
|
|
30 |
* |
|
|
31 |
* - load of mysql extension (if necessary) label_loading_mysql |
|
|
32 |
* - loading of an authentication library label_ |
|
|
33 |
* - db connection |
|
|
34 |
* - authentication work |
|
|
35 |
* - load of the libraries/defines_mysql.lib.php library to get the MySQL |
|
|
36 |
* release number |
|
|
37 |
*/ |
|
|
38 |
|
|
|
39 |
/** |
|
|
40 |
* For now, avoid warnings of E_STRICT mode |
|
|
41 |
* (this must be done before function definitions) |
|
|
42 |
*/ |
|
|
43 |
|
|
|
44 |
if (defined('E_STRICT')) { |
|
|
45 |
$old_error_reporting = error_reporting(0); |
|
|
46 |
if ($old_error_reporting & E_STRICT) { |
|
|
47 |
error_reporting($old_error_reporting ^ E_STRICT); |
|
|
48 |
} else { |
|
|
49 |
error_reporting($old_error_reporting); |
|
|
50 |
} |
|
|
51 |
unset($old_error_reporting); |
|
|
52 |
} |
|
|
53 |
|
|
|
54 |
/** |
|
|
55 |
* Avoid object cloning errors |
|
|
56 |
*/ |
|
|
57 |
|
|
|
58 |
@ini_set('zend.ze1_compatibility_mode',false); |
|
|
59 |
|
|
|
60 |
|
|
|
61 |
/******************************************************************************/ |
|
|
62 |
/* definition of functions LABEL_definition_of_functions */ |
|
|
63 |
/** |
|
|
64 |
* Removes insecure parts in a path; used before include() or |
|
|
65 |
* require() when a part of the path comes from an insecure source |
|
|
66 |
* like a cookie or form. |
|
|
67 |
* |
|
|
68 |
* @param string The path to check |
|
|
69 |
* |
|
|
70 |
* @return string The secured path |
|
|
71 |
* |
|
|
72 |
* @access public |
|
|
73 |
* @author Marc Delisle (lem9@users.sourceforge.net) |
|
|
74 |
*/ |
|
|
75 |
function PMA_securePath($path) |
|
|
76 |
{ |
|
|
77 |
// change .. to . |
|
|
78 |
$path = preg_replace('@\.\.*@', '.', $path); |
|
|
79 |
|
|
|
80 |
return $path; |
|
|
81 |
} // end function |
|
|
82 |
|
|
|
83 |
/** |
|
|
84 |
* returns array with dbs grouped with extended infos |
|
|
85 |
* |
|
|
86 |
* @uses $GLOBALS['dblist'] from PMA_availableDatabases() |
|
|
87 |
* @uses $GLOBALS['num_dbs'] from PMA_availableDatabases() |
|
|
88 |
* @uses $GLOBALS['cfgRelation']['commwork'] |
|
|
89 |
* @uses $GLOBALS['cfg']['ShowTooltip'] |
|
|
90 |
* @uses $GLOBALS['cfg']['LeftFrameDBTree'] |
|
|
91 |
* @uses $GLOBALS['cfg']['LeftFrameDBSeparator'] |
|
|
92 |
* @uses $GLOBALS['cfg']['ShowTooltipAliasDB'] |
|
|
93 |
* @uses PMA_availableDatabases() |
|
|
94 |
* @uses PMA_getTableCount() |
|
|
95 |
* @uses PMA_getComments() |
|
|
96 |
* @uses PMA_availableDatabases() |
|
|
97 |
* @uses is_array() |
|
|
98 |
* @uses implode() |
|
|
99 |
* @uses strstr() |
|
|
100 |
* @uses explode() |
|
|
101 |
* @return array db list |
|
|
102 |
*/ |
|
|
103 |
function PMA_getDbList() |
|
|
104 |
{ |
|
|
105 |
if (empty($GLOBALS['dblist'])) { |
|
|
106 |
PMA_availableDatabases(); |
|
|
107 |
} |
|
|
108 |
$dblist = $GLOBALS['dblist']; |
|
|
109 |
$dbgroups = array(); |
|
|
110 |
$parts = array(); |
|
|
111 |
foreach ($dblist as $key => $db) { |
|
|
112 |
// garvin: Get comments from PMA comments table |
|
|
113 |
$db_tooltip = ''; |
|
|
114 |
if ($GLOBALS['cfg']['ShowTooltip'] |
|
|
115 |
&& $GLOBALS['cfgRelation']['commwork']) { |
|
|
116 |
$_db_tooltip = PMA_getComments($db); |
|
|
117 |
if (is_array($_db_tooltip)) { |
|
|
118 |
$db_tooltip = implode(' ', $_db_tooltip); |
|
|
119 |
} |
|
|
120 |
} |
|
|
121 |
|
|
|
122 |
if ($GLOBALS['cfg']['LeftFrameDBTree'] |
|
|
123 |
&& $GLOBALS['cfg']['LeftFrameDBSeparator'] |
|
|
124 |
&& strstr($db, $GLOBALS['cfg']['LeftFrameDBSeparator'])) |
|
|
125 |
{ |
|
|
126 |
$pos = strrpos($db, $GLOBALS['cfg']['LeftFrameDBSeparator']); |
|
|
127 |
$group = substr($db, 0, $pos); |
|
|
128 |
$disp_name_cut = substr($db, $pos); |
|
|
129 |
} else { |
|
|
130 |
$group = $db; |
|
|
131 |
$disp_name_cut = $db; |
|
|
132 |
} |
|
|
133 |
|
|
|
134 |
$disp_name = $db; |
|
|
135 |
if ($db_tooltip && $GLOBALS['cfg']['ShowTooltipAliasDB']) { |
|
|
136 |
$disp_name = $db_tooltip; |
|
|
137 |
$disp_name_cut = $db_tooltip; |
|
|
138 |
$db_tooltip = $db; |
|
|
139 |
} |
|
|
140 |
|
|
|
141 |
$dbgroups[$group][$db] = array( |
|
|
142 |
'name' => $db, |
|
|
143 |
'disp_name_cut' => $disp_name_cut, |
|
|
144 |
'disp_name' => $disp_name, |
|
|
145 |
'comment' => $db_tooltip, |
|
|
146 |
'num_tables' => PMA_getTableCount($db), |
|
|
147 |
); |
|
|
148 |
} // end foreach ($dblist as $db) |
|
|
149 |
return $dbgroups; |
|
|
150 |
} |
|
|
151 |
|
|
|
152 |
/** |
|
|
153 |
* returns html code for select form element with dbs |
|
|
154 |
* |
|
|
155 |
* @return string html code select |
|
|
156 |
*/ |
|
|
157 |
function PMA_getHtmlSelectDb($selected = '') |
|
|
158 |
{ |
|
|
159 |
$dblist = PMA_getDbList(); |
|
|
160 |
// TODO: IE can not handle different text directions in select boxes |
|
|
161 |
// so, as mostly names will be in english, we set the whole selectbox to LTR |
|
|
162 |
// and EN |
|
|
163 |
$return = '<select name="db" id="lightm_db" xml:lang="en" dir="ltr"' |
|
|
164 |
.' onchange="if (this.value != \'\') window.parent.openDb(this.value);">' . "\n" |
|
|
165 |
.'<option value="" dir="' . $GLOBALS['text_dir'] . '">(' . $GLOBALS['strDatabases'] . ') ...</option>' |
|
|
166 |
."\n"; |
|
|
167 |
foreach ($dblist as $group => $dbs) { |
|
|
168 |
if (count($dbs) > 1) { |
|
|
169 |
$return .= '<optgroup label="' . htmlspecialchars($group) |
|
|
170 |
. '">' . "\n"; |
|
|
171 |
// wether display db_name cuted by the group part |
|
|
172 |
$cut = true; |
|
|
173 |
} else { |
|
|
174 |
// .. or full |
|
|
175 |
$cut = false; |
|
|
176 |
} |
|
|
177 |
foreach ($dbs as $db) { |
|
|
178 |
$return .= '<option value="' . $db['name'] . '"' |
|
|
179 |
.' title="' . $db['comment'] . '"'; |
|
|
180 |
if ($db['name'] == $selected) { |
|
|
181 |
$return .= ' selected="selected"'; |
|
|
182 |
} |
|
|
183 |
$return .= '>' . ($cut ? $db['disp_name_cut'] : $db['disp_name']) |
|
|
184 |
.' (' . $db['num_tables'] . ')</option>' . "\n"; |
|
|
185 |
} |
|
|
186 |
if (count($dbs) > 1) { |
|
|
187 |
$return .= '</optgroup>' . "\n"; |
|
|
188 |
} |
|
|
189 |
} |
|
|
190 |
$return .= '</select>'; |
|
|
191 |
|
|
|
192 |
return $return; |
|
|
193 |
} |
|
|
194 |
|
|
|
195 |
/** |
|
|
196 |
* returns count of tables in given db |
|
|
197 |
* |
|
|
198 |
* @param string $db database to count tables for |
|
|
199 |
* @return integer count of tables in $db |
|
|
200 |
*/ |
|
|
201 |
function PMA_getTableCount($db) |
|
|
202 |
{ |
|
|
203 |
$tables = PMA_DBI_try_query( |
|
|
204 |
'SHOW TABLES FROM ' . PMA_backquote($db) . ';', |
|
|
205 |
null, PMA_DBI_QUERY_STORE); |
|
|
206 |
if ($tables) { |
|
|
207 |
$num_tables = PMA_DBI_num_rows($tables); |
|
|
208 |
PMA_DBI_free_result($tables); |
|
|
209 |
} else { |
|
|
210 |
$num_tables = 0; |
|
|
211 |
} |
|
|
212 |
|
|
|
213 |
return $num_tables; |
|
|
214 |
} |
|
|
215 |
|
|
|
216 |
|
|
|
217 |
/** |
|
|
218 |
* Get the complete list of Databases a user can access |
|
|
219 |
* |
|
|
220 |
* @param boolean whether to include check on failed 'only_db' operations |
|
|
221 |
* @param resource database handle (superuser) |
|
|
222 |
* @param integer amount of databases inside the 'only_db' container |
|
|
223 |
* @param resource possible resource from a failed previous query |
|
|
224 |
* @param resource database handle (user) |
|
|
225 |
* @param array configuration |
|
|
226 |
* @param array previous list of databases |
|
|
227 |
* |
|
|
228 |
* @return array all databases a user has access to |
|
|
229 |
* |
|
|
230 |
* @access private |
|
|
231 |
*/ |
|
|
232 |
function PMA_safe_db_list($only_db_check, $controllink, $dblist_cnt, $userlink, |
|
|
233 |
$cfg, $dblist) |
|
|
234 |
{ |
|
|
235 |
if ($only_db_check == false) { |
|
|
236 |
// try to get the available dbs list |
|
|
237 |
// use userlink by default |
|
|
238 |
$dblist = PMA_DBI_get_dblist(); |
|
|
239 |
$dblist_cnt = count($dblist); |
|
|
240 |
|
|
|
241 |
// PMA_DBI_get_dblist() relies on the ability to run "SHOW DATABASES". |
|
|
242 |
// On servers started with --skip-show-database, this is not possible |
|
|
243 |
// so we have here a fallback method, which relies on the controluser |
|
|
244 |
// being able to access the "mysql" db, as explained in the doc. |
|
|
245 |
|
|
|
246 |
if (!$dblist_cnt) { |
|
|
247 |
$auth_query = 'SELECT User, Select_priv ' |
|
|
248 |
. 'FROM mysql.user ' |
|
|
249 |
. 'WHERE User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\''; |
|
|
250 |
$rs = PMA_DBI_try_query($auth_query, $controllink); |
|
|
251 |
} // end |
|
|
252 |
} |
|
|
253 |
|
|
|
254 |
// Access to "mysql" db allowed and dblist still empty -> gets the |
|
|
255 |
// usable db list |
|
|
256 |
if (!$dblist_cnt && ($rs && @PMA_DBI_num_rows($rs))) { |
|
|
257 |
$row = PMA_DBI_fetch_assoc($rs); |
|
|
258 |
PMA_DBI_free_result($rs); |
|
|
259 |
// Correction uva 19991215 |
|
|
260 |
// Previous code assumed database "mysql" admin table "db" column |
|
|
261 |
// "db" contains literal name of user database, and works if so. |
|
|
262 |
// Mysql usage generally (and uva usage specifically) allows this |
|
|
263 |
// column to contain regular expressions (we have all databases |
|
|
264 |
// owned by a given student/faculty/staff beginning with user i.d. |
|
|
265 |
// and governed by default by a single set of privileges with |
|
|
266 |
// regular expression as key). This breaks previous code. |
|
|
267 |
// This maintenance is to fix code to work correctly for regular |
|
|
268 |
// expressions. |
|
|
269 |
if ($row['Select_priv'] != 'Y') { |
|
|
270 |
|
|
|
271 |
// 1. get allowed dbs from the "mysql.db" table |
|
|
272 |
// lem9: User can be blank (anonymous user) |
|
|
273 |
$local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE Select_priv = \'Y\' AND (User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\' OR User = \'\')'; |
|
|
274 |
$rs = PMA_DBI_try_query($local_query, $controllink); |
|
|
275 |
if ($rs && @PMA_DBI_num_rows($rs)) { |
|
|
276 |
// Will use as associative array of the following 2 code |
|
|
277 |
// lines: |
|
|
278 |
// the 1st is the only line intact from before |
|
|
279 |
// correction, |
|
|
280 |
// the 2nd replaces $dblist[] = $row['Db']; |
|
|
281 |
$uva_mydbs = array(); |
|
|
282 |
// Code following those 2 lines in correction continues |
|
|
283 |
// populating $dblist[], as previous code did. But it is |
|
|
284 |
// now populated with actual database names instead of |
|
|
285 |
// with regular expressions. |
|
|
286 |
while ($row = PMA_DBI_fetch_assoc($rs)) { |
|
|
287 |
// loic1: all databases cases - part 1 |
|
|
288 |
if ( !isset($row['Db']) || ! strlen($row['Db']) || $row['Db'] == '%') { |
|
|
289 |
$uva_mydbs['%'] = 1; |
|
|
290 |
break; |
|
|
291 |
} |
|
|
292 |
// loic1: avoid multiple entries for dbs |
|
|
293 |
if (!isset($uva_mydbs[$row['Db']])) { |
|
|
294 |
$uva_mydbs[$row['Db']] = 1; |
|
|
295 |
} |
|
|
296 |
} // end while |
|
|
297 |
PMA_DBI_free_result($rs); |
|
|
298 |
$uva_alldbs = PMA_DBI_query('SHOW DATABASES;', $GLOBALS['controllink']); |
|
|
299 |
// loic1: all databases cases - part 2 |
|
|
300 |
if (isset($uva_mydbs['%'])) { |
|
|
301 |
while ($uva_row = PMA_DBI_fetch_row($uva_alldbs)) { |
|
|
302 |
$dblist[] = $uva_row[0]; |
|
|
303 |
} // end while |
|
|
304 |
} else { |
|
|
305 |
while ($uva_row = PMA_DBI_fetch_row($uva_alldbs)) { |
|
|
306 |
$uva_db = $uva_row[0]; |
|
|
307 |
if (isset($uva_mydbs[$uva_db]) && $uva_mydbs[$uva_db] == 1) { |
|
|
308 |
$dblist[] = $uva_db; |
|
|
309 |
$uva_mydbs[$uva_db] = 0; |
|
|
310 |
} elseif (!isset($dblist[$uva_db])) { |
|
|
311 |
foreach ($uva_mydbs AS $uva_matchpattern => $uva_value) { |
|
|
312 |
// loic1: fixed bad regexp |
|
|
313 |
// TODO: db names may contain characters |
|
|
314 |
// that are regexp instructions |
|
|
315 |
$re = '(^|(\\\\\\\\)+|[^\])'; |
|
|
316 |
$uva_regex = ereg_replace($re . '%', '\\1.*', ereg_replace($re . '_', '\\1.{1}', $uva_matchpattern)); |
|
|
317 |
// Fixed db name matching |
|
|
318 |
// 2000-08-28 -- Benjamin Gandon |
|
|
319 |
if (ereg('^' . $uva_regex . '$', $uva_db)) { |
|
|
320 |
$dblist[] = $uva_db; |
|
|
321 |
break; |
|
|
322 |
} |
|
|
323 |
} // end while |
|
|
324 |
} // end if ... elseif ... |
|
|
325 |
} // end while |
|
|
326 |
} // end else |
|
|
327 |
PMA_DBI_free_result($uva_alldbs); |
|
|
328 |
unset($uva_mydbs); |
|
|
329 |
} // end if |
|
|
330 |
|
|
|
331 |
// 2. get allowed dbs from the "mysql.tables_priv" table |
|
|
332 |
$local_query = 'SELECT DISTINCT Db FROM mysql.tables_priv WHERE Table_priv LIKE \'%Select%\' AND User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\''; |
|
|
333 |
$rs = PMA_DBI_try_query($local_query, $controllink); |
|
|
334 |
if ($rs && @PMA_DBI_num_rows($rs)) { |
|
|
335 |
while ($row = PMA_DBI_fetch_assoc($rs)) { |
|
|
336 |
if (!in_array($row['Db'], $dblist)) { |
|
|
337 |
$dblist[] = $row['Db']; |
|
|
338 |
} |
|
|
339 |
} // end while |
|
|
340 |
PMA_DBI_free_result($rs); |
|
|
341 |
} // end if |
|
|
342 |
} // end if |
|
|
343 |
} // end building available dbs from the "mysql" db |
|
|
344 |
|
|
|
345 |
return $dblist; |
|
|
346 |
} |
|
|
347 |
|
|
|
348 |
/** |
|
|
349 |
* Converts numbers like 10M into bytes |
|
|
350 |
* |
|
|
351 |
* @param string $size |
|
|
352 |
* @return integer $size |
|
|
353 |
*/ |
|
|
354 |
function get_real_size($size = 0) |
|
|
355 |
{ |
|
|
356 |
if (!$size) { |
|
|
357 |
return 0; |
|
|
358 |
} |
|
|
359 |
$scan['MB'] = 1048576; |
|
|
360 |
$scan['Mb'] = 1048576; |
|
|
361 |
$scan['M'] = 1048576; |
|
|
362 |
$scan['m'] = 1048576; |
|
|
363 |
$scan['KB'] = 1024; |
|
|
364 |
$scan['Kb'] = 1024; |
|
|
365 |
$scan['K'] = 1024; |
|
|
366 |
$scan['k'] = 1024; |
|
|
367 |
|
|
|
368 |
while (list($key) = each($scan)) { |
|
|
369 |
if ((strlen($size) > strlen($key)) |
|
|
370 |
&& (substr($size, strlen($size) - strlen($key)) == $key)) { |
|
|
371 |
$size = substr($size, 0, strlen($size) - strlen($key)) * $scan[$key]; |
|
|
372 |
break; |
|
|
373 |
} |
|
|
374 |
} |
|
|
375 |
return $size; |
|
|
376 |
} // end function get_real_size() |
|
|
377 |
|
|
|
378 |
/** |
|
|
379 |
* loads php module |
|
|
380 |
* |
|
|
381 |
* @uses PHP_OS |
|
|
382 |
* @uses extension_loaded() |
|
|
383 |
* @uses ini_get() |
|
|
384 |
* @uses function_exists() |
|
|
385 |
* @uses ob_start() |
|
|
386 |
* @uses phpinfo() |
|
|
387 |
* @uses strip_tags() |
|
|
388 |
* @uses ob_get_contents() |
|
|
389 |
* @uses ob_end_clean() |
|
|
390 |
* @uses preg_match() |
|
|
391 |
* @uses strtoupper() |
|
|
392 |
* @uses substr() |
|
|
393 |
* @uses dl() |
|
|
394 |
* @param string $module name if module to load |
|
|
395 |
* @return boolean success loading module |
|
|
396 |
*/ |
|
|
397 |
function PMA_dl($module) |
|
|
398 |
{ |
|
|
399 |
static $dl_allowed = null; |
|
|
400 |
|
|
|
401 |
if (extension_loaded($module)) { |
|
|
402 |
return true; |
|
|
403 |
} |
|
|
404 |
|
|
|
405 |
if (null === $dl_allowed) { |
|
|
406 |
if (!@ini_get('safe_mode') |
|
|
407 |
&& @ini_get('enable_dl') |
|
|
408 |
&& @function_exists('dl')) { |
|
|
409 |
ob_start(); |
|
|
410 |
phpinfo(INFO_GENERAL); /* Only general info */ |
|
|
411 |
$a = strip_tags(ob_get_contents()); |
|
|
412 |
ob_end_clean(); |
|
|
413 |
if (preg_match('@Thread Safety[[:space:]]*enabled@', $a)) { |
|
|
414 |
if (preg_match('@Server API[[:space:]]*\(CGI\|CLI\)@', $a)) { |
|
|
415 |
$dl_allowed = true; |
|
|
416 |
} else { |
|
|
417 |
$dl_allowed = false; |
|
|
418 |
} |
|
|
419 |
} else { |
|
|
420 |
$dl_allowed = true; |
|
|
421 |
} |
|
|
422 |
} else { |
|
|
423 |
$dl_allowed = false; |
|
|
424 |
} |
|
|
425 |
} |
|
|
426 |
|
|
|
427 |
if (!$dl_allowed) { |
|
|
428 |
return false; |
|
|
429 |
} |
|
|
430 |
|
|
|
431 |
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { |
|
|
432 |
$module_file = 'php_' . $module . '.dll'; |
|
|
433 |
} else { |
|
|
434 |
$module_file = $module . '.so'; |
|
|
435 |
} |
|
|
436 |
|
|
|
437 |
return @dl($module_file); |
|
|
438 |
} |
|
|
439 |
|
|
|
440 |
/** |
|
|
441 |
* merges array recursive like array_merge_recursive() but keyed-values are |
|
|
442 |
* always overwritten. |
|
|
443 |
* |
|
|
444 |
* array PMA_array_merge_recursive(array $array1[, array $array2[, array ...]]) |
|
|
445 |
* |
|
|
446 |
* @see http://php.net/array_merge |
|
|
447 |
* @see http://php.net/array_merge_recursive |
|
|
448 |
* @uses func_num_args() |
|
|
449 |
* @uses func_get_arg() |
|
|
450 |
* @uses is_array() |
|
|
451 |
* @uses call_user_func_array() |
|
|
452 |
* @param array array to merge |
|
|
453 |
* @param array array to merge |
|
|
454 |
* @param array ... |
|
|
455 |
* @return array merged array |
|
|
456 |
*/ |
|
|
457 |
function PMA_array_merge_recursive() |
|
|
458 |
{ |
|
|
459 |
switch(func_num_args()) { |
|
|
460 |
case 0 : |
|
|
461 |
return false; |
|
|
462 |
break; |
|
|
463 |
case 1 : |
|
|
464 |
// when does that happen? |
|
|
465 |
return func_get_arg(0); |
|
|
466 |
break; |
|
|
467 |
case 2 : |
|
|
468 |
$args = func_get_args(); |
|
|
469 |
if (!is_array($args[0]) || !is_array($args[1])) { |
|
|
470 |
return $args[1]; |
|
|
471 |
} |
|
|
472 |
foreach ($args[1] AS $key2 => $value2) { |
|
|
473 |
if (isset($args[0][$key2]) && !is_int($key2)) { |
|
|
474 |
$args[0][$key2] = PMA_array_merge_recursive($args[0][$key2], |
|
|
475 |
$value2); |
|
|
476 |
} else { |
|
|
477 |
// we erase the parent array, otherwise we cannot override a directive that |
|
|
478 |
// contains array elements, like this: |
|
|
479 |
// (in config.default.php) $cfg['ForeignKeyDropdownOrder'] = array('id-content','content-id'); |
|
|
480 |
// (in config.inc.php) $cfg['ForeignKeyDropdownOrder'] = array('content-id'); |
|
|
481 |
if (is_int($key2) && $key2 == 0) { |
|
|
482 |
unset($args[0]); |
|
|
483 |
} |
|
|
484 |
$args[0][$key2] = $value2; |
|
|
485 |
} |
|
|
486 |
} |
|
|
487 |
return $args[0]; |
|
|
488 |
break; |
|
|
489 |
default : |
|
|
490 |
$args = func_get_args(); |
|
|
491 |
$args[1] = PMA_array_merge_recursive($args[0], $args[1]); |
|
|
492 |
array_shift($args); |
|
|
493 |
return call_user_func_array('PMA_array_merge_recursive', $args); |
|
|
494 |
break; |
|
|
495 |
} |
|
|
496 |
} |
|
|
497 |
|
|
|
498 |
/** |
|
|
499 |
* calls $function vor every element in $array recursively |
|
|
500 |
* |
|
|
501 |
* @param array $array array to walk |
|
|
502 |
* @param string $function function to call for every array element |
|
|
503 |
*/ |
|
|
504 |
function PMA_arrayWalkRecursive(&$array, $function, $apply_to_keys_also = false) |
|
|
505 |
{ |
|
|
506 |
foreach ($array as $key => $value) { |
|
|
507 |
if (is_array($value)) { |
|
|
508 |
PMA_arrayWalkRecursive($array[$key], $function, $apply_to_keys_also); |
|
|
509 |
} else { |
|
|
510 |
$array[$key] = $function($value); |
|
|
511 |
} |
|
|
512 |
|
|
|
513 |
if ($apply_to_keys_also && is_string($key)) { |
|
|
514 |
$new_key = $function($key); |
|
|
515 |
if ($new_key != $key) { |
|
|
516 |
$array[$new_key] = $array[$key]; |
|
|
517 |
unset($array[$key]); |
|
|
518 |
} |
|
|
519 |
} |
|
|
520 |
} |
|
|
521 |
} |
|
|
522 |
|
|
|
523 |
/** |
|
|
524 |
* boolean phpMyAdmin.PMA_checkPageValidity(string &$page, array $whitelist) |
|
|
525 |
* |
|
|
526 |
* checks given given $page against given $whitelist and returns true if valid |
|
|
527 |
* it ignores optionaly query paramters in $page (script.php?ignored) |
|
|
528 |
* |
|
|
529 |
* @uses in_array() |
|
|
530 |
* @uses urldecode() |
|
|
531 |
* @uses substr() |
|
|
532 |
* @uses strpos() |
|
|
533 |
* @param string &$page page to check |
|
|
534 |
* @param array $whitelist whitelist to check page against |
|
|
535 |
* @return boolean whether $page is valid or not (in $whitelist or not) |
|
|
536 |
*/ |
|
|
537 |
function PMA_checkPageValidity(&$page, $whitelist) |
|
|
538 |
{ |
|
|
539 |
if (! isset($page)) { |
|
|
540 |
return false; |
|
|
541 |
} |
|
|
542 |
|
|
|
543 |
if (in_array($page, $whitelist)) { |
|
|
544 |
return true; |
|
|
545 |
} elseif (in_array(substr($page, 0, strpos($page . '?', '?')), $whitelist)) { |
|
|
546 |
return true; |
|
|
547 |
} else { |
|
|
548 |
$_page = urldecode($page); |
|
|
549 |
if (in_array(substr($_page, 0, strpos($_page . '?', '?')), $whitelist)) { |
|
|
550 |
return true; |
|
|
551 |
} |
|
|
552 |
} |
|
|
553 |
return false; |
|
|
554 |
} |
|
|
555 |
|
|
|
556 |
/** |
|
|
557 |
* trys to find the value for the given environment vriable name |
|
|
558 |
* |
|
|
559 |
* searchs in $_SERVER, $_ENV than trys getenv() and apache_getenv() |
|
|
560 |
* in this order |
|
|
561 |
* |
|
|
562 |
* @param string $var_name variable name |
|
|
563 |
* @return string value of $var or empty string |
|
|
564 |
*/ |
|
|
565 |
function PMA_getenv($var_name) { |
|
|
566 |
if (isset($_SERVER[$var_name])) { |
|
|
567 |
return $_SERVER[$var_name]; |
|
|
568 |
} elseif (isset($_ENV[$var_name])) { |
|
|
569 |
return $_ENV[$var_name]; |
|
|
570 |
} elseif (getenv($var_name)) { |
|
|
571 |
return getenv($var_name); |
|
|
572 |
} elseif (function_exists('apache_getenv') |
|
|
573 |
&& apache_getenv($var_name, true)) { |
|
|
574 |
return apache_getenv($var_name, true); |
|
|
575 |
} |
|
|
576 |
|
|
|
577 |
return ''; |
|
|
578 |
} |
|
|
579 |
|
|
|
580 |
/** |
|
|
581 |
* include here only libraries which contain only function definitions |
|
|
582 |
* no code im main()! |
|
|
583 |
*/ |
|
|
584 |
/* Input sanitizing */ |
|
|
585 |
require_once './libraries/sanitizing.lib.php'; |
|
|
586 |
require_once './libraries/Theme.class.php'; |
|
|
587 |
require_once './libraries/Theme_Manager.class.php'; |
|
|
588 |
require_once './libraries/Config.class.php'; |
|
|
589 |
|
|
|
590 |
|
|
|
591 |
|
|
|
592 |
if (!defined('PMA_MINIMUM_COMMON')) { |
|
|
593 |
/** |
|
|
594 |
* Displays the maximum size for an upload |
|
|
595 |
* |
|
|
596 |
* @param integer the size |
|
|
597 |
* |
|
|
598 |
* @return string the message |
|
|
599 |
* |
|
|
600 |
* @access public |
|
|
601 |
*/ |
|
|
602 |
function PMA_displayMaximumUploadSize($max_upload_size) |
|
|
603 |
{ |
|
|
604 |
list($max_size, $max_unit) = PMA_formatByteDown($max_upload_size); |
|
|
605 |
return '(' . sprintf($GLOBALS['strMaximumSize'], $max_size, $max_unit) . ')'; |
|
|
606 |
} |
|
|
607 |
|
|
|
608 |
/** |
|
|
609 |
* Generates a hidden field which should indicate to the browser |
|
|
610 |
* the maximum size for upload |
|
|
611 |
* |
|
|
612 |
* @param integer the size |
|
|
613 |
* |
|
|
614 |
* @return string the INPUT field |
|
|
615 |
* |
|
|
616 |
* @access public |
|
|
617 |
*/ |
|
|
618 |
function PMA_generateHiddenMaxFileSize($max_size) |
|
|
619 |
{ |
|
|
620 |
return '<input type="hidden" name="MAX_FILE_SIZE" value="' .$max_size . '" />'; |
|
|
621 |
} |
|
|
622 |
|
|
|
623 |
/** |
|
|
624 |
* Add slashes before "'" and "\" characters so a value containing them can |
|
|
625 |
* be used in a sql comparison. |
|
|
626 |
* |
|
|
627 |
* @param string the string to slash |
|
|
628 |
* @param boolean whether the string will be used in a 'LIKE' clause |
|
|
629 |
* (it then requires two more escaped sequences) or not |
|
|
630 |
* @param boolean whether to treat cr/lfs as escape-worthy entities |
|
|
631 |
* (converts \n to \\n, \r to \\r) |
|
|
632 |
* |
|
|
633 |
* @param boolean whether this function is used as part of the |
|
|
634 |
* "Create PHP code" dialog |
|
|
635 |
* |
|
|
636 |
* @return string the slashed string |
|
|
637 |
* |
|
|
638 |
* @access public |
|
|
639 |
*/ |
|
|
640 |
function PMA_sqlAddslashes($a_string = '', $is_like = false, $crlf = false, $php_code = false) |
|
|
641 |
{ |
|
|
642 |
if ($is_like) { |
|
|
643 |
$a_string = str_replace('\\', '\\\\\\\\', $a_string); |
|
|
644 |
} else { |
|
|
645 |
$a_string = str_replace('\\', '\\\\', $a_string); |
|
|
646 |
} |
|
|
647 |
|
|
|
648 |
if ($crlf) { |
|
|
649 |
$a_string = str_replace("\n", '\n', $a_string); |
|
|
650 |
$a_string = str_replace("\r", '\r', $a_string); |
|
|
651 |
$a_string = str_replace("\t", '\t', $a_string); |
|
|
652 |
} |
|
|
653 |
|
|
|
654 |
if ($php_code) { |
|
|
655 |
$a_string = str_replace('\'', '\\\'', $a_string); |
|
|
656 |
} else { |
|
|
657 |
$a_string = str_replace('\'', '\'\'', $a_string); |
|
|
658 |
} |
|
|
659 |
|
|
|
660 |
return $a_string; |
|
|
661 |
} // end of the 'PMA_sqlAddslashes()' function |
|
|
662 |
|
|
|
663 |
|
|
|
664 |
/** |
|
|
665 |
* Add slashes before "_" and "%" characters for using them in MySQL |
|
|
666 |
* database, table and field names. |
|
|
667 |
* Note: This function does not escape backslashes! |
|
|
668 |
* |
|
|
669 |
* @param string the string to escape |
|
|
670 |
* |
|
|
671 |
* @return string the escaped string |
|
|
672 |
* |
|
|
673 |
* @access public |
|
|
674 |
*/ |
|
|
675 |
function PMA_escape_mysql_wildcards($name) |
|
|
676 |
{ |
|
|
677 |
$name = str_replace('_', '\\_', $name); |
|
|
678 |
$name = str_replace('%', '\\%', $name); |
|
|
679 |
|
|
|
680 |
return $name; |
|
|
681 |
} // end of the 'PMA_escape_mysql_wildcards()' function |
|
|
682 |
|
|
|
683 |
/** |
|
|
684 |
* removes slashes before "_" and "%" characters |
|
|
685 |
* Note: This function does not unescape backslashes! |
|
|
686 |
* |
|
|
687 |
* @param string $name the string to escape |
|
|
688 |
* @return string the escaped string |
|
|
689 |
* @access public |
|
|
690 |
*/ |
|
|
691 |
function PMA_unescape_mysql_wildcards($name) |
|
|
692 |
{ |
|
|
693 |
$name = str_replace('\\_', '_', $name); |
|
|
694 |
$name = str_replace('\\%', '%', $name); |
|
|
695 |
|
|
|
696 |
return $name; |
|
|
697 |
} // end of the 'PMA_unescape_mysql_wildcards()' function |
|
|
698 |
|
|
|
699 |
/** |
|
|
700 |
* format sql strings |
|
|
701 |
* |
|
|
702 |
* @param mixed pre-parsed SQL structure |
|
|
703 |
* |
|
|
704 |
* @return string the formatted sql |
|
|
705 |
* |
|
|
706 |
* @global array the configuration array |
|
|
707 |
* @global boolean whether the current statement is a multiple one or not |
|
|
708 |
* |
|
|
709 |
* @access public |
|
|
710 |
* |
|
|
711 |
* @author Robin Johnson <robbat2@users.sourceforge.net> |
|
|
712 |
*/ |
|
|
713 |
function PMA_formatSql($parsed_sql, $unparsed_sql = '') |
|
|
714 |
{ |
|
|
715 |
global $cfg; |
|
|
716 |
|
|
|
717 |
// Check that we actually have a valid set of parsed data |
|
|
718 |
// well, not quite |
|
|
719 |
// first check for the SQL parser having hit an error |
|
|
720 |
if (PMA_SQP_isError()) { |
|
|
721 |
return $parsed_sql; |
|
|
722 |
} |
|
|
723 |
// then check for an array |
|
|
724 |
if (!is_array($parsed_sql)) { |
|
|
725 |
// We don't so just return the input directly |
|
|
726 |
// This is intended to be used for when the SQL Parser is turned off |
|
|
727 |
$formatted_sql = '<pre>' . "\n" |
|
|
728 |
. (($cfg['SQP']['fmtType'] == 'none' && $unparsed_sql != '') ? $unparsed_sql : $parsed_sql) . "\n" |
|
|
729 |
. '</pre>'; |
|
|
730 |
return $formatted_sql; |
|
|
731 |
} |
|
|
732 |
|
|
|
733 |
$formatted_sql = ''; |
|
|
734 |
|
|
|
735 |
switch ($cfg['SQP']['fmtType']) { |
|
|
736 |
case 'none': |
|
|
737 |
if ($unparsed_sql != '') { |
|
|
738 |
$formatted_sql = "<pre>\n" . PMA_SQP_formatNone(array('raw' => $unparsed_sql)) . "\n</pre>"; |
|
|
739 |
} else { |
|
|
740 |
$formatted_sql = PMA_SQP_formatNone($parsed_sql); |
|
|
741 |
} |
|
|
742 |
break; |
|
|
743 |
case 'html': |
|
|
744 |
$formatted_sql = PMA_SQP_formatHtml($parsed_sql, 'color'); |
|
|
745 |
break; |
|
|
746 |
case 'text': |
|
|
747 |
//$formatted_sql = PMA_SQP_formatText($parsed_sql); |
|
|
748 |
$formatted_sql = PMA_SQP_formatHtml($parsed_sql, 'text'); |
|
|
749 |
break; |
|
|
750 |
default: |
|
|
751 |
break; |
|
|
752 |
} // end switch |
|
|
753 |
|
|
|
754 |
return $formatted_sql; |
|
|
755 |
} // end of the "PMA_formatSql()" function |
|
|
756 |
|
|
|
757 |
|
|
|
758 |
/** |
|
|
759 |
* Displays a link to the official MySQL documentation |
|
|
760 |
* |
|
|
761 |
* @param string chapter of "HTML, one page per chapter" documentation |
|
|
762 |
* @param string contains name of page/anchor that is being linked |
|
|
763 |
* @param bool whether to use big icon (like in left frame) |
|
|
764 |
* |
|
|
765 |
* @return string the html link |
|
|
766 |
* |
|
|
767 |
* @access public |
|
|
768 |
*/ |
|
|
769 |
function PMA_showMySQLDocu($chapter, $link, $big_icon = false) |
|
|
770 |
{ |
|
|
771 |
global $cfg; |
|
|
772 |
|
|
|
773 |
if ($cfg['MySQLManualType'] == 'none' || empty($cfg['MySQLManualBase'])) { |
|
|
774 |
return ''; |
|
|
775 |
} |
|
|
776 |
|
|
|
777 |
// Fixup for newly used names: |
|
|
778 |
$chapter = str_replace('_', '-', strtolower($chapter)); |
|
|
779 |
$link = str_replace('_', '-', strtolower($link)); |
|
|
780 |
|
|
|
781 |
switch ($cfg['MySQLManualType']) { |
|
|
782 |
case 'chapters': |
|
|
783 |
if (empty($chapter)) { |
|
|
784 |
$chapter = 'index'; |
|
|
785 |
} |
|
|
786 |
$url = $cfg['MySQLManualBase'] . '/' . $chapter . '.html#' . $link; |
|
|
787 |
break; |
|
|
788 |
case 'big': |
|
|
789 |
$url = $cfg['MySQLManualBase'] . '#' . $link; |
|
|
790 |
break; |
|
|
791 |
case 'searchable': |
|
|
792 |
if (empty($link)) { |
|
|
793 |
$link = 'index'; |
|
|
794 |
} |
|
|
795 |
$url = $cfg['MySQLManualBase'] . '/' . $link . '.html'; |
|
|
796 |
break; |
|
|
797 |
case 'viewable': |
|
|
798 |
default: |
|
|
799 |
if (empty($link)) { |
|
|
800 |
$link = 'index'; |
|
|
801 |
} |
|
|
802 |
$mysql = '5.0'; |
|
|
803 |
if (defined('PMA_MYSQL_INT_VERSION')) { |
|
|
804 |
if (PMA_MYSQL_INT_VERSION < 50000) { |
|
|
805 |
$mysql = '4.1'; |
|
|
806 |
} elseif (PMA_MYSQL_INT_VERSION >= 50100) { |
|
|
807 |
$mysql = '5.1'; |
|
|
808 |
} elseif (PMA_MYSQL_INT_VERSION >= 50000) { |
|
|
809 |
$mysql = '5.0'; |
|
|
810 |
} |
|
|
811 |
} |
|
|
812 |
$url = $cfg['MySQLManualBase'] . '/' . $mysql . '/en/' . $link . '.html'; |
|
|
813 |
break; |
|
|
814 |
} |
|
|
815 |
|
|
|
816 |
if ($big_icon) { |
|
|
817 |
return '<a href="' . $url . '" target="mysql_doc"><img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 'b_sqlhelp.png" width="16" height="16" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" /></a>'; |
|
|
818 |
} elseif ($GLOBALS['cfg']['ReplaceHelpImg']) { |
|
|
819 |
return '<a href="' . $url . '" target="mysql_doc"><img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 'b_help.png" width="11" height="11" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" /></a>'; |
|
|
820 |
} else { |
|
|
821 |
return '[<a href="' . $url . '" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]'; |
|
|
822 |
} |
|
|
823 |
} // end of the 'PMA_showMySQLDocu()' function |
|
|
824 |
|
|
|
825 |
/** |
|
|
826 |
* Displays a hint icon, on mouse over show the hint |
|
|
827 |
* |
|
|
828 |
* @param string the error message |
|
|
829 |
* |
|
|
830 |
* @access public |
|
|
831 |
*/ |
|
|
832 |
function PMA_showHint($hint_message) |
|
|
833 |
{ |
|
|
834 |
//return '<img class="lightbulb" src="' . $GLOBALS['pmaThemeImage'] . 'b_tipp.png" width="16" height="16" border="0" alt="' . $hint_message . '" title="' . $hint_message . '" align="middle" onclick="alert(\'' . PMA_jsFormat($hint_message, false) . '\');" />'; |
|
|
835 |
return '<img class="lightbulb" src="' . $GLOBALS['pmaThemeImage'] . 'b_tipp.png" width="16" height="16" alt="Tip" title="Tip" onmouseover="pmaTooltip(\'' . PMA_jsFormat($hint_message, false) . '\'); return false;" onmouseout="swapTooltip(\'default\'); return false;" />'; |
|
|
836 |
} |
|
|
837 |
|
|
|
838 |
/** |
|
|
839 |
* Displays a MySQL error message in the right frame. |
|
|
840 |
* |
|
|
841 |
* @param string the error message |
|
|
842 |
* @param string the sql query that failed |
|
|
843 |
* @param boolean whether to show a "modify" link or not |
|
|
844 |
* @param string the "back" link url (full path is not required) |
|
|
845 |
* @param boolean EXIT the page? |
|
|
846 |
* |
|
|
847 |
* @global array the configuration array |
|
|
848 |
* |
|
|
849 |
* @access public |
|
|
850 |
*/ |
|
|
851 |
function PMA_mysqlDie($error_message = '', $the_query = '', |
|
|
852 |
$is_modify_link = true, $back_url = '', |
|
|
853 |
$exit = true) |
|
|
854 |
{ |
|
|
855 |
global $cfg, $table, $db, $sql_query; |
|
|
856 |
|
|
|
857 |
require_once './libraries/header.inc.php'; |
|
|
858 |
|
|
|
859 |
if (!$error_message) { |
|
|
860 |
$error_message = PMA_DBI_getError(); |
|
|
861 |
} |
|
|
862 |
if (!$the_query && !empty($GLOBALS['sql_query'])) { |
|
|
863 |
$the_query = $GLOBALS['sql_query']; |
|
|
864 |
} |
|
|
865 |
|
|
|
866 |
// --- Added to solve bug #641765 |
|
|
867 |
// Robbat2 - 12 January 2003, 9:46PM |
|
|
868 |
// Revised, Robbat2 - 13 January 2003, 2:59PM |
|
|
869 |
if (!function_exists('PMA_SQP_isError') || PMA_SQP_isError()) { |
|
|
870 |
$formatted_sql = htmlspecialchars($the_query); |
|
|
871 |
} elseif (empty($the_query) || trim($the_query) == '') { |
|
|
872 |
$formatted_sql = ''; |
|
|
873 |
} else { |
|
|
874 |
$formatted_sql = PMA_formatSql(PMA_SQP_parse($the_query), $the_query); |
|
|
875 |
} |
|
|
876 |
// --- |
|
|
877 |
echo "\n" . '<!-- PMA-SQL-ERROR -->' . "\n"; |
|
|
878 |
echo ' <div class="error"><h1>' . $GLOBALS['strError'] . '</h1>' . "\n"; |
|
|
879 |
// if the config password is wrong, or the MySQL server does not |
|
|
880 |
// respond, do not show the query that would reveal the |
|
|
881 |
// username/password |
|
|
882 |
if (!empty($the_query) && !strstr($the_query, 'connect')) { |
|
|
883 |
// --- Added to solve bug #641765 |
|
|
884 |
// Robbat2 - 12 January 2003, 9:46PM |
|
|
885 |
// Revised, Robbat2 - 13 January 2003, 2:59PM |
|
|
886 |
if (function_exists('PMA_SQP_isError') && PMA_SQP_isError()) { |
|
|
887 |
echo PMA_SQP_getErrorString() . "\n"; |
|
|
888 |
echo '<br />' . "\n"; |
|
|
889 |
} |
|
|
890 |
// --- |
|
|
891 |
// modified to show me the help on sql errors (Michael Keck) |
|
|
892 |
echo ' <p><strong>' . $GLOBALS['strSQLQuery'] . ':</strong>' . "\n"; |
|
|
893 |
if (strstr(strtolower($formatted_sql), 'select')) { // please show me help to the error on select |
|
|
894 |
echo PMA_showMySQLDocu('SQL-Syntax', 'SELECT'); |
|
|
895 |
} |
|
|
896 |
if ($is_modify_link && isset($db)) { |
|
|
897 |
if (isset($table)) { |
|
|
898 |
$doedit_goto = '<a href="tbl_properties.php?' . PMA_generate_common_url($db, $table) . '&sql_query=' . urlencode($the_query) . '&show_query=1">'; |
|
|
899 |
} else { |
|
|
900 |
$doedit_goto = '<a href="db_details.php?' . PMA_generate_common_url($db) . '&sql_query=' . urlencode($the_query) . '&show_query=1">'; |
|
|
901 |
} |
|
|
902 |
if ($GLOBALS['cfg']['PropertiesIconic']) { |
|
|
903 |
echo $doedit_goto |
|
|
904 |
. '<img class="icon" src=" '. $GLOBALS['pmaThemeImage'] . 'b_edit.png" width="16" height="16" alt="' . $GLOBALS['strEdit'] .'" />' |
|
|
905 |
. '</a>'; |
|
|
906 |
} else { |
|
|
907 |
echo ' [' |
|
|
908 |
. $doedit_goto . $GLOBALS['strEdit'] . '</a>' |
|
|
909 |
. ']' . "\n"; |
|
|
910 |
} |
|
|
911 |
} // end if |
|
|
912 |
echo ' </p>' . "\n" |
|
|
913 |
.' <p>' . "\n" |
|
|
914 |
.' ' . $formatted_sql . "\n" |
|
|
915 |
.' </p>' . "\n"; |
|
|
916 |
} // end if |
|
|
917 |
|
|
|
918 |
$tmp_mysql_error = ''; // for saving the original $error_message |
|
|
919 |
if (!empty($error_message)) { |
|
|
920 |
$tmp_mysql_error = strtolower($error_message); // save the original $error_message |
|
|
921 |
$error_message = htmlspecialchars($error_message); |
|
|
922 |
$error_message = preg_replace("@((\015\012)|(\015)|(\012)){3,}@", "\n\n", $error_message); |
|
|
923 |
} |
|
|
924 |
// modified to show me the help on error-returns (Michael Keck) |
|
|
925 |
echo '<p>' . "\n" |
|
|
926 |
. ' <strong>' . $GLOBALS['strMySQLSaid'] . '</strong>' |
|
|
927 |
. PMA_showMySQLDocu('Error-returns', 'Error-returns') |
|
|
928 |
. "\n" |
|
|
929 |
. '</p>' . "\n"; |
|
|
930 |
|
|
|
931 |
// The error message will be displayed within a CODE segment. |
|
|
932 |
// To preserve original formatting, but allow wordwrapping, we do a couple of replacements |
|
|
933 |
|
|
|
934 |
// Replace all non-single blanks with their HTML-counterpart |
|
|
935 |
$error_message = str_replace(' ', ' ', $error_message); |
|
|
936 |
// Replace TAB-characters with their HTML-counterpart |
|
|
937 |
$error_message = str_replace("\t", ' ', $error_message); |
|
|
938 |
// Replace linebreaks |
|
|
939 |
$error_message = nl2br($error_message); |
|
|
940 |
|
|
|
941 |
echo '<code>' . "\n" |
|
|
942 |
. $error_message . "\n" |
|
|
943 |
. '</code><br />' . "\n"; |
|
|
944 |
|
|
|
945 |
// feature request #1036254: |
|
|
946 |
// Add a link by MySQL-Error #1062 - Duplicate entry |
|
|
947 |
// 2004-10-20 by mkkeck |
|
|
948 |
// 2005-01-17 modified by mkkeck bugfix |
|
|
949 |
if (substr($error_message, 1, 4) == '1062') { |
|
|
950 |
// get the duplicate entry |
|
|
951 |
|
|
|
952 |
// get table name |
|
|
953 |
// TODO: what would be the best delimiter, while avoiding |
|
|
954 |
// special characters that can become high-ascii after editing, |
|
|
955 |
// depending upon which editor is used by the developer? |
|
|
956 |
$error_table = array(); |
|
|
957 |
if (preg_match('@ALTER\s*TABLE\s*\`([^\`]+)\`@iu', $the_query, $error_table)) { |
|
|
958 |
$error_table = $error_table[1]; |
|
|
959 |
} elseif (preg_match('@INSERT\s*INTO\s*\`([^\`]+)\`@iu', $the_query, $error_table)) { |
|
|
960 |
$error_table = $error_table[1]; |
|
|
961 |
} elseif (preg_match('@UPDATE\s*\`([^\`]+)\`@iu', $the_query, $error_table)) { |
|
|
962 |
$error_table = $error_table[1]; |
|
|
963 |
} elseif (preg_match('@INSERT\s*\`([^\`]+)\`@iu', $the_query, $error_table)) { |
|
|
964 |
$error_table = $error_table[1]; |
|
|
965 |
} |
|
|
966 |
|
|
|
967 |
// get fields |
|
|
968 |
$error_fields = array(); |
|
|
969 |
if (preg_match('@\(([^\)]+)\)@i', $the_query, $error_fields)) { |
|
|
970 |
$error_fields = explode(',', $error_fields[1]); |
|
|
971 |
} elseif (preg_match('@(`[^`]+`)\s*=@i', $the_query, $error_fields)) { |
|
|
972 |
$error_fields = explode(',', $error_fields[1]); |
|
|
973 |
} |
|
|
974 |
if (is_array($error_table) || is_array($error_fields)) { |
|
|
975 |
|
|
|
976 |
// duplicate value |
|
|
977 |
$duplicate_value = array(); |
|
|
978 |
preg_match('@\'([^\']+)\'@i', $tmp_mysql_error, $duplicate_value); |
|
|
979 |
$duplicate_value = $duplicate_value[1]; |
|
|
980 |
|
|
|
981 |
$sql = ' |
|
|
982 |
SELECT * |
|
|
983 |
FROM ' . PMA_backquote($error_table) . ' |
|
|
984 |
WHERE CONCAT_WS("-", ' . implode(', ', $error_fields) . ') |
|
|
985 |
= "' . PMA_sqlAddslashes($duplicate_value) . '" |
|
|
986 |
ORDER BY ' . implode(', ', $error_fields); |
|
|
987 |
unset($error_table, $error_fields, $duplicate_value); |
|
|
988 |
|
|
|
989 |
echo ' <form method="post" action="import.php" style="padding: 0; margin: 0">' ."\n" |
|
|
990 |
.' <input type="hidden" name="sql_query" value="' . htmlentities($sql) . '" />' . "\n" |
|
|
991 |
.' ' . PMA_generate_common_hidden_inputs($db, $table) . "\n" |
|
|
992 |
.' <input type="submit" name="submit" value="' . $GLOBALS['strBrowse'] . '" />' . "\n" |
|
|
993 |
.' </form>' . "\n"; |
|
|
994 |
unset($sql); |
|
|
995 |
} |
|
|
996 |
} // end of show duplicate entry |
|
|
997 |
|
|
|
998 |
echo '</div>'; |
|
|
999 |
echo '<fieldset class="tblFooters">'; |
|
|
1000 |
|
|
|
1001 |
if (!empty($back_url) && $exit) { |
|
|
1002 |
$goto_back_url='<a href="' . (strstr($back_url, '?') ? $back_url . '&no_history=true' : $back_url . '?no_history=true') . '">'; |
|
|
1003 |
echo '[ ' . $goto_back_url . $GLOBALS['strBack'] . '</a> ]'; |
|
|
1004 |
} |
|
|
1005 |
echo ' </fieldset>' . "\n\n"; |
|
|
1006 |
if ($exit) { |
|
|
1007 |
require_once './libraries/footer.inc.php'; |
|
|
1008 |
} |
|
|
1009 |
} // end of the 'PMA_mysqlDie()' function |
|
|
1010 |
|
|
|
1011 |
/** |
|
|
1012 |
* Returns a string formatted with CONVERT ... USING |
|
|
1013 |
* if MySQL supports it |
|
|
1014 |
* |
|
|
1015 |
* @param string the string itself |
|
|
1016 |
* @param string the mode: quoted or unquoted (this one by default) |
|
|
1017 |
* |
|
|
1018 |
* @return the formatted string |
|
|
1019 |
* |
|
|
1020 |
* @access private |
|
|
1021 |
*/ |
|
|
1022 |
function PMA_convert_using($string, $mode='unquoted') |
|
|
1023 |
{ |
|
|
1024 |
if ($mode == 'quoted') { |
|
|
1025 |
$possible_quote = "'"; |
|
|
1026 |
} else { |
|
|
1027 |
$possible_quote = ""; |
|
|
1028 |
} |
|
|
1029 |
|
|
|
1030 |
if (PMA_MYSQL_INT_VERSION >= 40100) { |
|
|
1031 |
list($conn_charset) = explode('_', $GLOBALS['collation_connection']); |
|
|
1032 |
$converted_string = "CONVERT(" . $possible_quote . $string . $possible_quote . " USING " . $conn_charset . ")"; |
|
|
1033 |
} else { |
|
|
1034 |
$converted_string = $possible_quote . $string . $possible_quote; |
|
|
1035 |
} |
|
|
1036 |
return $converted_string; |
|
|
1037 |
} // end function |
|
|
1038 |
|
|
|
1039 |
/** |
|
|
1040 |
* Send HTTP header, taking IIS limits into account (600 seems ok) |
|
|
1041 |
* |
|
|
1042 |
* @param string $uri the header to send |
|
|
1043 |
* @return boolean always true |
|
|
1044 |
*/ |
|
|
1045 |
function PMA_sendHeaderLocation($uri) |
|
|
1046 |
{ |
|
|
1047 |
if (PMA_IS_IIS && strlen($uri) > 600) { |
|
|
1048 |
|
|
|
1049 |
echo '<html><head><title>- - -</title>' . "\n"; |
|
|
1050 |
echo '<meta http-equiv="expires" content="0">' . "\n"; |
|
|
1051 |
echo '<meta http-equiv="Pragma" content="no-cache">' . "\n"; |
|
|
1052 |
echo '<meta http-equiv="Cache-Control" content="no-cache">' . "\n"; |
|
|
1053 |
echo '<meta http-equiv="Refresh" content="0;url=' .$uri . '">' . "\n"; |
|
|
1054 |
echo '<script type="text/javascript" language="javascript">' . "\n"; |
|
|
1055 |
echo '//<![CDATA[' . "\n"; |
|
|
1056 |
echo 'setTimeout ("window.location = unescape(\'"' . $uri . '"\')",2000); </script>' . "\n"; |
|
|
1057 |
echo '//]]>' . "\n"; |
|
|
1058 |
echo '</head>' . "\n"; |
|
|
1059 |
echo '<body>' . "\n"; |
|
|
1060 |
echo '<script type="text/javascript" language="javascript">' . "\n"; |
|
|
1061 |
echo '//<![CDATA[' . "\n"; |
|
|
1062 |
echo 'document.write (\'<p><a href="' . $uri . '">' . $GLOBALS['strGo'] . '</a></p>\');' . "\n"; |
|
|
1063 |
echo '//]]>' . "\n"; |
|
|
1064 |
echo '</script></body></html>' . "\n"; |
|
|
1065 |
|
|
|
1066 |
} else { |
|
|
1067 |
if (SID) { |
|
|
1068 |
if (strpos($uri, '?') === false) { |
|
|
1069 |
header('Location: ' . $uri . '?' . SID); |
|
|
1070 |
} else { |
|
|
1071 |
// use seperators defined by php, but prefer ';' |
|
|
1072 |
// as recommended by W3C |
|
|
1073 |
$php_arg_separator_input = ini_get('arg_separator.input'); |
|
|
1074 |
if (strpos($php_arg_separator_input, ';') !== false) { |
|
|
1075 |
$separator = ';'; |
|
|
1076 |
} elseif (strlen($php_arg_separator_input) > 0) { |
|
|
1077 |
$separator = $php_arg_separator_input{0}; |
|
|
1078 |
} else { |
|
|
1079 |
$separator = '&'; |
|
|
1080 |
} |
|
|
1081 |
header('Location: ' . $uri . $separator . SID); |
|
|
1082 |
} |
|
|
1083 |
} else { |
|
|
1084 |
session_write_close(); |
|
|
1085 |
// bug #1523784, IE6 does not like 'Refresh: 0', it |
|
|
1086 |
// results in a blank page |
|
|
1087 |
if (PMA_IS_IIS && defined('PMA_COMING_FROM_COOKIE_LOGIN')) { |
|
|
1088 |
header('Refresh: 0; ' . $uri); |
|
|
1089 |
} else { |
|
|
1090 |
header('Location: ' . $uri); |
|
|
1091 |
} |
|
|
1092 |
} |
|
|
1093 |
} |
|
|
1094 |
} |
|
|
1095 |
|
|
|
1096 |
/** |
|
|
1097 |
* Get the list and number of available databases. |
|
|
1098 |
* |
|
|
1099 |
* @param string the url to go back to in case of error |
|
|
1100 |
* |
|
|
1101 |
* @return boolean always true |
|
|
1102 |
* |
|
|
1103 |
* @global array the list of available databases |
|
|
1104 |
* @global integer the number of available databases |
|
|
1105 |
* @global array current configuration |
|
|
1106 |
*/ |
|
|
1107 |
function PMA_availableDatabases($error_url = '') |
|
|
1108 |
{ |
|
|
1109 |
global $dblist; |
|
|
1110 |
global $num_dbs; |
|
|
1111 |
global $cfg; |
|
|
1112 |
|
|
|
1113 |
// 1. A list of allowed databases has already been defined by the |
|
|
1114 |
// authentication process -> gets the available databases list |
|
|
1115 |
if (count($dblist)) { |
|
|
1116 |
foreach ($dblist as $key => $db) { |
|
|
1117 |
if (!@PMA_DBI_select_db($db) || (!empty($GLOBALS['cfg']['Server']['hide_db']) && preg_match('/' . $GLOBALS['cfg']['Server']['hide_db'] . '/', $db))) { |
|
|
1118 |
unset($dblist[$key]); |
|
|
1119 |
} // end if |
|
|
1120 |
} // end for |
|
|
1121 |
} // end if |
|
|
1122 |
// 2. Allowed database list is empty -> gets the list of all databases |
|
|
1123 |
// on the server |
|
|
1124 |
elseif (empty($cfg['Server']['only_db'])) { |
|
|
1125 |
$dblist = PMA_DBI_get_dblist(); // needed? or PMA_mysqlDie('', 'SHOW DATABASES;', false, $error_url); |
|
|
1126 |
} // end else |
|
|
1127 |
|
|
|
1128 |
$num_dbs = count($dblist); |
|
|
1129 |
|
|
|
1130 |
// natural order for db list; but do not sort if user asked |
|
|
1131 |
// for a specific order with the 'only_db' mechanism |
|
|
1132 |
if (!is_array($GLOBALS['cfg']['Server']['only_db']) |
|
|
1133 |
&& $GLOBALS['cfg']['NaturalOrder']) { |
|
|
1134 |
natsort($dblist); |
|
|
1135 |
} |
|
|
1136 |
|
|
|
1137 |
return true; |
|
|
1138 |
} // end of the 'PMA_availableDatabases()' function |
|
|
1139 |
|
|
|
1140 |
/** |
|
|
1141 |
* returns array with tables of given db with extended infomation and grouped |
|
|
1142 |
* |
|
|
1143 |
* @uses $GLOBALS['cfg']['LeftFrameTableSeparator'] |
|
|
1144 |
* @uses $GLOBALS['cfg']['LeftFrameTableLevel'] |
|
|
1145 |
* @uses $GLOBALS['cfg']['ShowTooltipAliasTB'] |
|
|
1146 |
* @uses $GLOBALS['cfg']['NaturalOrder'] |
|
|
1147 |
* @uses PMA_DBI_fetch_result() |
|
|
1148 |
* @uses PMA_backquote() |
|
|
1149 |
* @uses count() |
|
|
1150 |
* @uses array_merge |
|
|
1151 |
* @uses uksort() |
|
|
1152 |
* @uses strstr() |
|
|
1153 |
* @uses explode() |
|
|
1154 |
* @param string $db name of db |
|
|
1155 |
* return array (rekursive) grouped table list |
|
|
1156 |
*/ |
|
|
1157 |
function PMA_getTableList($db, $tables = null) |
|
|
1158 |
{ |
|
|
1159 |
$sep = $GLOBALS['cfg']['LeftFrameTableSeparator']; |
|
|
1160 |
|
|
|
1161 |
if ( null === $tables ) { |
|
|
1162 |
$tables = PMA_DBI_get_tables_full($db); |
|
|
1163 |
if ($GLOBALS['cfg']['NaturalOrder']) { |
|
|
1164 |
uksort($tables, 'strnatcasecmp'); |
|
|
1165 |
} |
|
|
1166 |
} |
|
|
1167 |
|
|
|
1168 |
if (count($tables) < 1) { |
|
|
1169 |
return $tables; |
|
|
1170 |
} |
|
|
1171 |
|
|
|
1172 |
$default = array( |
|
|
1173 |
'Name' => '', |
|
|
1174 |
'Rows' => 0, |
|
|
1175 |
'Comment' => '', |
|
|
1176 |
'disp_name' => '', |
|
|
1177 |
); |
|
|
1178 |
|
|
|
1179 |
$table_groups = array(); |
|
|
1180 |
|
|
|
1181 |
foreach ($tables as $table_name => $table) { |
|
|
1182 |
|
|
|
1183 |
// check for correct row count |
|
|
1184 |
if (null === $table['Rows']) { |
|
|
1185 |
// Do not check exact row count here, |
|
|
1186 |
// if row count is invalid possibly the table is defect |
|
|
1187 |
// and this would break left frame; |
|
|
1188 |
// but we can check row count if this is a view, |
|
|
1189 |
// since PMA_countRecords() returns a limited row count |
|
|
1190 |
// in this case. |
|
|
1191 |
|
|
|
1192 |
// set this because PMA_countRecords() can use it |
|
|
1193 |
$tbl_is_view = PMA_tableIsView($db, $table['Name']); |
|
|
1194 |
|
|
|
1195 |
if ($tbl_is_view) { |
|
|
1196 |
$table['Rows'] = PMA_countRecords($db, $table['Name'], |
|
|
1197 |
$return = true); |
|
|
1198 |
} |
|
|
1199 |
} |
|
|
1200 |
|
|
|
1201 |
// in $group we save the reference to the place in $table_groups |
|
|
1202 |
// where to store the table info |
|
|
1203 |
if ($GLOBALS['cfg']['LeftFrameDBTree'] |
|
|
1204 |
&& $sep && strstr($table_name, $sep)) |
|
|
1205 |
{ |
|
|
1206 |
$parts = explode($sep, $table_name); |
|
|
1207 |
|
|
|
1208 |
$group =& $table_groups; |
|
|
1209 |
$i = 0; |
|
|
1210 |
$group_name_full = ''; |
|
|
1211 |
while ($i < count($parts) - 1 |
|
|
1212 |
&& $i < $GLOBALS['cfg']['LeftFrameTableLevel']) { |
|
|
1213 |
$group_name = $parts[$i] . $sep; |
|
|
1214 |
$group_name_full .= $group_name; |
|
|
1215 |
|
|
|
1216 |
if (!isset($group[$group_name])) { |
|
|
1217 |
$group[$group_name] = array(); |
|
|
1218 |
$group[$group_name]['is' . $sep . 'group'] = true; |
|
|
1219 |
$group[$group_name]['tab' . $sep . 'count'] = 1; |
|
|
1220 |
$group[$group_name]['tab' . $sep . 'group'] = $group_name_full; |
|
|
1221 |
} elseif (!isset($group[$group_name]['is' . $sep . 'group'])) { |
|
|
1222 |
$table = $group[$group_name]; |
|
|
1223 |
$group[$group_name] = array(); |
|
|
1224 |
$group[$group_name][$group_name] = $table; |
|
|
1225 |
unset($table); |
|
|
1226 |
$group[$group_name]['is' . $sep . 'group'] = true; |
|
|
1227 |
$group[$group_name]['tab' . $sep . 'count'] = 1; |
|
|
1228 |
$group[$group_name]['tab' . $sep . 'group'] = $group_name_full; |
|
|
1229 |
} else { |
|
|
1230 |
$group[$group_name]['tab' . $sep . 'count']++; |
|
|
1231 |
} |
|
|
1232 |
$group =& $group[$group_name]; |
|
|
1233 |
$i++; |
|
|
1234 |
} |
|
|
1235 |
} else { |
|
|
1236 |
if (!isset($table_groups[$table_name])) { |
|
|
1237 |
$table_groups[$table_name] = array(); |
|
|
1238 |
} |
|
|
1239 |
$group =& $table_groups; |
|
|
1240 |
} |
|
|
1241 |
|
|
|
1242 |
|
|
|
1243 |
if ($GLOBALS['cfg']['ShowTooltipAliasTB'] |
|
|
1244 |
&& $GLOBALS['cfg']['ShowTooltipAliasTB'] !== 'nested') { |
|
|
1245 |
// switch tooltip and name |
|
|
1246 |
$table['Comment'] = $table['Name']; |
|
|
1247 |
$table['disp_name'] = $table['Comment']; |
|
|
1248 |
} else { |
|
|
1249 |
$table['disp_name'] = $table['Name']; |
|
|
1250 |
} |
|
|
1251 |
|
|
|
1252 |
$group[$table_name] = array_merge($default, $table); |
|
|
1253 |
} |
|
|
1254 |
|
|
|
1255 |
return $table_groups; |
|
|
1256 |
} |
|
|
1257 |
|
|
|
1258 |
/* ----------------------- Set of misc functions ----------------------- */ |
|
|
1259 |
|
|
|
1260 |
|
|
|
1261 |
/** |
|
|
1262 |
* Adds backquotes on both sides of a database, table or field name. |
|
|
1263 |
* and escapes backquotes inside the name with another backquote |
|
|
1264 |
* |
|
|
1265 |
* <code> |
|
|
1266 |
* echo PMA_backquote('owner`s db'); // `owner``s db` |
|
|
1267 |
* </code> |
|
|
1268 |
* |
|
|
1269 |
* @param mixed $a_name the database, table or field name to "backquote" |
|
|
1270 |
* or array of it |
|
|
1271 |
* @param boolean $do_it a flag to bypass this function (used by dump |
|
|
1272 |
* functions) |
|
|
1273 |
* @return mixed the "backquoted" database, table or field name if the |
|
|
1274 |
* current MySQL release is >= 3.23.6, the original one |
|
|
1275 |
* else |
|
|
1276 |
* @access public |
|
|
1277 |
*/ |
|
|
1278 |
function PMA_backquote($a_name, $do_it = true) |
|
|
1279 |
{ |
|
|
1280 |
if (! $do_it) { |
|
|
1281 |
return $a_name; |
|
|
1282 |
} |
|
|
1283 |
|
|
|
1284 |
if (is_array($a_name)) { |
|
|
1285 |
$result = array(); |
|
|
1286 |
foreach ($a_name as $key => $val) { |
|
|
1287 |
$result[$key] = PMA_backquote($val); |
|
|
1288 |
} |
|
|
1289 |
return $result; |
|
|
1290 |
} |
|
|
1291 |
|
|
|
1292 |
// '0' is also empty for php :-( |
|
|
1293 |
if (strlen($a_name) && $a_name != '*') { |
|
|
1294 |
return '`' . str_replace('`', '``', $a_name) . '`'; |
|
|
1295 |
} else { |
|
|
1296 |
return $a_name; |
|
|
1297 |
} |
|
|
1298 |
} // end of the 'PMA_backquote()' function |
|
|
1299 |
|
|
|
1300 |
|
|
|
1301 |
/** |
|
|
1302 |
* Format a string so it can be passed to a javascript function. |
|
|
1303 |
* This function is used to displays a javascript confirmation box for |
|
|
1304 |
* "DROP/DELETE/ALTER" queries. |
|
|
1305 |
* |
|
|
1306 |
* @param string the string to format |
|
|
1307 |
* @param boolean whether to add backquotes to the string or not |
|
|
1308 |
* |
|
|
1309 |
* @return string the formated string |
|
|
1310 |
* |
|
|
1311 |
* @access public |
|
|
1312 |
*/ |
|
|
1313 |
function PMA_jsFormat($a_string = '', $add_backquotes = true) |
|
|
1314 |
{ |
|
|
1315 |
if (is_string($a_string)) { |
|
|
1316 |
$a_string = htmlspecialchars($a_string); |
|
|
1317 |
$a_string = str_replace('\\', '\\\\', $a_string); |
|
|
1318 |
$a_string = str_replace('\'', '\\\'', $a_string); |
|
|
1319 |
$a_string = str_replace('#', '\\#', $a_string); |
|
|
1320 |
$a_string = str_replace("\012", '\\\\n', $a_string); |
|
|
1321 |
$a_string = str_replace("\015", '\\\\r', $a_string); |
|
|
1322 |
} |
|
|
1323 |
|
|
|
1324 |
return (($add_backquotes) ? PMA_backquote($a_string) : $a_string); |
|
|
1325 |
} // end of the 'PMA_jsFormat()' function |
|
|
1326 |
|
|
|
1327 |
|
|
|
1328 |
/** |
|
|
1329 |
* Defines the <CR><LF> value depending on the user OS. |
|
|
1330 |
* |
|
|
1331 |
* @return string the <CR><LF> value to use |
|
|
1332 |
* |
|
|
1333 |
* @access public |
|
|
1334 |
*/ |
|
|
1335 |
function PMA_whichCrlf() |
|
|
1336 |
{ |
|
|
1337 |
$the_crlf = "\n"; |
|
|
1338 |
|
|
|
1339 |
// The 'PMA_USR_OS' constant is defined in "./libraries/defines.lib.php" |
|
|
1340 |
// Win case |
|
|
1341 |
if (PMA_USR_OS == 'Win') { |
|
|
1342 |
$the_crlf = "\r\n"; |
|
|
1343 |
} |
|
|
1344 |
// Mac case |
|
|
1345 |
elseif (PMA_USR_OS == 'Mac') { |
|
|
1346 |
$the_crlf = "\r"; |
|
|
1347 |
} |
|
|
1348 |
// Others |
|
|
1349 |
else { |
|
|
1350 |
$the_crlf = "\n"; |
|
|
1351 |
} |
|
|
1352 |
|
|
|
1353 |
return $the_crlf; |
|
|
1354 |
} // end of the 'PMA_whichCrlf()' function |
|
|
1355 |
|
|
|
1356 |
/** |
|
|
1357 |
* Checks if this "table" is a view |
|
|
1358 |
* |
|
|
1359 |
* @param string the database name |
|
|
1360 |
* @param string the table name |
|
|
1361 |
* |
|
|
1362 |
* @return boolean whether this is a view |
|
|
1363 |
* |
|
|
1364 |
* @access public |
|
|
1365 |
*/ |
|
|
1366 |
function PMA_tableIsView($db, $table) { |
|
|
1367 |
// maybe we already know if the table is a view |
|
|
1368 |
// TODO: see what we could do with the possible existence |
|
|
1369 |
// of $table_is_view |
|
|
1370 |
if (isset($GLOBALS['tbl_is_view']) && $GLOBALS['tbl_is_view']) { |
|
|
1371 |
return true; |
|
|
1372 |
} |
|
|
1373 |
// old MySQL version: no view |
|
|
1374 |
if (PMA_MYSQL_INT_VERSION < 50000) { |
|
|
1375 |
return false; |
|
|
1376 |
} |
|
|
1377 |
if ( false === PMA_DBI_fetch_value('SELECT TABLE_NAME FROM information_schema.VIEWS WHERE TABLE_SCHEMA = \'' . $db . '\' AND TABLE_NAME = \'' . $table . '\';')) { |
|
|
1378 |
return false; |
|
|
1379 |
} else { |
|
|
1380 |
return true; |
|
|
1381 |
} |
|
|
1382 |
} |
|
|
1383 |
|
|
|
1384 |
/** |
|
|
1385 |
* Counts and returns (or displays) the number of records in a table |
|
|
1386 |
* |
|
|
1387 |
* Revision 13 July 2001: Patch for limiting dump size from |
|
|
1388 |
* vinay@sanisoft.com & girish@sanisoft.com |
|
|
1389 |
* |
|
|
1390 |
* @param string the current database name |
|
|
1391 |
* @param string the current table name |
|
|
1392 |
* @param boolean whether to retain or to displays the result |
|
|
1393 |
* @param boolean whether to force an exact count |
|
|
1394 |
* |
|
|
1395 |
* @return mixed the number of records if retain is required, true else |
|
|
1396 |
* |
|
|
1397 |
* @access public |
|
|
1398 |
*/ |
|
|
1399 |
function PMA_countRecords($db, $table, $ret = false, $force_exact = false) |
|
|
1400 |
{ |
|
|
1401 |
global $err_url, $cfg; |
|
|
1402 |
if (!$force_exact) { |
|
|
1403 |
$result = PMA_DBI_query('SHOW TABLE STATUS FROM ' . PMA_backquote($db) . ' LIKE \'' . PMA_sqlAddslashes($table, true) . '\';'); |
|
|
1404 |
$showtable = PMA_DBI_fetch_assoc($result); |
|
|
1405 |
$num = (isset($showtable['Rows']) ? $showtable['Rows'] : 0); |
|
|
1406 |
if ($num < $cfg['MaxExactCount']) { |
|
|
1407 |
unset($num); |
|
|
1408 |
} |
|
|
1409 |
PMA_DBI_free_result($result); |
|
|
1410 |
} |
|
|
1411 |
|
|
|
1412 |
$tbl_is_view = PMA_tableIsView($db, $table); |
|
|
1413 |
|
|
|
1414 |
if (!isset($num)) { |
|
|
1415 |
if (! $tbl_is_view) { |
|
|
1416 |
$num = PMA_DBI_fetch_value('SELECT COUNT(*) AS num FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table)); |
|
|
1417 |
// necessary? |
|
|
1418 |
if (! $num) { |
|
|
1419 |
$num = 0; |
|
|
1420 |
} |
|
|
1421 |
// since counting all rows of a view could be too long |
|
|
1422 |
} else { |
|
|
1423 |
// try_query because if can fail (a VIEW was based on a |
|
|
1424 |
// table that no longer exists) |
|
|
1425 |
$result = PMA_DBI_try_query('SELECT 1 FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table) . ' LIMIT ' . $cfg['MaxExactCount'], null, PMA_DBI_QUERY_STORE); |
|
|
1426 |
if (!PMA_DBI_getError()) { |
|
|
1427 |
$num = PMA_DBI_num_rows($result); |
|
|
1428 |
} else { |
|
|
1429 |
$num = 0; |
|
|
1430 |
} |
|
|
1431 |
} |
|
|
1432 |
} |
|
|
1433 |
if ($ret) { |
|
|
1434 |
return $num; |
|
|
1435 |
} else { |
|
|
1436 |
// Note: as of PMA 2.8.0, we no longer seem to be using |
|
|
1437 |
// PMA_countRecords() in display mode. |
|
|
1438 |
echo number_format($num, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']); |
|
|
1439 |
if ($tbl_is_view) { |
|
|
1440 |
echo ' ' . sprintf($GLOBALS['strViewMaxExactCount'], $cfg['MaxExactCount'], '[a@./Documentation.html#cfg_MaxExactCount@_blank]', '[/a]'); |
|
|
1441 |
} |
|
|
1442 |
return true; |
|
|
1443 |
} |
|
|
1444 |
} // end of the 'PMA_countRecords()' function |
|
|
1445 |
|
|
|
1446 |
/** |
|
|
1447 |
* Reloads navigation if needed. |
|
|
1448 |
* |
|
|
1449 |
* @global mixed configuration |
|
|
1450 |
* @global bool whether to reload |
|
|
1451 |
* |
|
|
1452 |
* @access public |
|
|
1453 |
*/ |
|
|
1454 |
function PMA_reloadNavigation() |
|
|
1455 |
{ |
|
|
1456 |
global $cfg; |
|
|
1457 |
|
|
|
1458 |
// Reloads the navigation frame via JavaScript if required |
|
|
1459 |
if (isset($GLOBALS['reload']) && $GLOBALS['reload']) { |
|
|
1460 |
echo "\n"; |
|
|
1461 |
$reload_url = './left.php?' . PMA_generate_common_url((isset($GLOBALS['db']) ? $GLOBALS['db'] : ''), '', '&'); |
|
|
1462 |
?> |
|
|
1463 |
<script type="text/javascript" language="javascript"> |
|
|
1464 |
//<![CDATA[ |
|
|
1465 |
if (typeof(window.parent) != 'undefined' |
|
|
1466 |
&& typeof(window.parent.frames[0]) != 'undefined') { |
|
|
1467 |
window.parent.goTo('<?php echo $reload_url; ?>'); |
|
|
1468 |
} |
|
|
1469 |
//]]> |
|
|
1470 |
</script> |
|
|
1471 |
<?php |
|
|
1472 |
unset($GLOBALS['reload']); |
|
|
1473 |
} |
|
|
1474 |
} |
|
|
1475 |
|
|
|
1476 |
/** |
|
|
1477 |
* Displays a message at the top of the "main" (right) frame |
|
|
1478 |
* |
|
|
1479 |
* @param string the message to display |
|
|
1480 |
* |
|
|
1481 |
* @global array the configuration array |
|
|
1482 |
* |
|
|
1483 |
* @access public |
|
|
1484 |
*/ |
|
|
1485 |
function PMA_showMessage($message) |
|
|
1486 |
{ |
|
|
1487 |
global $cfg; |
|
|
1488 |
|
|
|
1489 |
// Sanitizes $message |
|
|
1490 |
$message = PMA_sanitize($message); |
|
|
1491 |
|
|
|
1492 |
// Corrects the tooltip text via JS if required |
|
|
1493 |
if ( isset($GLOBALS['table']) && strlen($GLOBALS['table']) && $cfg['ShowTooltip']) { |
|
|
1494 |
$result = PMA_DBI_try_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], true) . '\''); |
|
|
1495 |
if ($result) { |
|
|
1496 |
$tbl_status = PMA_DBI_fetch_assoc($result); |
|
|
1497 |
$tooltip = (empty($tbl_status['Comment'])) |
|
|
1498 |
? '' |
|
|
1499 |
: $tbl_status['Comment'] . ' '; |
|
|
1500 |
$tooltip .= '(' . PMA_formatNumber($tbl_status['Rows'], 0) . ' ' . $GLOBALS['strRows'] . ')'; |
|
|
1501 |
PMA_DBI_free_result($result); |
|
|
1502 |
$uni_tbl = PMA_jsFormat($GLOBALS['db'] . '.' . $GLOBALS['table'], false); |
|
|
1503 |
echo "\n"; |
|
|
1504 |
?> |
|
|
1505 |
<script type="text/javascript" language="javascript"> |
|
|
1506 |
//<![CDATA[ |
|
|
1507 |
window.parent.updateTableTitle('<?php echo $uni_tbl; ?>', '<?php echo PMA_jsFormat($tooltip, false); ?>'); |
|
|
1508 |
//]]> |
|
|
1509 |
</script> |
|
|
1510 |
<?php |
|
|
1511 |
} // end if |
|
|
1512 |
} // end if ... elseif |
|
|
1513 |
|
|
|
1514 |
// Checks if the table needs to be repaired after a TRUNCATE query. |
|
|
1515 |
if (isset($GLOBALS['table']) && isset($GLOBALS['sql_query']) |
|
|
1516 |
&& $GLOBALS['sql_query'] == 'TRUNCATE TABLE ' . PMA_backquote($GLOBALS['table'])) { |
|
|
1517 |
if (!isset($tbl_status)) { |
|
|
1518 |
$result = @PMA_DBI_try_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], true) . '\''); |
|
|
1519 |
if ($result) { |
|
|
1520 |
$tbl_status = PMA_DBI_fetch_assoc($result); |
|
|
1521 |
PMA_DBI_free_result($result); |
|
|
1522 |
} |
|
|
1523 |
} |
|
|
1524 |
if (isset($tbl_status) && (int) $tbl_status['Index_length'] > 1024) { |
|
|
1525 |
PMA_DBI_try_query('REPAIR TABLE ' . PMA_backquote($GLOBALS['table'])); |
|
|
1526 |
} |
|
|
1527 |
} |
|
|
1528 |
unset($tbl_status); |
|
|
1529 |
?> |
|
|
1530 |
<br /> |
|
|
1531 |
<div align="<?php echo $GLOBALS['cell_align_left']; ?>"> |
|
|
1532 |
<?php |
|
|
1533 |
if (!empty($GLOBALS['show_error_header'])) { |
|
|
1534 |
?> |
|
|
1535 |
<div class="error"> |
|
|
1536 |
<h1><?php echo $GLOBALS['strError']; ?></h1> |
|
|
1537 |
<?php |
|
|
1538 |
} |
|
|
1539 |
|
|
|
1540 |
echo $message; |
|
|
1541 |
if (isset($GLOBALS['special_message'])) { |
|
|
1542 |
echo PMA_sanitize($GLOBALS['special_message']); |
|
|
1543 |
unset($GLOBALS['special_message']); |
|
|
1544 |
} |
|
|
1545 |
|
|
|
1546 |
if (!empty($GLOBALS['show_error_header'])) { |
|
|
1547 |
echo '</div>'; |
|
|
1548 |
} |
|
|
1549 |
|
|
|
1550 |
if ($cfg['ShowSQL'] == true |
|
|
1551 |
&& (!empty($GLOBALS['sql_query']) || !empty($GLOBALS['display_query']))) { |
|
|
1552 |
$local_query = !empty($GLOBALS['display_query']) ? $GLOBALS['display_query'] : (($cfg['SQP']['fmtType'] == 'none' && isset($GLOBALS['unparsed_sql']) && $GLOBALS['unparsed_sql'] != '') ? $GLOBALS['unparsed_sql'] : $GLOBALS['sql_query']); |
|
|
1553 |
// Basic url query part |
|
|
1554 |
$url_qpart = '?' . PMA_generate_common_url(isset($GLOBALS['db']) ? $GLOBALS['db'] : '', isset($GLOBALS['table']) ? $GLOBALS['table'] : ''); |
|
|
1555 |
|
|
|
1556 |
// Html format the query to be displayed |
|
|
1557 |
// The nl2br function isn't used because its result isn't a valid |
|
|
1558 |
// xhtml1.0 statement before php4.0.5 ("<br>" and not "<br />") |
|
|
1559 |
// If we want to show some sql code it is easiest to create it here |
|
|
1560 |
/* SQL-Parser-Analyzer */ |
|
|
1561 |
|
|
|
1562 |
if (!empty($GLOBALS['show_as_php'])) { |
|
|
1563 |
$new_line = '\'<br />' . "\n" . ' . \' '; |
|
|
1564 |
} |
|
|
1565 |
if (isset($new_line)) { |
|
|
1566 |
/* SQL-Parser-Analyzer */ |
|
|
1567 |
$query_base = PMA_sqlAddslashes(htmlspecialchars($local_query), false, false, true); |
|
|
1568 |
/* SQL-Parser-Analyzer */ |
|
|
1569 |
$query_base = preg_replace("@((\015\012)|(\015)|(\012))+@", $new_line, $query_base); |
|
|
1570 |
} else { |
|
|
1571 |
$query_base = $local_query; |
|
|
1572 |
} |
|
|
1573 |
|
|
|
1574 |
// Parse SQL if needed |
|
|
1575 |
if (isset($GLOBALS['parsed_sql']) && $query_base == $GLOBALS['parsed_sql']['raw']) { |
|
|
1576 |
$parsed_sql = $GLOBALS['parsed_sql']; |
|
|
1577 |
} else { |
|
|
1578 |
// when the query is large (for example an INSERT of binary |
|
|
1579 |
// data), the parser chokes; so avoid parsing it |
|
|
1580 |
if (strlen($query_base) < 1000) { |
|
|
1581 |
$parsed_sql = PMA_SQP_parse($query_base); |
|
|
1582 |
} |
|
|
1583 |
} |
|
|
1584 |
|
|
|
1585 |
// Analyze it |
|
|
1586 |
if (isset($parsed_sql)) { |
|
|
1587 |
$analyzed_display_query = PMA_SQP_analyze($parsed_sql); |
|
|
1588 |
} |
|
|
1589 |
|
|
|
1590 |
// Here we append the LIMIT added for navigation, to |
|
|
1591 |
// enable its display. Adding it higher in the code |
|
|
1592 |
// to $local_query would create a problem when |
|
|
1593 |
// using the Refresh or Edit links. |
|
|
1594 |
|
|
|
1595 |
// Only append it on SELECTs. |
|
|
1596 |
|
|
|
1597 |
// FIXME: what would be the best to do when someone |
|
|
1598 |
// hits Refresh: use the current LIMITs ? |
|
|
1599 |
|
|
|
1600 |
if (isset($analyzed_display_query[0]['queryflags']['select_from']) |
|
|
1601 |
&& isset($GLOBALS['sql_limit_to_append'])) { |
|
|
1602 |
$query_base = $analyzed_display_query[0]['section_before_limit'] . "\n" . $GLOBALS['sql_limit_to_append'] . $analyzed_display_query[0]['section_after_limit']; |
|
|
1603 |
// Need to reparse query |
|
|
1604 |
$parsed_sql = PMA_SQP_parse($query_base); |
|
|
1605 |
} |
|
|
1606 |
|
|
|
1607 |
if (!empty($GLOBALS['show_as_php'])) { |
|
|
1608 |
$query_base = '$sql = \'' . $query_base; |
|
|
1609 |
} elseif (!empty($GLOBALS['validatequery'])) { |
|
|
1610 |
$query_base = PMA_validateSQL($query_base); |
|
|
1611 |
} else { |
|
|
1612 |
if (isset($parsed_sql)) { |
|
|
1613 |
$query_base = PMA_formatSql($parsed_sql, $query_base); |
|
|
1614 |
} |
|
|
1615 |
} |
|
|
1616 |
|
|
|
1617 |
// Prepares links that may be displayed to edit/explain the query |
|
|
1618 |
// (don't go to default pages, we must go to the page |
|
|
1619 |
// where the query box is available) |
|
|
1620 |
// (also, I don't see why we should check the goto variable) |
|
|
1621 |
|
|
|
1622 |
//if (!isset($GLOBALS['goto'])) { |
|
|
1623 |
//$edit_target = (isset($GLOBALS['table'])) ? $cfg['DefaultTabTable'] : $cfg['DefaultTabDatabase']; |
|
|
1624 |
$edit_target = isset($GLOBALS['db']) ? (isset($GLOBALS['table']) ? 'tbl_properties.php' : 'db_details.php') : 'server_sql.php'; |
|
|
1625 |
//} elseif ($GLOBALS['goto'] != 'main.php') { |
|
|
1626 |
// $edit_target = $GLOBALS['goto']; |
|
|
1627 |
//} else { |
|
|
1628 |
// $edit_target = ''; |
|
|
1629 |
//} |
|
|
1630 |
|
|
|
1631 |
if (isset($cfg['SQLQuery']['Edit']) |
|
|
1632 |
&& ($cfg['SQLQuery']['Edit'] == true) |
|
|
1633 |
&& (!empty($edit_target))) { |
|
|
1634 |
|
|
|
1635 |
if ($cfg['EditInWindow'] == true) { |
|
|
1636 |
$onclick = 'window.parent.focus_querywindow(\'' . urlencode($local_query) . '\'); return false;'; |
|
|
1637 |
} else { |
|
|
1638 |
$onclick = ''; |
|
|
1639 |
} |
|
|
1640 |
|
|
|
1641 |
$edit_link = $edit_target |
|
|
1642 |
. $url_qpart |
|
|
1643 |
. '&sql_query=' . urlencode($local_query) |
|
|
1644 |
. '&show_query=1#querybox'; |
|
|
1645 |
$edit_link = ' [' . PMA_linkOrButton($edit_link, $GLOBALS['strEdit'], array('onclick' => $onclick)) . ']'; |
|
|
1646 |
} else { |
|
|
1647 |
$edit_link = ''; |
|
|
1648 |
} |
|
|
1649 |
|
|
|
1650 |
// Want to have the query explained (Mike Beck 2002-05-22) |
|
|
1651 |
// but only explain a SELECT (that has not been explained) |
|
|
1652 |
/* SQL-Parser-Analyzer */ |
|
|
1653 |
if (isset($cfg['SQLQuery']['Explain']) |
|
|
1654 |
&& $cfg['SQLQuery']['Explain'] == true) { |
|
|
1655 |
|
|
|
1656 |
// Detect if we are validating as well |
|
|
1657 |
// To preserve the validate uRL data |
|
|
1658 |
if (!empty($GLOBALS['validatequery'])) { |
|
|
1659 |
$explain_link_validate = '&validatequery=1'; |
|
|
1660 |
} else { |
|
|
1661 |
$explain_link_validate = ''; |
|
|
1662 |
} |
|
|
1663 |
|
|
|
1664 |
$explain_link = 'import.php' |
|
|
1665 |
. $url_qpart |
|
|
1666 |
. $explain_link_validate |
|
|
1667 |
. '&sql_query='; |
|
|
1668 |
|
|
|
1669 |
if (preg_match('@^SELECT[[:space:]]+@i', $local_query)) { |
|
|
1670 |
$explain_link .= urlencode('EXPLAIN ' . $local_query); |
|
|
1671 |
$message = $GLOBALS['strExplain']; |
|
|
1672 |
} elseif (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $local_query)) { |
|
|
1673 |
$explain_link .= urlencode(substr($local_query, 8)); |
|
|
1674 |
$message = $GLOBALS['strNoExplain']; |
|
|
1675 |
} else { |
|
|
1676 |
$explain_link = ''; |
|
|
1677 |
} |
|
|
1678 |
if (!empty($explain_link)) { |
|
|
1679 |
$explain_link = ' [' . PMA_linkOrButton($explain_link, $message) . ']'; |
|
|
1680 |
} |
|
|
1681 |
} else { |
|
|
1682 |
$explain_link = ''; |
|
|
1683 |
} //show explain |
|
|
1684 |
|
|
|
1685 |
// Also we would like to get the SQL formed in some nice |
|
|
1686 |
// php-code (Mike Beck 2002-05-22) |
|
|
1687 |
if (isset($cfg['SQLQuery']['ShowAsPHP']) |
|
|
1688 |
&& $cfg['SQLQuery']['ShowAsPHP'] == true) { |
|
|
1689 |
$php_link = 'import.php' |
|
|
1690 |
. $url_qpart |
|
|
1691 |
. '&show_query=1' |
|
|
1692 |
. '&sql_query=' . urlencode($local_query) |
|
|
1693 |
. '&show_as_php='; |
|
|
1694 |
|
|
|
1695 |
if (!empty($GLOBALS['show_as_php'])) { |
|
|
1696 |
$php_link .= '0'; |
|
|
1697 |
$message = $GLOBALS['strNoPhp']; |
|
|
1698 |
} else { |
|
|
1699 |
$php_link .= '1'; |
|
|
1700 |
$message = $GLOBALS['strPhp']; |
|
|
1701 |
} |
|
|
1702 |
$php_link = ' [' . PMA_linkOrButton($php_link, $message) . ']'; |
|
|
1703 |
|
|
|
1704 |
if (isset($GLOBALS['show_as_php']) && $GLOBALS['show_as_php'] == '1') { |
|
|
1705 |
$runquery_link |
|
|
1706 |
= 'import.php' |
|
|
1707 |
. $url_qpart |
|
|
1708 |
. '&show_query=1' |
|
|
1709 |
. '&sql_query=' . urlencode($local_query); |
|
|
1710 |
$php_link .= ' [' . PMA_linkOrButton($runquery_link, $GLOBALS['strRunQuery']) . ']'; |
|
|
1711 |
} |
|
|
1712 |
|
|
|
1713 |
} else { |
|
|
1714 |
$php_link = ''; |
|
|
1715 |
} //show as php |
|
|
1716 |
|
|
|
1717 |
// Refresh query |
|
|
1718 |
if (isset($cfg['SQLQuery']['Refresh']) |
|
|
1719 |
&& $cfg['SQLQuery']['Refresh'] |
|
|
1720 |
&& preg_match('@^(SELECT|SHOW)[[:space:]]+@i', $local_query)) { |
|
|
1721 |
$refresh_link = 'import.php' |
|
|
1722 |
. $url_qpart |
|
|
1723 |
. '&show_query=1' |
|
|
1724 |
. (isset($_GET['pos']) ? '&pos=' . $_GET['pos'] : '') |
|
|
1725 |
. '&sql_query=' . urlencode($local_query); |
|
|
1726 |
$refresh_link = ' [' . PMA_linkOrButton($refresh_link, $GLOBALS['strRefresh']) . ']'; |
|
|
1727 |
} else { |
|
|
1728 |
$refresh_link = ''; |
|
|
1729 |
} //show as php |
|
|
1730 |
|
|
|
1731 |
if (isset($cfg['SQLValidator']['use']) |
|
|
1732 |
&& $cfg['SQLValidator']['use'] == true |
|
|
1733 |
&& isset($cfg['SQLQuery']['Validate']) |
|
|
1734 |
&& $cfg['SQLQuery']['Validate'] == true) { |
|
|
1735 |
$validate_link = 'import.php' |
|
|
1736 |
. $url_qpart |
|
|
1737 |
. '&show_query=1' |
|
|
1738 |
. '&sql_query=' . urlencode($local_query) |
|
|
1739 |
. '&validatequery='; |
|
|
1740 |
if (!empty($GLOBALS['validatequery'])) { |
|
|
1741 |
$validate_link .= '0'; |
|
|
1742 |
$validate_message = $GLOBALS['strNoValidateSQL'] ; |
|
|
1743 |
} else { |
|
|
1744 |
$validate_link .= '1'; |
|
|
1745 |
$validate_message = $GLOBALS['strValidateSQL'] ; |
|
|
1746 |
} |
|
|
1747 |
$validate_link = ' [' . PMA_linkOrButton($validate_link, $validate_message) . ']'; |
|
|
1748 |
} else { |
|
|
1749 |
$validate_link = ''; |
|
|
1750 |
} //validator |
|
|
1751 |
unset($local_query); |
|
|
1752 |
|
|
|
1753 |
// Displays the message |
|
|
1754 |
echo '<fieldset class="">' . "\n"; |
|
|
1755 |
echo ' <legend>' . $GLOBALS['strSQLQuery'] . ':</legend>'; |
|
|
1756 |
echo ' ' . $query_base; |
|
|
1757 |
|
|
|
1758 |
//Clean up the end of the PHP |
|
|
1759 |
if (!empty($GLOBALS['show_as_php'])) { |
|
|
1760 |
echo '\';'; |
|
|
1761 |
} |
|
|
1762 |
echo '</fieldset>' . "\n"; |
|
|
1763 |
|
|
|
1764 |
if (!empty($edit_target)) { |
|
|
1765 |
echo '<fieldset class="tblFooters">'; |
|
|
1766 |
echo $edit_link . $explain_link . $php_link . $refresh_link . $validate_link; |
|
|
1767 |
echo '</fieldset>'; |
|
|
1768 |
} |
|
|
1769 |
} |
|
|
1770 |
?> |
|
|
1771 |
</div><br /> |
|
|
1772 |
<?php |
|
|
1773 |
} // end of the 'PMA_showMessage()' function |
|
|
1774 |
|
|
|
1775 |
|
|
|
1776 |
/** |
|
|
1777 |
* Formats $value to byte view |
|
|
1778 |
* |
|
|
1779 |
* @param double the value to format |
|
|
1780 |
* @param integer the sensitiveness |
|
|
1781 |
* @param integer the number of decimals to retain |
|
|
1782 |
* |
|
|
1783 |
* @return array the formatted value and its unit |
|
|
1784 |
* |
|
|
1785 |
* @access public |
|
|
1786 |
* |
|
|
1787 |
* @author staybyte |
|
|
1788 |
* @version 1.2 - 18 July 2002 |
|
|
1789 |
*/ |
|
|
1790 |
function PMA_formatByteDown($value, $limes = 6, $comma = 0) |
|
|
1791 |
{ |
|
|
1792 |
$dh = pow(10, $comma); |
|
|
1793 |
$li = pow(10, $limes); |
|
|
1794 |
$return_value = $value; |
|
|
1795 |
$unit = $GLOBALS['byteUnits'][0]; |
|
|
1796 |
|
|
|
1797 |
for ($d = 6, $ex = 15; $d >= 1; $d--, $ex-=3) { |
|
|
1798 |
if (isset($GLOBALS['byteUnits'][$d]) && $value >= $li * pow(10, $ex)) { |
|
|
1799 |
$value = round($value / (pow(1024, $d) / $dh)) /$dh; |
|
|
1800 |
$unit = $GLOBALS['byteUnits'][$d]; |
|
|
1801 |
break 1; |
|
|
1802 |
} // end if |
|
|
1803 |
} // end for |
|
|
1804 |
|
|
|
1805 |
if ($unit != $GLOBALS['byteUnits'][0]) { |
|
|
1806 |
$return_value = number_format($value, $comma, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']); |
|
|
1807 |
} else { |
|
|
1808 |
$return_value = number_format($value, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']); |
|
|
1809 |
} |
|
|
1810 |
|
|
|
1811 |
return array($return_value, $unit); |
|
|
1812 |
} // end of the 'PMA_formatByteDown' function |
|
|
1813 |
|
|
|
1814 |
/** |
|
|
1815 |
* Formats $value to the given length and appends SI prefixes |
|
|
1816 |
* $comma is not substracted from the length |
|
|
1817 |
* with a $length of 0 no truncation occurs, number is only formated |
|
|
1818 |
* to the current locale |
|
|
1819 |
* <code> |
|
|
1820 |
* echo PMA_formatNumber(123456789, 6); // 123,457 k |
|
|
1821 |
* echo PMA_formatNumber(-123456789, 4, 2); // -123.46 M |
|
|
1822 |
* echo PMA_formatNumber(-0.003, 6); // -3 m |
|
|
1823 |
* echo PMA_formatNumber(0.003, 3, 3); // 0.003 |
|
|
1824 |
* echo PMA_formatNumber(0.00003, 3, 2); // 0.03 m |
|
|
1825 |
* echo PMA_formatNumber(0, 6); // 0 |
|
|
1826 |
* </code> |
|
|
1827 |
* @param double $value the value to format |
|
|
1828 |
* @param integer $length the max length |
|
|
1829 |
* @param integer $comma the number of decimals to retain |
|
|
1830 |
* @param boolean $only_down do not reformat numbers below 1 |
|
|
1831 |
* |
|
|
1832 |
* @return string the formatted value and its unit |
|
|
1833 |
* |
|
|
1834 |
* @access public |
|
|
1835 |
* |
|
|
1836 |
* @author staybyte, sebastian mendel |
|
|
1837 |
* @version 1.1.0 - 2005-10-27 |
|
|
1838 |
*/ |
|
|
1839 |
function PMA_formatNumber($value, $length = 3, $comma = 0, $only_down = false) |
|
|
1840 |
{ |
|
|
1841 |
if ($length === 0) { |
|
|
1842 |
return number_format($value, |
|
|
1843 |
$comma, |
|
|
1844 |
$GLOBALS['number_decimal_separator'], |
|
|
1845 |
$GLOBALS['number_thousands_separator']); |
|
|
1846 |
} |
|
|
1847 |
|
|
|
1848 |
// this units needs no translation, ISO |
|
|
1849 |
$units = array( |
|
|
1850 |
-8 => 'y', |
|
|
1851 |
-7 => 'z', |
|
|
1852 |
-6 => 'a', |
|
|
1853 |
-5 => 'f', |
|
|
1854 |
-4 => 'p', |
|
|
1855 |
-3 => 'n', |
|
|
1856 |
-2 => 'µ', |
|
|
1857 |
-1 => 'm', |
|
|
1858 |
|
|
|
1859 |
1 => 'k', |
|
|
1860 |
2 => 'M', |
|
|
1861 |
3 => 'G', |
|
|
1862 |
4 => 'T', |
|
|
1863 |
5 => 'P', |
|
|
1864 |
6 => 'E', |
|
|
1865 |
7 => 'Z', |
|
|
1866 |
8 => 'Y' |
|
|
1867 |
); |
|
|
1868 |
|
|
|
1869 |
// we need at least 3 digits to be displayed |
|
|
1870 |
if (3 > $length + $comma) { |
|
|
1871 |
$length = 3 - $comma; |
|
|
1872 |
} |
|
|
1873 |
|
|
|
1874 |
// check for negativ value to retain sign |
|
|
1875 |
if ($value < 0) { |
|
|
1876 |
$sign = '-'; |
|
|
1877 |
$value = abs($value); |
|
|
1878 |
} else { |
|
|
1879 |
$sign = ''; |
|
|
1880 |
} |
|
|
1881 |
|
|
|
1882 |
$dh = pow(10, $comma); |
|
|
1883 |
$li = pow(10, $length); |
|
|
1884 |
$unit = $units[0]; |
|
|
1885 |
|
|
|
1886 |
if ($value >= 1) { |
|
|
1887 |
for ($d = 8; $d >= 0; $d--) { |
|
|
1888 |
if (isset($units[$d]) && $value >= $li * pow(1000, $d-1)) { |
|
|
1889 |
$value = round($value / (pow(1000, $d) / $dh)) /$dh; |
|
|
1890 |
$unit = $units[$d]; |
|
|
1891 |
break 1; |
|
|
1892 |
} // end if |
|
|
1893 |
} // end for |
|
|
1894 |
} elseif (!$only_down && (float) $value !== 0.0) { |
|
|
1895 |
for ($d = -8; $d <= 8; $d++) { |
|
|
1896 |
if (isset($units[$d]) && $value <= $li * pow(1000, $d-1)) { |
|
|
1897 |
$value = round($value / (pow(1000, $d) / $dh)) /$dh; |
|
|
1898 |
$unit = $units[$d]; |
|
|
1899 |
break 1; |
|
|
1900 |
} // end if |
|
|
1901 |
} // end for |
|
|
1902 |
} // end if ($value >= 1) elseif (!$only_down && (float) $value !== 0.0) |
|
|
1903 |
|
|
|
1904 |
$value = number_format($value, |
|
|
1905 |
$comma, |
|
|
1906 |
$GLOBALS['number_decimal_separator'], |
|
|
1907 |
$GLOBALS['number_thousands_separator']); |
|
|
1908 |
|
|
|
1909 |
return $sign . $value . ' ' . $unit; |
|
|
1910 |
} // end of the 'PMA_formatNumber' function |
|
|
1911 |
|
|
|
1912 |
/** |
|
|
1913 |
* Extracts ENUM / SET options from a type definition string |
|
|
1914 |
* |
|
|
1915 |
* @param string The column type definition |
|
|
1916 |
* |
|
|
1917 |
* @return array The options or |
|
|
1918 |
* boolean false in case of an error. |
|
|
1919 |
* |
|
|
1920 |
* @author rabus |
|
|
1921 |
*/ |
|
|
1922 |
function PMA_getEnumSetOptions($type_def) |
|
|
1923 |
{ |
|
|
1924 |
$open = strpos($type_def, '('); |
|
|
1925 |
$close = strrpos($type_def, ')'); |
|
|
1926 |
if (!$open || !$close) { |
|
|
1927 |
return false; |
|
|
1928 |
} |
|
|
1929 |
$options = substr($type_def, $open + 2, $close - $open - 3); |
|
|
1930 |
$options = explode('\',\'', $options); |
|
|
1931 |
return $options; |
|
|
1932 |
} // end of the 'PMA_getEnumSetOptions' function |
|
|
1933 |
|
|
|
1934 |
/** |
|
|
1935 |
* Writes localised date |
|
|
1936 |
* |
|
|
1937 |
* @param string the current timestamp |
|
|
1938 |
* |
|
|
1939 |
* @return string the formatted date |
|
|
1940 |
* |
|
|
1941 |
* @access public |
|
|
1942 |
*/ |
|
|
1943 |
function PMA_localisedDate($timestamp = -1, $format = '') |
|
|
1944 |
{ |
|
|
1945 |
global $datefmt, $month, $day_of_week; |
|
|
1946 |
|
|
|
1947 |
if ($format == '') { |
|
|
1948 |
$format = $datefmt; |
|
|
1949 |
} |
|
|
1950 |
|
|
|
1951 |
if ($timestamp == -1) { |
|
|
1952 |
$timestamp = time(); |
|
|
1953 |
} |
|
|
1954 |
|
|
|
1955 |
$date = preg_replace('@%[aA]@', $day_of_week[(int)strftime('%w', $timestamp)], $format); |
|
|
1956 |
$date = preg_replace('@%[bB]@', $month[(int)strftime('%m', $timestamp)-1], $date); |
|
|
1957 |
|
|
|
1958 |
return strftime($date, $timestamp); |
|
|
1959 |
} // end of the 'PMA_localisedDate()' function |
|
|
1960 |
|
|
|
1961 |
|
|
|
1962 |
/** |
|
|
1963 |
* returns a tab for tabbed navigation. |
|
|
1964 |
* If the variables $link and $args ar left empty, an inactive tab is created |
|
|
1965 |
* |
|
|
1966 |
* @uses array_merge() |
|
|
1967 |
* basename() |
|
|
1968 |
* $GLOBALS['strEmpty'] |
|
|
1969 |
* $GLOBALS['strDrop'] |
|
|
1970 |
* $GLOBALS['active_page'] |
|
|
1971 |
* $GLOBALS['PHP_SELF'] |
|
|
1972 |
* htmlentities() |
|
|
1973 |
* PMA_generate_common_url() |
|
|
1974 |
* $GLOBALS['url_query'] |
|
|
1975 |
* urlencode() |
|
|
1976 |
* $GLOBALS['cfg']['MainPageIconic'] |
|
|
1977 |
* $GLOBALS['pmaThemeImage'] |
|
|
1978 |
* sprintf() |
|
|
1979 |
* trigger_error() |
|
|
1980 |
* E_USER_NOTICE |
|
|
1981 |
* @param array $tab array with all options |
|
|
1982 |
* @return string html code for one tab, a link if valid otherwise a span |
|
|
1983 |
* @access public |
|
|
1984 |
*/ |
|
|
1985 |
function PMA_getTab($tab) |
|
|
1986 |
{ |
|
|
1987 |
// default values |
|
|
1988 |
$defaults = array( |
|
|
1989 |
'text' => '', |
|
|
1990 |
'class' => '', |
|
|
1991 |
'active' => false, |
|
|
1992 |
'link' => '', |
|
|
1993 |
'sep' => '?', |
|
|
1994 |
'attr' => '', |
|
|
1995 |
'args' => '', |
|
|
1996 |
); |
|
|
1997 |
|
|
|
1998 |
$tab = array_merge($defaults, $tab); |
|
|
1999 |
|
|
|
2000 |
// determine additionnal style-class |
|
|
2001 |
if (empty($tab['class'])) { |
|
|
2002 |
if ($tab['text'] == $GLOBALS['strEmpty'] |
|
|
2003 |
|| $tab['text'] == $GLOBALS['strDrop']) { |
|
|
2004 |
$tab['class'] = 'caution'; |
|
|
2005 |
} elseif (!empty($tab['active']) |
|
|
2006 |
|| (isset($GLOBALS['active_page']) |
|
|
2007 |
&& $GLOBALS['active_page'] == $tab['link']) |
|
|
2008 |
|| basename(PMA_getenv('PHP_SELF')) == $tab['link']) |
|
|
2009 |
{ |
|
|
2010 |
$tab['class'] = 'active'; |
|
|
2011 |
} |
|
|
2012 |
} |
|
|
2013 |
|
|
|
2014 |
// build the link |
|
|
2015 |
if (!empty($tab['link'])) { |
|
|
2016 |
$tab['link'] = htmlentities($tab['link']); |
|
|
2017 |
$tab['link'] = $tab['link'] . $tab['sep'] |
|
|
2018 |
.(empty($GLOBALS['url_query']) ? |
|
|
2019 |
PMA_generate_common_url() : $GLOBALS['url_query']); |
|
|
2020 |
if (!empty($tab['args'])) { |
|
|
2021 |
foreach ($tab['args'] as $param => $value) { |
|
|
2022 |
$tab['link'] .= '&' . urlencode($param) . '=' |
|
|
2023 |
. urlencode($value); |
|
|
2024 |
} |
|
|
2025 |
} |
|
|
2026 |
} |
|
|
2027 |
|
|
|
2028 |
// display icon, even if iconic is disabled but the link-text is missing |
|
|
2029 |
if (($GLOBALS['cfg']['MainPageIconic'] || empty($tab['text'])) |
|
|
2030 |
&& isset($tab['icon'])) { |
|
|
2031 |
$image = '<img class="icon" src="' . htmlentities($GLOBALS['pmaThemeImage']) |
|
|
2032 |
.'%1$s" width="16" height="16" alt="%2$s" />%2$s'; |
|
|
2033 |
$tab['text'] = sprintf($image, htmlentities($tab['icon']), $tab['text']); |
|
|
2034 |
} |
|
|
2035 |
// check to not display an empty link-text |
|
|
2036 |
elseif (empty($tab['text'])) { |
|
|
2037 |
$tab['text'] = '?'; |
|
|
2038 |
trigger_error('empty linktext in function ' . __FUNCTION__ . '()', |
|
|
2039 |
E_USER_NOTICE); |
|
|
2040 |
} |
|
|
2041 |
|
|
|
2042 |
if (!empty($tab['link'])) { |
|
|
2043 |
$out = '<a class="tab' . htmlentities($tab['class']) . '"' |
|
|
2044 |
.' href="' . $tab['link'] . '" ' . $tab['attr'] . '>' |
|
|
2045 |
. $tab['text'] . '</a>'; |
|
|
2046 |
} else { |
|
|
2047 |
$out = '<span class="tab' . htmlentities($tab['class']) . '">' |
|
|
2048 |
. $tab['text'] . '</span>'; |
|
|
2049 |
} |
|
|
2050 |
|
|
|
2051 |
return $out; |
|
|
2052 |
} // end of the 'PMA_getTab()' function |
|
|
2053 |
|
|
|
2054 |
/** |
|
|
2055 |
* returns html-code for a tab navigation |
|
|
2056 |
* |
|
|
2057 |
* @uses PMA_getTab() |
|
|
2058 |
* @uses htmlentities() |
|
|
2059 |
* @param array $tabs one element per tab |
|
|
2060 |
* @param string $tag_id id used for the html-tag |
|
|
2061 |
* @return string html-code for tab-navigation |
|
|
2062 |
*/ |
|
|
2063 |
function PMA_getTabs($tabs, $tag_id = 'topmenu') |
|
|
2064 |
{ |
|
|
2065 |
$tab_navigation = |
|
|
2066 |
'<div id="' . htmlentities($tag_id) . 'container">' . "\n" |
|
|
2067 |
.'<ul id="' . htmlentities($tag_id) . '">' . "\n"; |
|
|
2068 |
|
|
|
2069 |
foreach ($tabs as $tab) { |
|
|
2070 |
$tab_navigation .= '<li>' . PMA_getTab($tab) . '</li>' . "\n"; |
|
|
2071 |
} |
|
|
2072 |
|
|
|
2073 |
$tab_navigation .= |
|
|
2074 |
'</ul>' . "\n" |
|
|
2075 |
.'<div class="clearfloat"></div>' |
|
|
2076 |
.'</div>' . "\n"; |
|
|
2077 |
|
|
|
2078 |
return $tab_navigation; |
|
|
2079 |
} |
|
|
2080 |
|
|
|
2081 |
|
|
|
2082 |
/** |
|
|
2083 |
* Displays a link, or a button if the link's URL is too large, to |
|
|
2084 |
* accommodate some browsers' limitations |
|
|
2085 |
* |
|
|
2086 |
* @param string the URL |
|
|
2087 |
* @param string the link message |
|
|
2088 |
* @param mixed $tag_params string: js confirmation |
|
|
2089 |
* array: additional tag params (f.e. style="") |
|
|
2090 |
* @param boolean $new_form we set this to false when we are already in |
|
|
2091 |
* a form, to avoid generating nested forms |
|
|
2092 |
* |
|
|
2093 |
* @return string the results to be echoed or saved in an array |
|
|
2094 |
*/ |
|
|
2095 |
function PMA_linkOrButton($url, $message, $tag_params = array(), |
|
|
2096 |
$new_form = true, $strip_img = false, $target = '') |
|
|
2097 |
{ |
|
|
2098 |
if (! is_array($tag_params)) { |
|
|
2099 |
$tmp = $tag_params; |
|
|
2100 |
$tag_params = array(); |
|
|
2101 |
if (!empty($tmp)) { |
|
|
2102 |
$tag_params['onclick'] = 'return confirmLink(this, \'' . $tmp . '\')'; |
|
|
2103 |
} |
|
|
2104 |
unset($tmp); |
|
|
2105 |
} |
|
|
2106 |
if (! empty($target)) { |
|
|
2107 |
$tag_params['target'] = htmlentities($target); |
|
|
2108 |
} |
|
|
2109 |
|
|
|
2110 |
$tag_params_strings = array(); |
|
|
2111 |
foreach ($tag_params as $par_name => $par_value) { |
|
|
2112 |
// htmlentities() only on non javascript |
|
|
2113 |
$par_value = substr($par_name, 0, 2) == 'on' |
|
|
2114 |
? $par_value |
|
|
2115 |
: htmlentities($par_value); |
|
|
2116 |
$tag_params_strings[] = $par_name . '="' . $par_value . '"'; |
|
|
2117 |
} |
|
|
2118 |
|
|
|
2119 |
// previously the limit was set to 2047, it seems 1000 is better |
|
|
2120 |
if (strlen($url) <= 1000) { |
|
|
2121 |
// no whitespace within an <a> else Safari will make it part of the link |
|
|
2122 |
$ret = "\n" . '<a href="' . $url . '" ' |
|
|
2123 |
. implode(' ', $tag_params_strings) . '>' |
|
|
2124 |
. $message . '</a>' . "\n"; |
|
|
2125 |
} else { |
|
|
2126 |
// no spaces (linebreaks) at all |
|
|
2127 |
// or after the hidden fields |
|
|
2128 |
// IE will display them all |
|
|
2129 |
|
|
|
2130 |
// add class=link to submit button |
|
|
2131 |
if (empty($tag_params['class'])) { |
|
|
2132 |
$tag_params['class'] = 'link'; |
|
|
2133 |
} |
|
|
2134 |
$url = str_replace('&', '&', $url); |
|
|
2135 |
$url_parts = parse_url($url); |
|
|
2136 |
$query_parts = explode('&', $url_parts['query']); |
|
|
2137 |
if ($new_form) { |
|
|
2138 |
$ret = '<form action="' . $url_parts['path'] . '" class="link"' |
|
|
2139 |
. ' method="post"' . $target . ' style="display: inline;">'; |
|
|
2140 |
$subname_open = ''; |
|
|
2141 |
$subname_close = ''; |
|
|
2142 |
$submit_name = ''; |
|
|
2143 |
} else { |
|
|
2144 |
$query_parts[] = 'redirect=' . $url_parts['path']; |
|
|
2145 |
if (empty($GLOBALS['subform_counter'])) { |
|
|
2146 |
$GLOBALS['subform_counter'] = 0; |
|
|
2147 |
} |
|
|
2148 |
$GLOBALS['subform_counter']++; |
|
|
2149 |
$ret = ''; |
|
|
2150 |
$subname_open = 'subform[' . $GLOBALS['subform_counter'] . ']['; |
|
|
2151 |
$subname_close = ']'; |
|
|
2152 |
$submit_name = ' name="usesubform[' . $GLOBALS['subform_counter'] . ']"'; |
|
|
2153 |
} |
|
|
2154 |
foreach ($query_parts AS $query_pair) { |
|
|
2155 |
list($eachvar, $eachval) = explode('=', $query_pair); |
|
|
2156 |
$ret .= '<input type="hidden" name="' . $subname_open . $eachvar |
|
|
2157 |
. $subname_close . '" value="' |
|
|
2158 |
. htmlspecialchars(urldecode($eachval)) . '" />'; |
|
|
2159 |
} // end while |
|
|
2160 |
|
|
|
2161 |
if (stristr($message, '<img')) { |
|
|
2162 |
if ($strip_img) { |
|
|
2163 |
$message = trim(strip_tags($message)); |
|
|
2164 |
$ret .= '<input type="submit"' . $submit_name . ' ' |
|
|
2165 |
. implode(' ', $tag_params_strings) |
|
|
2166 |
. ' value="' . htmlspecialchars($message) . '" />'; |
|
|
2167 |
} else { |
|
|
2168 |
$ret .= '<input type="image"' . $submit_name . ' ' |
|
|
2169 |
. implode(' ', $tag_params_strings) |
|
|
2170 |
. ' src="' . preg_replace( |
|
|
2171 |
'/^.*\ssrc="([^"]*)".*$/si', '\1', $message) . '"' |
|
|
2172 |
. ' value="' . htmlspecialchars( |
|
|
2173 |
preg_replace('/^.*\salt="([^"]*)".*$/si', '\1', |
|
|
2174 |
$message)) |
|
|
2175 |
. '" />'; |
|
|
2176 |
} |
|
|
2177 |
} else { |
|
|
2178 |
$message = trim(strip_tags($message)); |
|
|
2179 |
$ret .= '<input type="submit"' . $submit_name . ' ' |
|
|
2180 |
. implode(' ', $tag_params_strings) |
|
|
2181 |
. ' value="' . htmlspecialchars($message) . '" />'; |
|
|
2182 |
} |
|
|
2183 |
if ($new_form) { |
|
|
2184 |
$ret .= '</form>'; |
|
|
2185 |
} |
|
|
2186 |
} // end if... else... |
|
|
2187 |
|
|
|
2188 |
return $ret; |
|
|
2189 |
} // end of the 'PMA_linkOrButton()' function |
|
|
2190 |
|
|
|
2191 |
|
|
|
2192 |
/** |
|
|
2193 |
* Returns a given timespan value in a readable format. |
|
|
2194 |
* |
|
|
2195 |
* @param int the timespan |
|
|
2196 |
* |
|
|
2197 |
* @return string the formatted value |
|
|
2198 |
*/ |
|
|
2199 |
function PMA_timespanFormat($seconds) |
|
|
2200 |
{ |
|
|
2201 |
$return_string = ''; |
|
|
2202 |
$days = floor($seconds / 86400); |
|
|
2203 |
if ($days > 0) { |
|
|
2204 |
$seconds -= $days * 86400; |
|
|
2205 |
} |
|
|
2206 |
$hours = floor($seconds / 3600); |
|
|
2207 |
if ($days > 0 || $hours > 0) { |
|
|
2208 |
$seconds -= $hours * 3600; |
|
|
2209 |
} |
|
|
2210 |
$minutes = floor($seconds / 60); |
|
|
2211 |
if ($days > 0 || $hours > 0 || $minutes > 0) { |
|
|
2212 |
$seconds -= $minutes * 60; |
|
|
2213 |
} |
|
|
2214 |
return sprintf($GLOBALS['timespanfmt'], (string)$days, (string)$hours, (string)$minutes, (string)$seconds); |
|
|
2215 |
} |
|
|
2216 |
|
|
|
2217 |
/** |
|
|
2218 |
* Takes a string and outputs each character on a line for itself. Used |
|
|
2219 |
* mainly for horizontalflipped display mode. |
|
|
2220 |
* Takes care of special html-characters. |
|
|
2221 |
* Fulfills todo-item |
|
|
2222 |
* http://sf.net/tracker/?func=detail&aid=544361&group_id=23067&atid=377411 |
|
|
2223 |
* |
|
|
2224 |
* @param string The string |
|
|
2225 |
* @param string The Separator (defaults to "<br />\n") |
|
|
2226 |
* |
|
|
2227 |
* @access public |
|
|
2228 |
* @author Garvin Hicking <me@supergarv.de> |
|
|
2229 |
* @return string The flipped string |
|
|
2230 |
*/ |
|
|
2231 |
function PMA_flipstring($string, $Separator = "<br />\n") |
|
|
2232 |
{ |
|
|
2233 |
$format_string = ''; |
|
|
2234 |
$charbuff = false; |
|
|
2235 |
|
|
|
2236 |
for ($i = 0; $i < strlen($string); $i++) { |
|
|
2237 |
$char = $string{$i}; |
|
|
2238 |
$append = false; |
|
|
2239 |
|
|
|
2240 |
if ($char == '&') { |
|
|
2241 |
$format_string .= $charbuff; |
|
|
2242 |
$charbuff = $char; |
|
|
2243 |
$append = true; |
|
|
2244 |
} elseif (!empty($charbuff)) { |
|
|
2245 |
$charbuff .= $char; |
|
|
2246 |
} elseif ($char == ';' && !empty($charbuff)) { |
|
|
2247 |
$format_string .= $charbuff; |
|
|
2248 |
$charbuff = false; |
|
|
2249 |
$append = true; |
|
|
2250 |
} else { |
|
|
2251 |
$format_string .= $char; |
|
|
2252 |
$append = true; |
|
|
2253 |
} |
|
|
2254 |
|
|
|
2255 |
if ($append && ($i != strlen($string))) { |
|
|
2256 |
$format_string .= $Separator; |
|
|
2257 |
} |
|
|
2258 |
} |
|
|
2259 |
|
|
|
2260 |
return $format_string; |
|
|
2261 |
} |
|
|
2262 |
|
|
|
2263 |
|
|
|
2264 |
/** |
|
|
2265 |
* Function added to avoid path disclosures. |
|
|
2266 |
* Called by each script that needs parameters, it displays |
|
|
2267 |
* an error message and, by default, stops the execution. |
|
|
2268 |
* |
|
|
2269 |
* Not sure we could use a strMissingParameter message here, |
|
|
2270 |
* would have to check if the error message file is always available |
|
|
2271 |
* |
|
|
2272 |
* @param array The names of the parameters needed by the calling |
|
|
2273 |
* script. |
|
|
2274 |
* @param boolean Stop the execution? |
|
|
2275 |
* (Set this manually to false in the calling script |
|
|
2276 |
* until you know all needed parameters to check). |
|
|
2277 |
* @param boolean Whether to include this list in checking for special params. |
|
|
2278 |
* @global string path to current script |
|
|
2279 |
* @global boolean flag whether any special variable was required |
|
|
2280 |
* |
|
|
2281 |
* @access public |
|
|
2282 |
* @author Marc Delisle (lem9@users.sourceforge.net) |
|
|
2283 |
*/ |
|
|
2284 |
function PMA_checkParameters($params, $die = true, $request = true) |
|
|
2285 |
{ |
|
|
2286 |
global $PHP_SELF, $checked_special; |
|
|
2287 |
|
|
|
2288 |
if (!isset($checked_special)) { |
|
|
2289 |
$checked_special = false; |
|
|
2290 |
} |
|
|
2291 |
|
|
|
2292 |
$reported_script_name = basename($PHP_SELF); |
|
|
2293 |
$found_error = false; |
|
|
2294 |
$error_message = ''; |
|
|
2295 |
|
|
|
2296 |
foreach ($params AS $param) { |
|
|
2297 |
if ($request && $param != 'db' && $param != 'table') { |
|
|
2298 |
$checked_special = true; |
|
|
2299 |
} |
|
|
2300 |
|
|
|
2301 |
if (!isset($GLOBALS[$param])) { |
|
|
2302 |
$error_message .= $reported_script_name . ': Missing parameter: ' . $param . ' <a href="./Documentation.html#faqmissingparameters" target="documentation"> (FAQ 2.8)</a><br />'; |
|
|
2303 |
$found_error = true; |
|
|
2304 |
} |
|
|
2305 |
} |
|
|
2306 |
if ($found_error) { |
|
|
2307 |
require_once './libraries/header_meta_style.inc.php'; |
|
|
2308 |
echo '</head><body><p>' . $error_message . '</p></body></html>'; |
|
|
2309 |
if ($die) { |
|
|
2310 |
exit(); |
|
|
2311 |
} |
|
|
2312 |
} |
|
|
2313 |
} // end function |
|
|
2314 |
|
|
|
2315 |
/** |
|
|
2316 |
* Function to generate unique condition for specified row. |
|
|
2317 |
* |
|
|
2318 |
* @param resource handle for current query |
|
|
2319 |
* @param integer number of fields |
|
|
2320 |
* @param array meta information about fields |
|
|
2321 |
* @param array current row |
|
|
2322 |
* |
|
|
2323 |
* @access public |
|
|
2324 |
* @author Michal Cihar (michal@cihar.com) |
|
|
2325 |
* @return string calculated condition |
|
|
2326 |
*/ |
|
|
2327 |
function PMA_getUvaCondition($handle, $fields_cnt, $fields_meta, $row) |
|
|
2328 |
{ |
|
|
2329 |
$primary_key = ''; |
|
|
2330 |
$unique_key = ''; |
|
|
2331 |
$uva_nonprimary_condition = ''; |
|
|
2332 |
|
|
|
2333 |
for ($i = 0; $i < $fields_cnt; ++$i) { |
|
|
2334 |
$field_flags = PMA_DBI_field_flags($handle, $i); |
|
|
2335 |
$meta = $fields_meta[$i]; |
|
|
2336 |
// do not use an alias in a condition |
|
|
2337 |
$column_for_condition = $meta->name; |
|
|
2338 |
if (isset($analyzed_sql[0]['select_expr']) && is_array($analyzed_sql[0]['select_expr'])) { |
|
|
2339 |
foreach ($analyzed_sql[0]['select_expr'] AS $select_expr_position => $select_expr) { |
|
|
2340 |
$alias = $analyzed_sql[0]['select_expr'][$select_expr_position]['alias']; |
|
|
2341 |
if (strlen($alias)) { |
|
|
2342 |
$true_column = $analyzed_sql[0]['select_expr'][$select_expr_position]['column']; |
|
|
2343 |
if ($alias == $meta->name) { |
|
|
2344 |
$column_for_condition = $true_column; |
|
|
2345 |
} // end if |
|
|
2346 |
} // end if |
|
|
2347 |
} // end while |
|
|
2348 |
} |
|
|
2349 |
|
|
|
2350 |
// to fix the bug where float fields (primary or not) |
|
|
2351 |
// can't be matched because of the imprecision of |
|
|
2352 |
// floating comparison, use CONCAT |
|
|
2353 |
// (also, the syntax "CONCAT(field) IS NULL" |
|
|
2354 |
// that we need on the next "if" will work) |
|
|
2355 |
if ($meta->type == 'real') { |
|
|
2356 |
$condition = ' CONCAT(' . PMA_backquote($column_for_condition) . ') '; |
|
|
2357 |
} else { |
|
|
2358 |
// string and blob fields have to be converted using |
|
|
2359 |
// the system character set (always utf8) since |
|
|
2360 |
// mysql4.1 can use different charset for fields. |
|
|
2361 |
if (PMA_MYSQL_INT_VERSION >= 40100 && ($meta->type == 'string' || $meta->type == 'blob')) { |
|
|
2362 |
$condition = ' CONVERT(' . PMA_backquote($column_for_condition) . ' USING utf8) '; |
|
|
2363 |
} else { |
|
|
2364 |
$condition = ' ' . PMA_backquote($column_for_condition) . ' '; |
|
|
2365 |
} |
|
|
2366 |
} // end if... else... |
|
|
2367 |
|
|
|
2368 |
if (!isset($row[$i]) || is_null($row[$i])) { |
|
|
2369 |
$condition .= 'IS NULL AND'; |
|
|
2370 |
} else { |
|
|
2371 |
// timestamp is numeric on some MySQL 4.1 |
|
|
2372 |
if ($meta->numeric && $meta->type != 'timestamp') { |
|
|
2373 |
$condition .= '= ' . $row[$i] . ' AND'; |
|
|
2374 |
} elseif ($meta->type == 'blob' |
|
|
2375 |
// hexify only if this is a true not empty BLOB |
|
|
2376 |
&& stristr($field_flags, 'BINARY') |
|
|
2377 |
&& !empty($row[$i])) { |
|
|
2378 |
// use a CAST if possible, to avoid problems |
|
|
2379 |
// if the field contains wildcard characters % or _ |
|
|
2380 |
if (PMA_MYSQL_INT_VERSION < 40002) { |
|
|
2381 |
$condition .= 'LIKE 0x' . bin2hex($row[$i]). ' AND'; |
|
|
2382 |
} else { |
|
|
2383 |
$condition .= '= CAST(0x' . bin2hex($row[$i]). ' AS BINARY) AND'; |
|
|
2384 |
} |
|
|
2385 |
} else { |
|
|
2386 |
$condition .= '= \'' . PMA_sqlAddslashes($row[$i], false, true) . '\' AND'; |
|
|
2387 |
} |
|
|
2388 |
} |
|
|
2389 |
if ($meta->primary_key > 0) { |
|
|
2390 |
$primary_key .= $condition; |
|
|
2391 |
} elseif ($meta->unique_key > 0) { |
|
|
2392 |
$unique_key .= $condition; |
|
|
2393 |
} |
|
|
2394 |
$uva_nonprimary_condition .= $condition; |
|
|
2395 |
} // end for |
|
|
2396 |
|
|
|
2397 |
// Correction uva 19991216: prefer primary or unique keys |
|
|
2398 |
// for condition, but use conjunction of all values if no |
|
|
2399 |
// primary key |
|
|
2400 |
if ($primary_key) { |
|
|
2401 |
$uva_condition = $primary_key; |
|
|
2402 |
} elseif ($unique_key) { |
|
|
2403 |
$uva_condition = $unique_key; |
|
|
2404 |
} else { |
|
|
2405 |
$uva_condition = $uva_nonprimary_condition; |
|
|
2406 |
} |
|
|
2407 |
|
|
|
2408 |
return preg_replace('|\s?AND$|', '', $uva_condition); |
|
|
2409 |
} // end function |
|
|
2410 |
|
|
|
2411 |
/** |
|
|
2412 |
* Function to generate unique condition for specified row. |
|
|
2413 |
* |
|
|
2414 |
* @param string name of button element |
|
|
2415 |
* @param string class of button element |
|
|
2416 |
* @param string name of image element |
|
|
2417 |
* @param string text to display |
|
|
2418 |
* @param string image to display |
|
|
2419 |
* |
|
|
2420 |
* @access public |
|
|
2421 |
* @author Michal Cihar (michal@cihar.com) |
|
|
2422 |
*/ |
|
|
2423 |
function PMA_buttonOrImage($button_name, $button_class, $image_name, $text, |
|
|
2424 |
$image) |
|
|
2425 |
{ |
|
|
2426 |
global $pmaThemeImage, $propicon; |
|
|
2427 |
|
|
|
2428 |
/* Opera has trouble with <input type="image"> */ |
|
|
2429 |
/* IE has trouble with <button> */ |
|
|
2430 |
if (PMA_USR_BROWSER_AGENT != 'IE') { |
|
|
2431 |
echo '<button class="' . $button_class . '" type="submit"' |
|
|
2432 |
.' name="' . $button_name . '" value="' . $text . '"' |
|
|
2433 |
.' title="' . $text . '">' . "\n" |
|
|
2434 |
.'<img class="icon" src="' . $pmaThemeImage . $image . '"' |
|
|
2435 |
.' title="' . $text . '" alt="' . $text . '" width="16"' |
|
|
2436 |
.' height="16" />' |
|
|
2437 |
.($propicon == 'both' ? ' ' . $text : '') . "\n" |
|
|
2438 |
.'</button>' . "\n"; |
|
|
2439 |
} else { |
|
|
2440 |
echo '<input type="image" name="' . $image_name . '" value="' |
|
|
2441 |
. $text . '" title="' . $text . '" src="' . $pmaThemeImage |
|
|
2442 |
. $image . '" />' |
|
|
2443 |
. ($propicon == 'both' ? ' ' . $text : '') . "\n"; |
|
|
2444 |
} |
|
|
2445 |
} // end function |
|
|
2446 |
|
|
|
2447 |
/** |
|
|
2448 |
* Generate a pagination selector for browsing resultsets |
|
|
2449 |
* |
|
|
2450 |
* @param string URL for the JavaScript |
|
|
2451 |
* @param string Number of rows in the pagination set |
|
|
2452 |
* @param string current page number |
|
|
2453 |
* @param string number of total pages |
|
|
2454 |
* @param string If the number of pages is lower than this |
|
|
2455 |
* variable, no pages will be ommitted in |
|
|
2456 |
* pagination |
|
|
2457 |
* @param string How many rows at the beginning should always |
|
|
2458 |
* be shown? |
|
|
2459 |
* @param string How many rows at the end should always |
|
|
2460 |
* be shown? |
|
|
2461 |
* @param string Percentage of calculation page offsets to |
|
|
2462 |
* hop to a next page |
|
|
2463 |
* @param string Near the current page, how many pages should |
|
|
2464 |
* be considered "nearby" and displayed as |
|
|
2465 |
* well? |
|
|
2466 |
* |
|
|
2467 |
* @access public |
|
|
2468 |
* @author Garvin Hicking (pma@supergarv.de) |
|
|
2469 |
*/ |
|
|
2470 |
function PMA_pageselector($url, $rows, $pageNow = 1, $nbTotalPage = 1, |
|
|
2471 |
$showAll = 200, $sliceStart = 5, $sliceEnd = 5, $percent = 20, |
|
|
2472 |
$range = 10) |
|
|
2473 |
{ |
|
|
2474 |
$gotopage = $GLOBALS['strPageNumber'] |
|
|
2475 |
. ' <select name="goToPage" onchange="goToUrl(this, \'' |
|
|
2476 |
. $url . '\');">' . "\n"; |
|
|
2477 |
if ($nbTotalPage < $showAll) { |
|
|
2478 |
$pages = range(1, $nbTotalPage); |
|
|
2479 |
} else { |
|
|
2480 |
$pages = array(); |
|
|
2481 |
|
|
|
2482 |
// Always show first X pages |
|
|
2483 |
for ($i = 1; $i <= $sliceStart; $i++) { |
|
|
2484 |
$pages[] = $i; |
|
|
2485 |
} |
|
|
2486 |
|
|
|
2487 |
// Always show last X pages |
|
|
2488 |
for ($i = $nbTotalPage - $sliceEnd; $i <= $nbTotalPage; $i++) { |
|
|
2489 |
$pages[] = $i; |
|
|
2490 |
} |
|
|
2491 |
|
|
|
2492 |
// garvin: Based on the number of results we add the specified |
|
|
2493 |
// $percent percentate to each page number, |
|
|
2494 |
// so that we have a representing page number every now and then to |
|
|
2495 |
// immideately jump to specific pages. |
|
|
2496 |
// As soon as we get near our currently chosen page ($pageNow - |
|
|
2497 |
// $range), every page number will be |
|
|
2498 |
// shown. |
|
|
2499 |
$i = $sliceStart; |
|
|
2500 |
$x = $nbTotalPage - $sliceEnd; |
|
|
2501 |
$met_boundary = false; |
|
|
2502 |
while ($i <= $x) { |
|
|
2503 |
if ($i >= ($pageNow - $range) && $i <= ($pageNow + $range)) { |
|
|
2504 |
// If our pageselector comes near the current page, we use 1 |
|
|
2505 |
// counter increments |
|
|
2506 |
$i++; |
|
|
2507 |
$met_boundary = true; |
|
|
2508 |
} else { |
|
|
2509 |
// We add the percentate increment to our current page to |
|
|
2510 |
// hop to the next one in range |
|
|
2511 |
$i = $i + floor($nbTotalPage / $percent); |
|
|
2512 |
|
|
|
2513 |
// Make sure that we do not cross our boundaries. |
|
|
2514 |
if ($i > ($pageNow - $range) && !$met_boundary) { |
|
|
2515 |
$i = $pageNow - $range; |
|
|
2516 |
} |
|
|
2517 |
} |
|
|
2518 |
|
|
|
2519 |
if ($i > 0 && $i <= $x) { |
|
|
2520 |
$pages[] = $i; |
|
|
2521 |
} |
|
|
2522 |
} |
|
|
2523 |
|
|
|
2524 |
// Since because of ellipsing of the current page some numbers may be double, |
|
|
2525 |
// we unify our array: |
|
|
2526 |
sort($pages); |
|
|
2527 |
$pages = array_unique($pages); |
|
|
2528 |
} |
|
|
2529 |
|
|
|
2530 |
foreach ($pages AS $i) { |
|
|
2531 |
if ($i == $pageNow) { |
|
|
2532 |
$selected = 'selected="selected" style="font-weight: bold"'; |
|
|
2533 |
} else { |
|
|
2534 |
$selected = ''; |
|
|
2535 |
} |
|
|
2536 |
$gotopage .= ' <option ' . $selected . ' value="' . (($i - 1) * $rows) . '">' . $i . '</option>' . "\n"; |
|
|
2537 |
} |
|
|
2538 |
|
|
|
2539 |
$gotopage .= ' </select>'; |
|
|
2540 |
|
|
|
2541 |
return $gotopage; |
|
|
2542 |
} // end function |
|
|
2543 |
|
|
|
2544 |
/** |
|
|
2545 |
* @TODO add documentation |
|
|
2546 |
*/ |
|
|
2547 |
function PMA_generateFieldSpec($name, $type, $length, $attribute, |
|
|
2548 |
$collation, $null, $default, $default_current_timestamp, $extra, |
|
|
2549 |
$comment='', &$field_primary, $index, $default_orig = false) |
|
|
2550 |
{ |
|
|
2551 |
|
|
|
2552 |
// $default_current_timestamp has priority over $default |
|
|
2553 |
// TODO: on the interface, some js to clear the default value |
|
|
2554 |
// when the default current_timestamp is checked |
|
|
2555 |
|
|
|
2556 |
$query = PMA_backquote($name) . ' ' . $type; |
|
|
2557 |
|
|
|
2558 |
if ($length != '' |
|
|
2559 |
&& !preg_match('@^(DATE|DATETIME|TIME|TINYBLOB|TINYTEXT|BLOB|TEXT|MEDIUMBLOB|MEDIUMTEXT|LONGBLOB|LONGTEXT)$@i', $type)) { |
|
|
2560 |
$query .= '(' . $length . ')'; |
|
|
2561 |
} |
|
|
2562 |
|
|
|
2563 |
if ($attribute != '') { |
|
|
2564 |
$query .= ' ' . $attribute; |
|
|
2565 |
} |
|
|
2566 |
|
|
|
2567 |
if (PMA_MYSQL_INT_VERSION >= 40100 && !empty($collation) |
|
|
2568 |
&& $collation != 'NULL' |
|
|
2569 |
&& preg_match('@^(TINYTEXT|TEXT|MEDIUMTEXT|LONGTEXT|VARCHAR|CHAR|ENUM|SET)$@i', $type)) { |
|
|
2570 |
$query .= PMA_generateCharsetQueryPart($collation); |
|
|
2571 |
} |
|
|
2572 |
|
|
|
2573 |
if (!($null === false)) { |
|
|
2574 |
if (!empty($null)) { |
|
|
2575 |
$query .= ' NOT NULL'; |
|
|
2576 |
} else { |
|
|
2577 |
$query .= ' NULL'; |
|
|
2578 |
} |
|
|
2579 |
} |
|
|
2580 |
|
|
|
2581 |
if ($default_current_timestamp && strpos(' ' . strtoupper($type), 'TIMESTAMP') == 1) { |
|
|
2582 |
$query .= ' DEFAULT CURRENT_TIMESTAMP'; |
|
|
2583 |
// 0 is empty in PHP |
|
|
2584 |
// auto_increment field cannot have a default value |
|
|
2585 |
} elseif ($extra !== 'AUTO_INCREMENT' && (!empty($default) || $default == '0' || $default != $default_orig)) { |
|
|
2586 |
if (strtoupper($default) == 'NULL') { |
|
|
2587 |
$query .= ' DEFAULT NULL'; |
|
|
2588 |
} else { |
|
|
2589 |
if (!empty($default) || $default == '0') { |
|
|
2590 |
$query .= ' DEFAULT \'' . PMA_sqlAddslashes($default) . '\''; |
|
|
2591 |
} |
|
|
2592 |
} |
|
|
2593 |
} |
|
|
2594 |
|
|
|
2595 |
if (!empty($extra)) { |
|
|
2596 |
$query .= ' ' . $extra; |
|
|
2597 |
// An auto_increment field must be use as a primary key |
|
|
2598 |
if ($extra == 'AUTO_INCREMENT' && isset($field_primary)) { |
|
|
2599 |
$primary_cnt = count($field_primary); |
|
|
2600 |
for ($j = 0; $j < $primary_cnt && $field_primary[$j] != $index; $j++) { |
|
|
2601 |
// void |
|
|
2602 |
} // end for |
|
|
2603 |
if (isset($field_primary[$j]) && $field_primary[$j] == $index) { |
|
|
2604 |
$query .= ' PRIMARY KEY'; |
|
|
2605 |
unset($field_primary[$j]); |
|
|
2606 |
} // end if |
|
|
2607 |
} // end if (auto_increment) |
|
|
2608 |
} |
|
|
2609 |
if (PMA_MYSQL_INT_VERSION >= 40100 && !empty($comment)) { |
|
|
2610 |
$query .= " COMMENT '" . PMA_sqlAddslashes($comment) . "'"; |
|
|
2611 |
} |
|
|
2612 |
return $query; |
|
|
2613 |
} // end function |
|
|
2614 |
|
|
|
2615 |
/** |
|
|
2616 |
* @TODO add documentation |
|
|
2617 |
*/ |
|
|
2618 |
function PMA_generateAlterTable($oldcol, $newcol, $type, $length, |
|
|
2619 |
$attribute, $collation, $null, $default, $default_current_timestamp, |
|
|
2620 |
$extra, $comment='', $default_orig) |
|
|
2621 |
{ |
|
|
2622 |
$empty_a = array(); |
|
|
2623 |
return PMA_backquote($oldcol) . ' ' |
|
|
2624 |
. PMA_generateFieldSpec($newcol, $type, $length, $attribute, |
|
|
2625 |
$collation, $null, $default, $default_current_timestamp, $extra, |
|
|
2626 |
$comment, $empty_a, -1, $default_orig); |
|
|
2627 |
} // end function |
|
|
2628 |
|
|
|
2629 |
/** |
|
|
2630 |
* @TODO add documentation |
|
|
2631 |
*/ |
|
|
2632 |
function PMA_userDir($dir) |
|
|
2633 |
{ |
|
|
2634 |
global $cfg; |
|
|
2635 |
|
|
|
2636 |
if (substr($dir, -1) != '/') { |
|
|
2637 |
$dir .= '/'; |
|
|
2638 |
} |
|
|
2639 |
|
|
|
2640 |
return str_replace('%u', $cfg['Server']['user'], $dir); |
|
|
2641 |
} |
|
|
2642 |
|
|
|
2643 |
/** |
|
|
2644 |
* returns html code for db link to default db page |
|
|
2645 |
* |
|
|
2646 |
* @uses $GLOBALS['cfg']['DefaultTabDatabase'] |
|
|
2647 |
* @uses $GLOBALS['db'] |
|
|
2648 |
* @uses $GLOBALS['strJumpToDB'] |
|
|
2649 |
* @uses PMA_generate_common_url() |
|
|
2650 |
* @param string $database |
|
|
2651 |
* @return string html link to default db page |
|
|
2652 |
*/ |
|
|
2653 |
function PMA_getDbLink($database = null) |
|
|
2654 |
{ |
|
|
2655 |
if (!strlen($database)) { |
|
|
2656 |
if (!strlen($GLOBALS['db'])) { |
|
|
2657 |
return ''; |
|
|
2658 |
} |
|
|
2659 |
$database = $GLOBALS['db']; |
|
|
2660 |
} |
|
|
2661 |
|
|
|
2662 |
return '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?' . PMA_generate_common_url($database) . '"' |
|
|
2663 |
.' title="' . sprintf($GLOBALS['strJumpToDB'], htmlspecialchars($database)) . '">' |
|
|
2664 |
.htmlspecialchars($database) . '</a>'; |
|
|
2665 |
} |
|
|
2666 |
|
|
|
2667 |
/** |
|
|
2668 |
* removes cookie |
|
|
2669 |
* |
|
|
2670 |
* @uses $GLOBALS['cookie_path'] |
|
|
2671 |
* @uses $GLOBALS['is_https'] |
|
|
2672 |
* @uses setcookie() |
|
|
2673 |
* @uses time() |
|
|
2674 |
* @param string $cookie name of cookie to remove |
|
|
2675 |
* @return boolean result of setcookie() |
|
|
2676 |
*/ |
|
|
2677 |
function PMA_removeCookie($cookie) |
|
|
2678 |
{ |
|
|
2679 |
return setcookie($cookie, '', time() - 3600, |
|
|
2680 |
$GLOBALS['cookie_path'], '', $GLOBALS['is_https']); |
|
|
2681 |
} |
|
|
2682 |
|
|
|
2683 |
/** |
|
|
2684 |
* sets cookie if value is different from current cokkie value, |
|
|
2685 |
* or removes if value is equal to default |
|
|
2686 |
* |
|
|
2687 |
* @uses $GLOBALS['cookie_path'] |
|
|
2688 |
* @uses $GLOBALS['is_https'] |
|
|
2689 |
* @uses $_COOKIE |
|
|
2690 |
* @uses PMA_removeCookie() |
|
|
2691 |
* @uses setcookie() |
|
|
2692 |
* @uses time() |
|
|
2693 |
* @param string $cookie name of cookie to remove |
|
|
2694 |
* @param mixed $value new cookie value |
|
|
2695 |
* @param string $default default value |
|
|
2696 |
* @return boolean result of setcookie() |
|
|
2697 |
*/ |
|
|
2698 |
function PMA_setCookie($cookie, $value, $default = null) |
|
|
2699 |
{ |
|
|
2700 |
if (strlen($value) && null !== $default && $value === $default) { |
|
|
2701 |
// remove cookie, default value is used |
|
|
2702 |
return PMA_removeCookie($cookie); |
|
|
2703 |
} |
|
|
2704 |
|
|
|
2705 |
if (! strlen($value) && isset($_COOKIE[$cookie])) { |
|
|
2706 |
// remove cookie, value is empty |
|
|
2707 |
return PMA_removeCookie($cookie); |
|
|
2708 |
} |
|
|
2709 |
|
|
|
2710 |
if (! isset($_COOKIE[$cookie]) || $_COOKIE[$cookie] !== $value) { |
|
|
2711 |
// set cookie with new value |
|
|
2712 |
return setcookie($cookie, $value, time() + 60*60*24*30, |
|
|
2713 |
$GLOBALS['cookie_path'], '', $GLOBALS['is_https']); |
|
|
2714 |
} |
|
|
2715 |
|
|
|
2716 |
// cookie has already $value as value |
|
|
2717 |
return true; |
|
|
2718 |
} |
|
|
2719 |
|
|
|
2720 |
|
|
|
2721 |
/** |
|
|
2722 |
* include here only libraries which contain only function definitions |
|
|
2723 |
* no code im main()! |
|
|
2724 |
*/ |
|
|
2725 |
/** |
|
|
2726 |
* Include URL/hidden inputs generating. |
|
|
2727 |
*/ |
|
|
2728 |
require_once './libraries/url_generating.lib.php'; |
|
|
2729 |
|
|
|
2730 |
} |
|
|
2731 |
|
|
|
2732 |
|
|
|
2733 |
/******************************************************************************/ |
|
|
2734 |
/* start procedural code label_start_procedural */ |
|
|
2735 |
|
|
|
2736 |
/** |
|
|
2737 |
* protect against older PHP versions' bug about GLOBALS overwrite |
|
|
2738 |
* (no need to localize this message :)) |
|
|
2739 |
* but what if script.php?GLOBALS[admin]=1&GLOBALS[_REQUEST]=1 ??? |
|
|
2740 |
*/ |
|
|
2741 |
if (isset($_REQUEST['GLOBALS']) || isset($_FILES['GLOBALS']) |
|
|
2742 |
|| isset($_SERVER['GLOBALS']) || isset($_COOKIE['GLOBALS']) |
|
|
2743 |
|| isset($_ENV['GLOBALS'])) { |
|
|
2744 |
die('GLOBALS overwrite attempt'); |
|
|
2745 |
} |
|
|
2746 |
|
|
|
2747 |
/** |
|
|
2748 |
* just to be sure there was no import (registering) before here |
|
|
2749 |
* we empty the global space |
|
|
2750 |
*/ |
|
|
2751 |
$variables_whitelist = array ( |
|
|
2752 |
'GLOBALS', |
|
|
2753 |
'_SERVER', |
|
|
2754 |
'_GET', |
|
|
2755 |
'_POST', |
|
|
2756 |
'_REQUEST', |
|
|
2757 |
'_FILES', |
|
|
2758 |
'_ENV', |
|
|
2759 |
'_COOKIE', |
|
|
2760 |
'_SESSION', |
|
|
2761 |
); |
|
|
2762 |
|
|
|
2763 |
foreach (get_defined_vars() as $key => $value) { |
|
|
2764 |
if (!in_array($key, $variables_whitelist)) { |
|
|
2765 |
unset($$key); |
|
|
2766 |
} |
|
|
2767 |
} |
|
|
2768 |
unset($key, $value); |
|
|
2769 |
|
|
|
2770 |
|
|
|
2771 |
/** |
|
|
2772 |
* check if a subform is submitted |
|
|
2773 |
*/ |
|
|
2774 |
$__redirect = null; |
|
|
2775 |
if (isset($_POST['usesubform'])) { |
|
|
2776 |
// if a subform is present and should be used |
|
|
2777 |
// the rest of the form is deprecated |
|
|
2778 |
$subform_id = key($_POST['usesubform']); |
|
|
2779 |
$subform = $_POST['subform'][$subform_id]; |
|
|
2780 |
$_POST = $subform; |
|
|
2781 |
$_REQUEST = $subform; |
|
|
2782 |
if (isset($_POST['redirect']) |
|
|
2783 |
&& $_POST['redirect'] != basename(PMA_getenv('PHP_SELF'))) { |
|
|
2784 |
$__redirect = $_POST['redirect']; |
|
|
2785 |
unset($_POST['redirect']); |
|
|
2786 |
} // end if (isset($_POST['redirect'])) |
|
|
2787 |
unset($subform_id, $subform); |
|
|
2788 |
} // end if (isset($_POST['usesubform'])) |
|
|
2789 |
// end check if a subform is submitted |
|
|
2790 |
|
|
|
2791 |
if (get_magic_quotes_gpc()) { |
|
|
2792 |
PMA_arrayWalkRecursive($_GET, 'stripslashes', true); |
|
|
2793 |
PMA_arrayWalkRecursive($_POST, 'stripslashes', true); |
|
|
2794 |
PMA_arrayWalkRecursive($_COOKIE, 'stripslashes', true); |
|
|
2795 |
PMA_arrayWalkRecursive($_REQUEST, 'stripslashes', true); |
|
|
2796 |
} |
|
|
2797 |
|
|
|
2798 |
require_once './libraries/session.inc.php'; |
|
|
2799 |
|
|
|
2800 |
/** |
|
|
2801 |
* include deprecated grab_globals only if required |
|
|
2802 |
*/ |
|
|
2803 |
if (empty($__redirect) && !defined('PMA_NO_VARIABLES_IMPORT')) { |
|
|
2804 |
require './libraries/grab_globals.lib.php'; |
|
|
2805 |
} |
|
|
2806 |
|
|
|
2807 |
/** |
|
|
2808 |
* init some variables LABEL_variables_init |
|
|
2809 |
*/ |
|
|
2810 |
|
|
|
2811 |
/** |
|
|
2812 |
* @var array $GLOBALS['PMA_errors'] holds errors |
|
|
2813 |
*/ |
|
|
2814 |
$GLOBALS['PMA_errors'] = array(); |
|
|
2815 |
|
|
|
2816 |
/** |
|
|
2817 |
* @var array $GLOBALS['url_params'] holds params to be passed to next page |
|
|
2818 |
*/ |
|
|
2819 |
$GLOBALS['url_params'] = array(); |
|
|
2820 |
|
|
|
2821 |
/** |
|
|
2822 |
* @var array whitelist for $goto |
|
|
2823 |
*/ |
|
|
2824 |
$goto_whitelist = array( |
|
|
2825 |
//'browse_foreigners.php', |
|
|
2826 |
//'calendar.php', |
|
|
2827 |
//'changelog.php', |
|
|
2828 |
//'chk_rel.php', |
|
|
2829 |
'db_create.php', |
|
|
2830 |
'db_datadict.php', |
|
|
2831 |
'db_details.php', |
|
|
2832 |
'db_details_export.php', |
|
|
2833 |
'db_details_importdocsql.php', |
|
|
2834 |
'db_details_qbe.php', |
|
|
2835 |
'db_details_structure.php', |
|
|
2836 |
'db_import.php', |
|
|
2837 |
'db_operations.php', |
|
|
2838 |
'db_printview.php', |
|
|
2839 |
'db_search.php', |
|
|
2840 |
//'Documentation.html', |
|
|
2841 |
//'error.php', |
|
|
2842 |
'export.php', |
|
|
2843 |
'import.php', |
|
|
2844 |
//'index.php', |
|
|
2845 |
//'left.php', |
|
|
2846 |
//'license.php', |
|
|
2847 |
'main.php', |
|
|
2848 |
'pdf_pages.php', |
|
|
2849 |
'pdf_schema.php', |
|
|
2850 |
//'phpinfo.php', |
|
|
2851 |
'querywindow.php', |
|
|
2852 |
//'readme.php', |
|
|
2853 |
'server_binlog.php', |
|
|
2854 |
'server_collations.php', |
|
|
2855 |
'server_databases.php', |
|
|
2856 |
'server_engines.php', |
|
|
2857 |
'server_export.php', |
|
|
2858 |
'server_import.php', |
|
|
2859 |
'server_privileges.php', |
|
|
2860 |
'server_processlist.php', |
|
|
2861 |
'server_sql.php', |
|
|
2862 |
'server_status.php', |
|
|
2863 |
'server_variables.php', |
|
|
2864 |
'sql.php', |
|
|
2865 |
'tbl_addfield.php', |
|
|
2866 |
'tbl_alter.php', |
|
|
2867 |
'tbl_change.php', |
|
|
2868 |
'tbl_create.php', |
|
|
2869 |
'tbl_import.php', |
|
|
2870 |
'tbl_indexes.php', |
|
|
2871 |
'tbl_move_copy.php', |
|
|
2872 |
'tbl_printview.php', |
|
|
2873 |
'tbl_properties.php', |
|
|
2874 |
'tbl_properties_export.php', |
|
|
2875 |
'tbl_properties_operations.php', |
|
|
2876 |
'tbl_properties_structure.php', |
|
|
2877 |
'tbl_relation.php', |
|
|
2878 |
'tbl_replace.php', |
|
|
2879 |
'tbl_row_action.php', |
|
|
2880 |
'tbl_select.php', |
|
|
2881 |
//'themes.php', |
|
|
2882 |
'transformation_overview.php', |
|
|
2883 |
'transformation_wrapper.php', |
|
|
2884 |
'translators.html', |
|
|
2885 |
'user_password.php', |
|
|
2886 |
); |
|
|
2887 |
|
|
|
2888 |
/** |
|
|
2889 |
* check $__redirect against whitelist |
|
|
2890 |
*/ |
|
|
2891 |
if (! PMA_checkPageValidity($__redirect, $goto_whitelist)) { |
|
|
2892 |
$__redirect = null; |
|
|
2893 |
} |
|
|
2894 |
|
|
|
2895 |
/** |
|
|
2896 |
* @var string $goto holds page that should be displayed |
|
|
2897 |
*/ |
|
|
2898 |
// Security fix: disallow accessing serious server files via "?goto=" |
|
|
2899 |
if (PMA_checkPageValidity($_REQUEST['goto'], $goto_whitelist)) { |
|
|
2900 |
$GLOBALS['goto'] = $_REQUEST['goto']; |
|
|
2901 |
$GLOBALS['url_params']['goto'] = $_REQUEST['goto']; |
|
|
2902 |
} else { |
|
|
2903 |
unset($_REQUEST['goto'], $_GET['goto'], $_POST['goto'], $_COOKIE['goto']); |
|
|
2904 |
$GLOBALS['goto'] = ''; |
|
|
2905 |
} |
|
|
2906 |
|
|
|
2907 |
/** |
|
|
2908 |
* @var string $back returning page |
|
|
2909 |
*/ |
|
|
2910 |
if (PMA_checkPageValidity($_REQUEST['back'], $goto_whitelist)) { |
|
|
2911 |
$GLOBALS['back'] = $_REQUEST['back']; |
|
|
2912 |
} else { |
|
|
2913 |
unset($_REQUEST['back'], $_GET['back'], $_POST['back'], $_COOKIE['back']); |
|
|
2914 |
} |
|
|
2915 |
|
|
|
2916 |
/** |
|
|
2917 |
* Check whether user supplied token is valid, if not remove any |
|
|
2918 |
* possibly dangerous stuff from request. |
|
|
2919 |
*/ |
|
|
2920 |
if (!isset($_REQUEST['token']) || $_SESSION['PMA_token'] != $_REQUEST['token']) { |
|
|
2921 |
/* List of parameters which are allowed from unsafe source */ |
|
|
2922 |
$allow_list = array( |
|
|
2923 |
'db', 'table', 'lang', 'server', 'convcharset', 'collation_connection', 'target', |
|
|
2924 |
/* Session ID */ |
|
|
2925 |
'phpMyAdmin', |
|
|
2926 |
/* Cookie preferences */ |
|
|
2927 |
'pma_lang', 'pma_charset', 'pma_collation_connection', 'pma_convcharset', |
|
|
2928 |
/* Possible login form */ |
|
|
2929 |
'pma_username', 'pma_password', |
|
|
2930 |
); |
|
|
2931 |
$keys = array_keys($_REQUEST); |
|
|
2932 |
/* Remove any non allowed stuff from requests */ |
|
|
2933 |
foreach($keys as $key) { |
|
|
2934 |
if (!in_array($key, $allow_list)) { |
|
|
2935 |
unset($_REQUEST[$key]); |
|
|
2936 |
unset($_GET[$key]); |
|
|
2937 |
unset($_POST[$key]); |
|
|
2938 |
unset($GLOBALS[$key]); |
|
|
2939 |
} else { |
|
|
2940 |
// allowed stuff could be compromised so escape it |
|
|
2941 |
$_REQUEST[$key] = htmlspecialchars($_REQUEST[$key], ENT_QUOTES); |
|
|
2942 |
} |
|
|
2943 |
} |
|
|
2944 |
} |
|
|
2945 |
|
|
|
2946 |
/** |
|
|
2947 |
* @var string $convcharset |
|
|
2948 |
* @see also select_lang.lib.php |
|
|
2949 |
*/ |
|
|
2950 |
if (isset($_REQUEST['convcharset'])) { |
|
|
2951 |
$convcharset = strip_tags($_REQUEST['convcharset']); |
|
|
2952 |
} |
|
|
2953 |
|
|
|
2954 |
/** |
|
|
2955 |
* @var string $db current selected database |
|
|
2956 |
*/ |
|
|
2957 |
if (isset($_REQUEST['db'])) { |
|
|
2958 |
// can we strip tags from this? |
|
|
2959 |
// only \ and / is not allowed in db names for MySQL |
|
|
2960 |
$GLOBALS['db'] = $_REQUEST['db']; |
|
|
2961 |
$GLOBALS['url_params']['db'] = $GLOBALS['db']; |
|
|
2962 |
} else { |
|
|
2963 |
$GLOBALS['db'] = ''; |
|
|
2964 |
} |
|
|
2965 |
|
|
|
2966 |
/** |
|
|
2967 |
* @var string $db current selected database |
|
|
2968 |
*/ |
|
|
2969 |
if (isset($_REQUEST['table'])) { |
|
|
2970 |
// can we strip tags from this? |
|
|
2971 |
// only \ and / is not allowed in table names for MySQL |
|
|
2972 |
$GLOBALS['table'] = $_REQUEST['table']; |
|
|
2973 |
$GLOBALS['url_params']['table'] = $GLOBALS['table']; |
|
|
2974 |
} else { |
|
|
2975 |
$GLOBALS['table'] = ''; |
|
|
2976 |
} |
|
|
2977 |
|
|
|
2978 |
/** |
|
|
2979 |
* @var string $sql_query sql query to be executed |
|
|
2980 |
*/ |
|
|
2981 |
if (isset($_REQUEST['sql_query'])) { |
|
|
2982 |
$GLOBALS['sql_query'] = $_REQUEST['sql_query']; |
|
|
2983 |
} |
|
|
2984 |
|
|
|
2985 |
//$_REQUEST['set_theme'] // checked later in this file LABEL_theme_setup |
|
|
2986 |
//$_REQUEST['server']; // checked later in this file |
|
|
2987 |
//$_REQUEST['lang']; // checked by LABEL_loading_language_file |
|
|
2988 |
|
|
|
2989 |
|
|
|
2990 |
|
|
|
2991 |
/******************************************************************************/ |
|
|
2992 |
/* parsing config file LABEL_parsing_config_file */ |
|
|
2993 |
|
|
|
2994 |
if (empty($_SESSION['PMA_Config'])) { |
|
|
2995 |
/** |
|
|
2996 |
* We really need this one! |
|
|
2997 |
*/ |
|
|
2998 |
if (!function_exists('preg_replace')) { |
|
|
2999 |
header('Location: error.php' |
|
|
3000 |
. '?lang=' . urlencode($available_languages[$lang][2]) |
|
|
3001 |
. '&char=' . urlencode($charset) |
|
|
3002 |
. '&dir=' . urlencode($text_dir) |
|
|
3003 |
. '&type=' . urlencode($strError) |
|
|
3004 |
. '&error=' . urlencode( |
|
|
3005 |
strtr(sprintf($strCantLoad, 'pcre'), |
|
|
3006 |
array('<br />' => '[br]'))) |
|
|
3007 |
. '&' . SID |
|
|
3008 |
); |
|
|
3009 |
exit(); |
|
|
3010 |
} |
|
|
3011 |
|
|
|
3012 |
$_SESSION['PMA_Config'] = new PMA_Config('./config.inc.php'); |
|
|
3013 |
|
|
|
3014 |
} elseif (version_compare(phpversion(), '5', 'lt')) { |
|
|
3015 |
$_SESSION['PMA_Config']->__wakeup(); |
|
|
3016 |
} |
|
|
3017 |
|
|
|
3018 |
if (!defined('PMA_MINIMUM_COMMON')) { |
|
|
3019 |
$_SESSION['PMA_Config']->checkPmaAbsoluteUri(); |
|
|
3020 |
} |
|
|
3021 |
|
|
|
3022 |
// BC |
|
|
3023 |
$_SESSION['PMA_Config']->enableBc(); |
|
|
3024 |
|
|
|
3025 |
|
|
|
3026 |
/** |
|
|
3027 |
* check https connection |
|
|
3028 |
*/ |
|
|
3029 |
if ($_SESSION['PMA_Config']->get('ForceSSL') |
|
|
3030 |
&& !$_SESSION['PMA_Config']->get('is_https')) { |
|
|
3031 |
PMA_sendHeaderLocation( |
|
|
3032 |
preg_replace('/^http/', 'https', |
|
|
3033 |
$_SESSION['PMA_Config']->get('PmaAbsoluteUri')) |
|
|
3034 |
. PMA_generate_common_url($_GET)); |
|
|
3035 |
exit; |
|
|
3036 |
} |
|
|
3037 |
|
|
|
3038 |
|
|
|
3039 |
/******************************************************************************/ |
|
|
3040 |
/* loading language file LABEL_loading_language_file */ |
|
|
3041 |
|
|
|
3042 |
/** |
|
|
3043 |
* Added messages while developing: |
|
|
3044 |
*/ |
|
|
3045 |
if (file_exists('./lang/added_messages.php')) { |
|
|
3046 |
include './lang/added_messages.php'; |
|
|
3047 |
} |
|
|
3048 |
|
|
|
3049 |
/** |
|
|
3050 |
* Includes the language file if it hasn't been included yet |
|
|
3051 |
*/ |
|
|
3052 |
require_once './libraries/select_lang.lib.php'; |
|
|
3053 |
|
|
|
3054 |
|
|
|
3055 |
/** |
|
|
3056 |
* check for errors occured while loading config |
|
|
3057 |
*/ |
|
|
3058 |
if ($_SESSION['PMA_Config']->error_config_file) { |
|
|
3059 |
$GLOBALS['PMA_errors'][] = $strConfigFileError |
|
|
3060 |
.'<br /><br />' |
|
|
3061 |
.'<a href="' . $_SESSION['PMA_Config']->getSource() . '"' |
|
|
3062 |
.' target="_blank">' . $_SESSION['PMA_Config']->getSource() . '</a>'; |
|
|
3063 |
} |
|
|
3064 |
if ($_SESSION['PMA_Config']->error_config_default_file) { |
|
|
3065 |
$GLOBALS['PMA_errors'][] = sprintf($strConfigDefaultFileError, |
|
|
3066 |
$_SESSION['PMA_Config']->default_source); |
|
|
3067 |
} |
|
|
3068 |
if ($_SESSION['PMA_Config']->error_pma_uri) { |
|
|
3069 |
$GLOBALS['PMA_errors'][] = sprintf($strPmaUriError); |
|
|
3070 |
} |
|
|
3071 |
|
|
|
3072 |
/** |
|
|
3073 |
* Servers array fixups. |
|
|
3074 |
* $default_server comes from PMA_Config::enableBc() |
|
|
3075 |
* @todo merge into PMA_Config |
|
|
3076 |
*/ |
|
|
3077 |
// Do we have some server? |
|
|
3078 |
if (!isset($cfg['Servers']) || count($cfg['Servers']) == 0) { |
|
|
3079 |
// No server => create one with defaults |
|
|
3080 |
$cfg['Servers'] = array(1 => $default_server); |
|
|
3081 |
} else { |
|
|
3082 |
// We have server(s) => apply default config |
|
|
3083 |
$new_servers = array(); |
|
|
3084 |
|
|
|
3085 |
foreach ($cfg['Servers'] as $server_index => $each_server) { |
|
|
3086 |
if (!is_int($server_index) || $server_index < 1) { |
|
|
3087 |
$GLOBALS['PMA_errors'][] = sprintf($strInvalidServerIndex, $server_index); |
|
|
3088 |
continue; |
|
|
3089 |
} |
|
|
3090 |
|
|
|
3091 |
$each_server = array_merge($default_server, $each_server); |
|
|
3092 |
|
|
|
3093 |
// Don't use servers with no hostname |
|
|
3094 |
if ($each_server['connect_type'] == 'tcp' && empty($each_server['host'])) { |
|
|
3095 |
$GLOBALS['PMA_errors'][] = sprintf($strInvalidServerHostname, $server_index); |
|
|
3096 |
continue; |
|
|
3097 |
} |
|
|
3098 |
|
|
|
3099 |
// Final solution to bug #582890 |
|
|
3100 |
// If we are using a socket connection |
|
|
3101 |
// and there is nothing in the verbose server name |
|
|
3102 |
// or the host field, then generate a name for the server |
|
|
3103 |
// in the form of "Server 2", localized of course! |
|
|
3104 |
if ($each_server['connect_type'] == 'socket' && empty($each_server['host']) && empty($each_server['verbose'])) { |
|
|
3105 |
$each_server['verbose'] = $GLOBALS['strServer'] . $server_index; |
|
|
3106 |
} |
|
|
3107 |
|
|
|
3108 |
$new_servers[$server_index] = $each_server; |
|
|
3109 |
} |
|
|
3110 |
$cfg['Servers'] = $new_servers; |
|
|
3111 |
unset($new_servers, $server_index, $each_server); |
|
|
3112 |
} |
|
|
3113 |
|
|
|
3114 |
// Cleanup |
|
|
3115 |
unset($default_server); |
|
|
3116 |
|
|
|
3117 |
|
|
|
3118 |
/******************************************************************************/ |
|
|
3119 |
/* setup themes LABEL_theme_setup */ |
|
|
3120 |
|
|
|
3121 |
if (!isset($_SESSION['PMA_Theme_Manager'])) { |
|
|
3122 |
$_SESSION['PMA_Theme_Manager'] = new PMA_Theme_Manager; |
|
|
3123 |
} else { |
|
|
3124 |
$_SESSION['PMA_Theme_Manager']->checkConfig(); |
|
|
3125 |
} |
|
|
3126 |
|
|
|
3127 |
if (isset($_REQUEST['set_theme'])) { |
|
|
3128 |
// if user submit a theme |
|
|
3129 |
$_SESSION['PMA_Theme_Manager']->setActiveTheme($_REQUEST['set_theme']); |
|
|
3130 |
} |
|
|
3131 |
|
|
|
3132 |
$_SESSION['PMA_Theme'] = $_SESSION['PMA_Theme_Manager']->theme; |
|
|
3133 |
|
|
|
3134 |
// BC |
|
|
3135 |
$GLOBALS['theme'] = $_SESSION['PMA_Theme']->getName(); |
|
|
3136 |
$GLOBALS['pmaThemePath'] = $_SESSION['PMA_Theme']->getPath(); |
|
|
3137 |
$GLOBALS['pmaThemeImage'] = $_SESSION['PMA_Theme']->getImgPath(); |
|
|
3138 |
|
|
|
3139 |
/** |
|
|
3140 |
* load layout file if exists |
|
|
3141 |
*/ |
|
|
3142 |
if (@file_exists($_SESSION['PMA_Theme']->getLayoutFile())) { |
|
|
3143 |
include $_SESSION['PMA_Theme']->getLayoutFile(); |
|
|
3144 |
} |
|
|
3145 |
|
|
|
3146 |
if (!defined('PMA_MINIMUM_COMMON')) { |
|
|
3147 |
/** |
|
|
3148 |
* Charset conversion. |
|
|
3149 |
*/ |
|
|
3150 |
require_once './libraries/charset_conversion.lib.php'; |
|
|
3151 |
|
|
|
3152 |
/** |
|
|
3153 |
* String handling |
|
|
3154 |
*/ |
|
|
3155 |
require_once './libraries/string.lib.php'; |
|
|
3156 |
|
|
|
3157 |
/** |
|
|
3158 |
* @var array database list |
|
|
3159 |
*/ |
|
|
3160 |
$dblist = array(); |
|
|
3161 |
|
|
|
3162 |
/** |
|
|
3163 |
* If no server is selected, make sure that $cfg['Server'] is empty (so |
|
|
3164 |
* that nothing will work), and skip server authentication. |
|
|
3165 |
* We do NOT exit here, but continue on without logging into any server. |
|
|
3166 |
* This way, the welcome page will still come up (with no server info) and |
|
|
3167 |
* present a choice of servers in the case that there are multiple servers |
|
|
3168 |
* and '$cfg['ServerDefault'] = 0' is set. |
|
|
3169 |
*/ |
|
|
3170 |
if (!empty($_REQUEST['server']) && !empty($cfg['Servers'][$_REQUEST['server']])) { |
|
|
3171 |
$GLOBALS['server'] = $_REQUEST['server']; |
|
|
3172 |
$cfg['Server'] = $cfg['Servers'][$GLOBALS['server']]; |
|
|
3173 |
} else { |
|
|
3174 |
if (!empty($cfg['Servers'][$cfg['ServerDefault']])) { |
|
|
3175 |
$GLOBALS['server'] = $cfg['ServerDefault']; |
|
|
3176 |
$cfg['Server'] = $cfg['Servers'][$GLOBALS['server']]; |
|
|
3177 |
} else { |
|
|
3178 |
$GLOBALS['server'] = 0; |
|
|
3179 |
$cfg['Server'] = array(); |
|
|
3180 |
} |
|
|
3181 |
} |
|
|
3182 |
$GLOBALS['url_params']['server'] = $GLOBALS['server']; |
|
|
3183 |
|
|
|
3184 |
|
|
|
3185 |
if (!empty($cfg['Server'])) { |
|
|
3186 |
|
|
|
3187 |
/** |
|
|
3188 |
* Loads the proper database interface for this server |
|
|
3189 |
*/ |
|
|
3190 |
require_once './libraries/database_interface.lib.php'; |
|
|
3191 |
|
|
|
3192 |
// Gets the authentication library that fits the $cfg['Server'] settings |
|
|
3193 |
// and run authentication |
|
|
3194 |
|
|
|
3195 |
// (for a quick check of path disclosure in auth/cookies:) |
|
|
3196 |
$coming_from_common = true; |
|
|
3197 |
|
|
|
3198 |
if (!file_exists('./libraries/auth/' . $cfg['Server']['auth_type'] . '.auth.lib.php')) { |
|
|
3199 |
header('Location: error.php' |
|
|
3200 |
. '?lang=' . urlencode($available_languages[$lang][2]) |
|
|
3201 |
. '&char=' . urlencode($charset) |
|
|
3202 |
. '&dir=' . urlencode($text_dir) |
|
|
3203 |
. '&type=' . urlencode($strError) |
|
|
3204 |
. '&error=' . urlencode( |
|
|
3205 |
$strInvalidAuthMethod . ' ' |
|
|
3206 |
. $cfg['Server']['auth_type']) |
|
|
3207 |
. '&' . SID |
|
|
3208 |
); |
|
|
3209 |
exit(); |
|
|
3210 |
} |
|
|
3211 |
require_once './libraries/auth/' . $cfg['Server']['auth_type'] . '.auth.lib.php'; |
|
|
3212 |
if (!PMA_auth_check()) { |
|
|
3213 |
PMA_auth(); |
|
|
3214 |
} else { |
|
|
3215 |
PMA_auth_set_user(); |
|
|
3216 |
} |
|
|
3217 |
|
|
|
3218 |
// Check IP-based Allow/Deny rules as soon as possible to reject the |
|
|
3219 |
// user |
|
|
3220 |
// Based on mod_access in Apache: |
|
|
3221 |
// http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/aaa/mod_access.c?rev=1.37&content-type=text/vnd.viewcvs-markup |
|
|
3222 |
// Look at: "static int check_dir_access(request_rec *r)" |
|
|
3223 |
// Robbat2 - May 10, 2002 |
|
|
3224 |
if (isset($cfg['Server']['AllowDeny']) |
|
|
3225 |
&& isset($cfg['Server']['AllowDeny']['order'])) { |
|
|
3226 |
|
|
|
3227 |
require_once './libraries/ip_allow_deny.lib.php'; |
|
|
3228 |
|
|
|
3229 |
$allowDeny_forbidden = false; // default |
|
|
3230 |
if ($cfg['Server']['AllowDeny']['order'] == 'allow,deny') { |
|
|
3231 |
$allowDeny_forbidden = true; |
|
|
3232 |
if (PMA_allowDeny('allow')) { |
|
|
3233 |
$allowDeny_forbidden = false; |
|
|
3234 |
} |
|
|
3235 |
if (PMA_allowDeny('deny')) { |
|
|
3236 |
$allowDeny_forbidden = true; |
|
|
3237 |
} |
|
|
3238 |
} elseif ($cfg['Server']['AllowDeny']['order'] == 'deny,allow') { |
|
|
3239 |
if (PMA_allowDeny('deny')) { |
|
|
3240 |
$allowDeny_forbidden = true; |
|
|
3241 |
} |
|
|
3242 |
if (PMA_allowDeny('allow')) { |
|
|
3243 |
$allowDeny_forbidden = false; |
|
|
3244 |
} |
|
|
3245 |
} elseif ($cfg['Server']['AllowDeny']['order'] == 'explicit') { |
|
|
3246 |
if (PMA_allowDeny('allow') |
|
|
3247 |
&& !PMA_allowDeny('deny')) { |
|
|
3248 |
$allowDeny_forbidden = false; |
|
|
3249 |
} else { |
|
|
3250 |
$allowDeny_forbidden = true; |
|
|
3251 |
} |
|
|
3252 |
} // end if ... elseif ... elseif |
|
|
3253 |
|
|
|
3254 |
// Ejects the user if banished |
|
|
3255 |
if ($allowDeny_forbidden) { |
|
|
3256 |
PMA_auth_fails(); |
|
|
3257 |
} |
|
|
3258 |
unset($allowDeny_forbidden); //Clean up after you! |
|
|
3259 |
} // end if |
|
|
3260 |
|
|
|
3261 |
// is root allowed? |
|
|
3262 |
if (!$cfg['Server']['AllowRoot'] && $cfg['Server']['user'] == 'root') { |
|
|
3263 |
$allowDeny_forbidden = true; |
|
|
3264 |
PMA_auth_fails(); |
|
|
3265 |
unset($allowDeny_forbidden); //Clean up after you! |
|
|
3266 |
} |
|
|
3267 |
|
|
|
3268 |
// The user can work with only some databases |
|
|
3269 |
if (isset($cfg['Server']['only_db']) && $cfg['Server']['only_db'] != '') { |
|
|
3270 |
if (is_array($cfg['Server']['only_db'])) { |
|
|
3271 |
$dblist = $cfg['Server']['only_db']; |
|
|
3272 |
} else { |
|
|
3273 |
$dblist[] = $cfg['Server']['only_db']; |
|
|
3274 |
} |
|
|
3275 |
} // end if |
|
|
3276 |
|
|
|
3277 |
$bkp_track_err = @ini_set('track_errors', 1); |
|
|
3278 |
|
|
|
3279 |
// Try to connect MySQL with the control user profile (will be used to |
|
|
3280 |
// get the privileges list for the current user but the true user link |
|
|
3281 |
// must be open after this one so it would be default one for all the |
|
|
3282 |
// scripts) |
|
|
3283 |
if ($cfg['Server']['controluser'] != '') { |
|
|
3284 |
$controllink = PMA_DBI_connect($cfg['Server']['controluser'], |
|
|
3285 |
$cfg['Server']['controlpass'], true); |
|
|
3286 |
} else { |
|
|
3287 |
$controllink = PMA_DBI_connect($cfg['Server']['user'], |
|
|
3288 |
$cfg['Server']['password'], true); |
|
|
3289 |
} // end if ... else |
|
|
3290 |
|
|
|
3291 |
// Pass #1 of DB-Config to read in master level DB-Config will go here |
|
|
3292 |
// Robbat2 - May 11, 2002 |
|
|
3293 |
|
|
|
3294 |
// Connects to the server (validates user's login) |
|
|
3295 |
$userlink = PMA_DBI_connect($cfg['Server']['user'], |
|
|
3296 |
$cfg['Server']['password'], false); |
|
|
3297 |
|
|
|
3298 |
// Pass #2 of DB-Config to read in user level DB-Config will go here |
|
|
3299 |
// Robbat2 - May 11, 2002 |
|
|
3300 |
|
|
|
3301 |
@ini_set('track_errors', $bkp_track_err); |
|
|
3302 |
unset($bkp_track_err); |
|
|
3303 |
|
|
|
3304 |
/** |
|
|
3305 |
* SQL Parser code |
|
|
3306 |
*/ |
|
|
3307 |
require_once './libraries/sqlparser.lib.php'; |
|
|
3308 |
|
|
|
3309 |
/** |
|
|
3310 |
* SQL Validator interface code |
|
|
3311 |
*/ |
|
|
3312 |
require_once './libraries/sqlvalidator.lib.php'; |
|
|
3313 |
|
|
|
3314 |
// if 'only_db' is set for the current user, there is no need to check for |
|
|
3315 |
// available databases in the "mysql" db |
|
|
3316 |
$dblist_cnt = count($dblist); |
|
|
3317 |
if ($dblist_cnt) { |
|
|
3318 |
$true_dblist = array(); |
|
|
3319 |
$is_show_dbs = true; |
|
|
3320 |
|
|
|
3321 |
$dblist_asterisk_bool = false; |
|
|
3322 |
for ($i = 0; $i < $dblist_cnt; $i++) { |
|
|
3323 |
|
|
|
3324 |
// The current position |
|
|
3325 |
if ($dblist[$i] == '*' && $dblist_asterisk_bool == false) { |
|
|
3326 |
$dblist_asterisk_bool = true; |
|
|
3327 |
$dblist_full = PMA_safe_db_list(false, $controllink, false, |
|
|
3328 |
$userlink, $cfg, $dblist); |
|
|
3329 |
foreach ($dblist_full as $dbl_val) { |
|
|
3330 |
if (!in_array($dbl_val, $dblist)) { |
|
|
3331 |
$true_dblist[] = $dbl_val; |
|
|
3332 |
} |
|
|
3333 |
} |
|
|
3334 |
|
|
|
3335 |
continue; |
|
|
3336 |
} elseif ($dblist[$i] == '*') { |
|
|
3337 |
// We don't want more than one asterisk inside our 'only_db'. |
|
|
3338 |
continue; |
|
|
3339 |
} |
|
|
3340 |
if ($is_show_dbs && preg_match('/(^|[^\\\\])(_|%)/', $dblist[$i])) { |
|
|
3341 |
$local_query = 'SHOW DATABASES LIKE \'' . $dblist[$i] . '\''; |
|
|
3342 |
// here, a PMA_DBI_query() could fail silently |
|
|
3343 |
// if SHOW DATABASES is disabled |
|
|
3344 |
$rs = PMA_DBI_try_query($local_query, $userlink); |
|
|
3345 |
|
|
|
3346 |
if ($i == 0 && ! $rs) { |
|
|
3347 |
$error_code = substr(PMA_DBI_getError($userlink), 1, 4); |
|
|
3348 |
if ($error_code == 1227 || $error_code == 1045) { |
|
|
3349 |
// "SHOW DATABASES" statement is disabled or not allowed to user |
|
|
3350 |
$true_dblist[] = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i])); |
|
|
3351 |
$is_show_dbs = false; |
|
|
3352 |
} |
|
|
3353 |
unset($error_code); |
|
|
3354 |
} |
|
|
3355 |
// Debug |
|
|
3356 |
// elseif (PMA_DBI_getError($controllink)) { |
|
|
3357 |
// PMA_mysqlDie(PMA_DBI_getError($controllink), $local_query, false); |
|
|
3358 |
// } |
|
|
3359 |
while ($row = @PMA_DBI_fetch_row($rs)) { |
|
|
3360 |
$true_dblist[] = $row[0]; |
|
|
3361 |
} // end while |
|
|
3362 |
if ($rs) { |
|
|
3363 |
PMA_DBI_free_result($rs); |
|
|
3364 |
} |
|
|
3365 |
} else { |
|
|
3366 |
$true_dblist[] = str_replace('\\_', '_', |
|
|
3367 |
str_replace('\\%', '%', $dblist[$i])); |
|
|
3368 |
} // end if... else... |
|
|
3369 |
} // end for |
|
|
3370 |
$dblist = $true_dblist; |
|
|
3371 |
unset($true_dblist, $i, $dbl_val); |
|
|
3372 |
$only_db_check = true; |
|
|
3373 |
} // end if |
|
|
3374 |
|
|
|
3375 |
// 'only_db' is empty for the current user... |
|
|
3376 |
else { |
|
|
3377 |
$only_db_check = false; |
|
|
3378 |
} // end if (!$dblist_cnt) |
|
|
3379 |
|
|
|
3380 |
if (isset($dblist_full) && !count($dblist_full)) { |
|
|
3381 |
$dblist = PMA_safe_db_list($only_db_check, $controllink, |
|
|
3382 |
$dblist_cnt, $userlink, $cfg, $dblist); |
|
|
3383 |
} |
|
|
3384 |
unset($only_db_check, $dblist_full); |
|
|
3385 |
|
|
|
3386 |
} // end server connecting |
|
|
3387 |
|
|
|
3388 |
|
|
|
3389 |
// Kanji encoding convert feature appended by Y.Kawada (2002/2/20) |
|
|
3390 |
if (@function_exists('mb_convert_encoding') |
|
|
3391 |
&& strpos(' ' . $lang, 'ja-') |
|
|
3392 |
&& file_exists('./libraries/kanji-encoding.lib.php')) { |
|
|
3393 |
require_once './libraries/kanji-encoding.lib.php'; |
|
|
3394 |
define('PMA_MULTIBYTE_ENCODING', 1); |
|
|
3395 |
} // end if |
|
|
3396 |
|
|
|
3397 |
/** |
|
|
3398 |
* save some settings in cookies |
|
|
3399 |
*/ |
|
|
3400 |
PMA_setCookie('pma_lang', $GLOBALS['lang']); |
|
|
3401 |
PMA_setCookie('pma_charset', $GLOBALS['convcharset']); |
|
|
3402 |
PMA_setCookie('pma_collation_connection', $GLOBALS['collation_connection']); |
|
|
3403 |
|
|
|
3404 |
$_SESSION['PMA_Theme_Manager']->setThemeCookie(); |
|
|
3405 |
|
|
|
3406 |
} // end if !defined('PMA_MINIMUM_COMMON') |
|
|
3407 |
|
|
|
3408 |
if (!empty($__redirect) && in_array($__redirect, $goto_whitelist)) { |
|
|
3409 |
// to handle bug #1388167 |
|
|
3410 |
if (isset($_GET['is_js_confirmed'])) { |
|
|
3411 |
$is_js_confirmed = 1; |
|
|
3412 |
} |
|
|
3413 |
require $__redirect; |
|
|
3414 |
exit(); |
|
|
3415 |
} |
|
|
3416 |
|
|
|
3417 |
?> |