Fixed bug #658668 (\n\r\t handling)
[phpmyadmin/crack.git] / libraries / common.lib.php3
blobd5fa4119d4307d67e30321597e3ee8c50043544c
1 <?php
2 /* $Id$ */
3 // vim: expandtab sw=4 ts=4 sts=4:
5 error_reporting(E_ALL);
6 /**
7 * Misc stuff and functions used by almost all the scripts.
8 * Among other things, it contains the advanced authentification work.
9 */
13 if (!defined('PMA_COMMON_LIB_INCLUDED')) {
14 define('PMA_COMMON_LIB_INCLUDED', 1);
16 /**
17 * Order of sections for common.lib.php3:
19 * in PHP3, functions and constants must be physically defined
20 * before they are referenced
22 * some functions need the constants of libraries/defines.lib.php3
23 * and defines_php.lib.php3
25 * the PMA_setFontSizes() function must be before the call to the
26 * libraries/auth/cookie.auth.lib.php3 library
28 * the include of libraries/defines.lib.php3 must be after the connection
29 * to db to get the MySql version
31 * the PMA_sqlAddslashes() function must be before the connection to db
33 * the authentication libraries must be before the connection to db but
34 * after the PMA_isInto() function
36 * the PMA_mysqlDie() function must be before the connection to db but
37 * after mysql extension has been loaded
39 * the PMA_mysqlDie() function needs the PMA_format_sql() Function
41 * ... so the required order is:
43 * - parsing of the configuration file
44 * - first load of the libraries/define.lib.php3 library (won't get the
45 * MySQL release number)
46 * - load of mysql extension (if necessary)
47 * - definition of PMA_sqlAddslashes()
48 * - definition of PMA_format_sql()
49 * - definition of PMA_mysqlDie()
50 * - definition of PMA_isInto()
51 * - definition of PMA_setFontSizes()
52 * - loading of an authentication library
53 * - db connection
54 * - authentication work
55 * - second load of the libraries/define.lib.php3 library to get the MySQL
56 * release number)
57 * - other functions, respecting dependencies
61 /**
62 * Avoids undefined variables in PHP3
64 if (!isset($use_backquotes)) {
65 $use_backquotes = 0;
67 if (!isset($pos)) {
68 $pos = 0;
71 /**
72 * Detects the config file we want to load
74 if (file_exists('./config.inc.developer.php3')) {
75 $cfgfile_to_load = './config.inc.developer.php3';
76 } else {
77 $cfgfile_to_load = './config.inc.php3';
80 /**
81 * Parses the configuration file and gets some constants used to define
82 * versions of phpMyAdmin/php/mysql...
84 $old_error_reporting = error_reporting(0);
85 include($cfgfile_to_load);
86 // Include failed
87 if (!isset($cfgServers) && !isset($cfg['Servers'])) {
88 // Creates fake settings
89 $cfg = array('DefaultLang' => 'en-iso-8859-1',
90 'AllowAnywhereRecoding' => FALSE);
91 // Loads the language file
92 include('./libraries/select_lang.lib.php3');
93 // Sends the Content-Type header
94 header('Content-Type: text/html; charset=' . $charset);
95 // Displays the error message
97 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
98 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
99 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $available_languages[$lang][2]; ?>" lang="<?php echo $available_languages[$lang][2]; ?>" dir="<?php echo $text_dir; ?>">
101 <head>
102 <title>phpMyAdmin</title>
103 <meta http-equiv="Content-Type" content="text/html; charset=<?php echo $charset; ?>" />
104 <style type="text/css">
105 <!--
106 body {font-family: sans-serif; font-size: small; color: #000000; background-color: #F5F5F5}
107 h1 {font-family: sans-serif; font-size: large; font-weight: bold}
108 //-->
109 </style>
110 </head>
113 <body bgcolor="#ffffff">
114 <h1>phpMyAdmin - <?php echo $strError; ?></h1>
116 <?php echo $strConfigFileError; ?><br /><br />
117 <a href="config.inc.php3" target="_blank">config.inc.php3</a>
118 </p>
119 </body>
121 </html>
122 <?php
123 exit();
125 error_reporting($old_error_reporting);
126 unset($old_error_reporting);
127 unset($cfgfile_to_load);
130 * Includes compatibility code for older config.inc.php3 revisions
131 * if necessary
133 if (!isset($cfg['FileRevision']) || (int) substr($cfg['FileRevision'], 13, 3) < 167) {
134 include('./libraries/config_import.lib.php3');
138 * Includes the language file if it hasn't been included yet
140 if (!defined('PMA_SELECT_LANG_LIB_INCLUDED')) {
141 include('./libraries/select_lang.lib.php3');
145 * Include MySQL wrappers.
147 include('./libraries/mysql_wrappers.lib.php3');
150 * Gets constants that defines the PHP version number.
151 * This include must be located physically before any code that needs to
152 * reference the constants, else PHP 3.0.16 won't be happy.
154 include('./libraries/defines_php.lib.php3');
157 * Define $is_upload
159 $is_upload = (PMA_PHP_INT_VERSION >= 40000 && function_exists('ini_get'))
160 ? ((strtolower(ini_get('file_uploads')) == 'on' || ini_get('file_uploads') == 1) && intval(ini_get('upload_max_filesize')))
161 // loic1: php 3.0.15 and lower bug -> always enabled
162 : (PMA_PHP_INT_VERSION < 30016 || intval(@get_cfg_var('upload_max_filesize')));
165 * Charset conversion.
167 include('./libraries/charset_conversion.lib.php3');
170 * Gets constants that defines the MySQL version number.
171 * This include must be located physically before any code that needs to
172 * reference the constants, else PHP 3.0.16 won't be happy; and must be
173 * located after we are connected to db to get the MySql version (see
174 * below).
176 include('./libraries/defines.lib.php3');
179 * String handling
181 include('./libraries/string.lib.php3');
184 * SQL Parser data and code
186 include('./libraries/sqlparser.data.php3');
187 include('./libraries/sqlparser.lib.php3');
190 * SQL Validator interface code
192 include('./libraries/sqlvalidator.lib.php3');
194 // If zlib output compression is set in the php configuration file, no
195 // output buffering should be run
196 if (PMA_PHP_INT_VERSION < 40000
197 || (PMA_PHP_INT_VERSION >= 40005 && @ini_get('zlib.output_compression'))) {
198 $cfg['OBGzip'] = FALSE;
202 * Include URL/hidden inputs generating.
204 include('./libraries/url_generating.lib.php3');
208 * Loads the mysql extensions if it is not loaded yet
209 * staybyte - 26. June 2001
211 if (((PMA_PHP_INT_VERSION >= 40000 && !@ini_get('safe_mode') && @ini_get('enable_dl'))
212 || (PMA_PHP_INT_VERSION < 40000 && PMA_PHP_INT_VERSION > 30009 && !@get_cfg_var('safe_mode')))
213 && @function_exists('dl')) {
214 if (PMA_PHP_INT_VERSION < 40000) {
215 $extension = 'MySQL';
216 } else {
217 $extension = 'mysql';
219 if (PMA_IS_WINDOWS) {
220 $suffix = '.dll';
221 } else {
222 $suffix = '.so';
224 if (!@extension_loaded($extension)) {
225 @dl($extension . $suffix);
227 if (!@extension_loaded($extension)) {
228 echo $strCantLoadMySQL . '<br />' . "\n"
229 . '<a href="./Documentation.html#faqmysql" target="documentation">' . $GLOBALS['strDocu'] . '</a>' . "\n";
230 exit();
232 } // end load mysql extension
234 // check whether mysql is available
235 if (!@function_exists('mysql_connect')) {
236 echo $strCantLoadMySQL . '<br />' . "\n"
237 . '<a href="./Documentation.html#faqmysql" target="documentation">' . $GLOBALS['strDocu'] . '</a>' . "\n";
238 exit();
244 * Add slashes before "'" and "\" characters so a value containing them can
245 * be used in a sql comparison.
247 * @param string the string to slash
248 * @param boolean whether the string will be used in a 'LIKE' clause
249 * (it then requires two more escaped sequences) or not
250 * @param boolean whether to treat cr/lfs as escape-worthy entities
251 (converts \n to \\n, \r to \\r)
254 * @return string the slashed string
256 * @access public
258 function PMA_sqlAddslashes($a_string = '', $is_like = FALSE, $crlf = FALSE)
260 if ($is_like) {
261 $a_string = str_replace('\\', '\\\\\\\\', $a_string);
262 } else {
263 $a_string = str_replace('\\', '\\\\', $a_string);
266 if ($crlf) {
267 $a_string = str_replace("\n", '\n', $a_string);
268 $a_string = str_replace("\r", '\r', $a_string);
269 $a_string = str_replace("\t", '\t', $a_string);
272 $a_string = str_replace('\'', '\\\'', $a_string);
274 return $a_string;
275 } // end of the 'PMA_sqlAddslashes()' function
279 * Add slashes before "_" and "%" characters for using them in MySQL
280 * database, table and field names.
281 * Note: This function does not escape backslashes!
283 * @param string the string to escape
285 * @return string the escaped string
287 * @access public
289 function PMA_escape_mysql_wildcards($name)
291 $name = str_replace('_', '\\_', $name);
292 $name = str_replace('%', '\\%', $name);
294 return $name;
295 } // end of the 'PMA_escape_mysql_wildcards()' function
299 * format sql strings
301 * @param mixed pre-parsed SQL structure
303 * @return string the formatted sql
305 * @global array the configuration array
306 * @global boolean whether the current statement is a multiple one or not
308 * @access public
310 * @author Robin Johnson <robbat2@users.sourceforge.net>
312 function PMA_formatSql($parsed_sql)
314 global $cfg;
316 // Check that we actually have a valid set of parsed data
317 // well, not quite
318 // first check for the SQL parser having hit an error
319 if (PMA_SQP_isError()) {
320 return $parsed_sql;
322 // then check for an array
323 if (!is_array($parsed_sql)) {
324 // We don't so just return the input directly
325 // This is intended to be used for when the SQL Parser is turned off
326 $formatted_sql = '<pre>' . "\n"
327 . $parsed_sql . "\n"
328 . '</pre>';
329 return $formatted_sql;
332 $formatted_sql = '';
334 switch ($cfg['SQP']['fmtType']) {
335 case 'none':
336 $formatted_sql = PMA_SQP_formatNone($parsed_sql);
337 break;
338 case 'html':
339 $formatted_sql = PMA_SQP_formatHtml($parsed_sql,'color');
340 break;
341 case 'text':
342 //$formatted_sql = PMA_SQP_formatText($parsed_sql);
343 $formatted_sql = PMA_SQP_formatHtml($parsed_sql,'text');
344 break;
345 default:
346 break;
347 } // end switch
349 return $formatted_sql;
350 } // end of the "PMA_formatSql()" function
354 * Displays a MySQL error message in the right frame.
356 * @param string the error mesage
357 * @param string the sql query that failed
358 * @param boolean whether to show a "modify" link or not
359 * @param string the "back" link url (full path is not required)
361 * @global array the configuration array
363 * @access public
365 function PMA_mysqlDie($error_message = '', $the_query = '',
366 $is_modify_link = TRUE, $back_url = '')
368 global $cfg;
370 if (empty($GLOBALS['is_header_sent'])) {
371 include('./header.inc.php3');
374 if (!$error_message) {
375 $error_message = PMA_mysql_error();
377 if (!$the_query && !empty($GLOBALS['sql_query'])) {
378 $the_query = $GLOBALS['sql_query'];
381 // --- Added to solve bug #641765
382 // Robbat2 - 12 January 2003, 9:46PM
383 // Revised, Robbat2 - 13 Janurary 2003, 2:59PM
384 if (PMA_SQP_isError()) {
385 $parsed_sql = $the_query;
386 } else {
387 $parsed_sql = PMA_SQP_parse($the_query);
389 // ---
391 echo '<p><b>'. $GLOBALS['strError'] . '</b></p>' . "\n";
392 // if the config password is wrong, or the MySQL server does not
393 // respond, do not show the query that would reveal the
394 // username/password
395 if (!empty($the_query) && !strstr($the_query, 'connect')) {
396 // --- Added to solve bug #641765
397 // Robbat2 - 12 January 2003, 9:46PM
398 // Revised, Robbat2 - 13 Janurary 2003, 2:59PM
399 if (PMA_SQP_isError()) {
400 echo PMA_SQP_getErrorString();
402 // ---
403 echo '<p>' . "\n";
404 echo ' ' . $GLOBALS['strSQLQuery'] . '&nbsp;:&nbsp;' . "\n";
405 if ($is_modify_link && isset($db)) {
406 echo ' ['
407 . '<a href="db_details.php3?' . PMA_generate_common_url($GLOBALS['db']) . '&amp;sql_query=' . urlencode($the_query) . '&amp;show_query=1">' . $GLOBALS['strEdit'] . '</a>'
408 . ']' . "\n";
409 } // end if
410 echo '</p>' . "\n"
411 . '<p>' . "\n"
412 . ' ' . PMA_formatSql($parsed_sql) . "\n"
413 . '</p>' . "\n";
414 } // end if
415 if (!empty($error_message)) {
416 $error_message = htmlspecialchars($error_message);
417 $error_message = ereg_replace("((\015\012)|(\015)|(\012)){3,}", "\n\n", $error_message);
419 echo '<p>' . "\n"
420 . ' ' . $GLOBALS['strMySQLSaid'] . '<br />' . "\n"
421 . '</p>' . "\n";
422 echo '<pre>' . "\n"
423 . $error_message . "\n"
424 . '</pre>' . "\n";
427 if (!empty($back_url)) {
428 echo '<a href="' . $back_url . '">' . $GLOBALS['strBack'] . '</a>';
430 echo "\n";
432 include('./footer.inc.php3');
433 exit();
434 } // end of the 'PMA_mysqlDie()' function
438 * Defines whether a string exists inside an array or not
440 * @param string string to search for
441 * @param mixed array to search into
443 * @return integer the rank of the $toFind string in the array or '-1' if
444 * it hasn't been found
446 * @access public
448 function PMA_isInto($toFind = '', &$in)
450 $max = count($in);
451 for ($i = 0; $i < $max && ($toFind != $in[$i]); $i++) {
452 // void();
455 return ($i < $max) ? $i : -1;
456 } // end of the 'PMA_isInto()' function
460 * Determines the font sizes to use depending on the os and browser of the
461 * user.
463 * This function is based on an article from phpBuilder (see
464 * http://www.phpbuilder.net/columns/tim20000821.php3).
466 * @return boolean always true
468 * @global string the standard font size
469 * @global string the font size for titles
470 * @global string the small font size
471 * @global string the smallest font size
473 * @access public
475 * @version 1.1
477 function PMA_setFontSizes()
479 global $font_size, $font_biggest, $font_bigger, $font_smaller, $font_smallest;
481 // IE (<6)/Opera (<7) for win case: needs smaller fonts than anyone else
482 if (PMA_USR_OS == 'Win'
483 && ((PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER < 6)
484 || (PMA_USR_BROWSER_AGENT == 'OPERA' && PMA_USR_BROWSER_VER < 7))) {
485 $font_size = 'x-small';
486 $font_biggest = 'large';
487 $font_bigger = 'medium';
488 $font_smaller = '90%';
489 $font_smallest = '7pt';
491 // IE6 and other browsers for win case
492 else if (PMA_USR_OS == 'Win') {
493 $font_size = 'small';
494 $font_biggest = 'large';
495 $font_bigger = 'medium';
496 $font_smaller = (PMA_USR_BROWSER_AGENT == 'IE')
497 ? '90%'
498 : 'x-small';
499 $font_smallest = 'x-small';
501 // Some mac browsers need also smaller default fonts size (OmniWeb &
502 // Opera)...
503 else if (PMA_USR_OS == 'Mac'
504 && (PMA_USR_BROWSER_AGENT == 'OMNIWEB' || PMA_USR_BROWSER_AGENT == 'OPERA')) {
505 $font_size = 'x-small';
506 $font_biggest = 'large';
507 $font_bigger = 'medium';
508 $font_smaller = '90%';
509 $font_smallest = '7pt';
511 // ... but most of them (except IE 5+ & NS 6+) need bigger fonts
512 else if ((PMA_USR_OS == 'Mac'
513 && ((PMA_USR_BROWSER_AGENT != 'IE' && PMA_USR_BROWSER_AGENT != 'MOZILLA')
514 || PMA_USR_BROWSER_VER < 5))
515 || PMA_USR_BROWSER_AGENT == 'KONQUEROR') {
516 $font_size = 'medium';
517 $font_biggest = 'x-large';
518 $font_bigger = 'large';
519 $font_smaller = 'small';
520 $font_smallest = 'x-small';
522 // OS/2 browser
523 else if (PMA_USR_OS == 'OS/2'
524 && PMA_USR_BROWSER_AGENT == 'OPERA') {
525 $font_size = 'small';
526 $font_biggest = 'medium';
527 $font_bigger = 'medium';
528 $font_smaller = 'x-small';
529 $font_smallest = 'x-small';
531 else {
532 $font_size = 'small';
533 $font_biggest = 'large';
534 $font_bigger = 'medium';
535 $font_smaller = 'x-small';
536 $font_smallest = 'x-small';
539 return TRUE;
540 } // end of the 'PMA_setFontSizes()' function
544 * $cfg['PmaAbsoluteUri'] is a required directive else cookies won't be
545 * set properly and, depending on browsers, inserting or updating a
546 * record might fail
548 $display_pmaAbsoluteUri_warning = 0;
550 // Olivier: Setup a default value to let the people and lazy syadmins
551 // work anyway, but display a big warning on the main.php3
552 // page.
553 if (empty($cfg['PmaAbsoluteUri'])) {
554 if (!empty($_SERVER)) {
555 $SERVER_ARRAY = '_SERVER';
556 } else if (!empty($HTTP_SERVER_VARS)) {
557 $SERVER_ARRAY = 'HTTP_SERVER_VARS';
558 } else {
559 $SERVER_ARRAY = 'GLOBALS';
560 } // end if
561 if (isset(${$SERVER_ARRAY}['HTTP_HOST'])) {
562 $HTTP_HOST = ${$SERVER_ARRAY}['HTTP_HOST'];
564 if (isset(${$SERVER_ARRAY}['HTTPS'])) {
565 $HTTPS = ${$SERVER_ARRAY}['HTTPS'];
567 if (isset(${$SERVER_ARRAY}['SERVER_PORT'])) {
568 $SERVER_PORT = ${$SERVER_ARRAY}['SERVER_PORT'];
570 if (isset(${$SERVER_ARRAY}['REQUEST_URI'])) {
571 $REQUEST_URI = ${$SERVER_ARRAY}['REQUEST_URI'];
573 if (isset(${$SERVER_ARRAY}['PATH_INFO'])) {
574 $PATH_INFO = ${$SERVER_ARRAY}['PATH_INFO'];
576 $port_in_HTTP_HOST = (strpos($HTTP_HOST, ':') > 0);
577 $cfg['PmaAbsoluteUri'] = ((!empty($HTTPS) && strtolower($HTTPS) != 'off') ? 'https' : 'http') . '://'
578 . $HTTP_HOST;
580 // if $cfg['PmaAbsoluteUri'] is empty and port == 80 or port == 443, do not add ":80" or ":443"
581 // to the generated URL -> prevents a double password query in case of http authentication.
583 if (!(!$port_in_HTTP_HOST && !empty($SERVER_PORT) && ($SERVER_PORT == 80 || $SERVER_PORT == 443))) {
584 $cfg['PmaAbsoluteUri'] .= ((!empty($SERVER_PORT) && !$port_in_HTTP_HOST) ? ':' . $SERVER_PORT : '');
587 // rabus: if php is in CGI mode, $PHP_SELF often contains the path to the CGI executable.
588 // This is why we try to get the path from $REQUEST_URI or $PATH_INFO first.
589 if (isset($REQUEST_URI)) {
590 $cfg['PmaAbsoluteUri'] .= substr($REQUEST_URI, 0, strrpos($REQUEST_URI, '/') + 1);
591 } else if (isset($PATH_INFO)) {
592 $cfg['PmaAbsoluteUri'] .= substr($PATH_INFO, 0, strrpos($PATH_INFO, '/') + 1);
593 } else {
594 $cfg['PmaAbsoluteUri'] .= substr($PHP_SELF, 0, strrpos($PHP_SELF, '/') + 1);
597 // We display the warning by default, but not if it is disabled thru
598 // via the $cfg['PmaAbsoluteUri_DisableWarning'] variable.
599 // This is intended for sysadmins that actually want the default
600 // behaviour of auto-detection due to their setup.
601 // See the mailing list message:
602 // http://sourceforge.net/mailarchive/forum.php?thread_id=859093&forum_id=2141
603 if ($cfg['PmaAbsoluteUri_DisableWarning'] == FALSE) {
604 $display_pmaAbsoluteUri_warning = 1;
607 // Adds a trailing slash et the end of the phpMyAdmin uri if it does not
608 // exist
609 else if (substr($cfg['PmaAbsoluteUri'], -1) != '/') {
610 $cfg['PmaAbsoluteUri'] .= '/';
615 * Make sure $cfg['DefaultTabDatabase'] and $cfg['DefaultTabTable'] are set.
616 * Todo: check if it is set to a *valid* value.
618 if (empty($cfg['DefaultTabDatabase'])) {
619 $cfg['DefaultTabDatabase'] = 'db_details_structure.php3';
622 if (empty($cfg['DefaultTabTable'])) {
623 $cfg['DefaultTabTable'] = 'tbl_properties_structure.php3';
628 * Use mysql_connect() or mysql_pconnect()?
630 $connect_func = ($cfg['PersistentConnections']) ? 'mysql_pconnect' : 'mysql_connect';
631 $dblist = array();
635 * Gets the valid servers list and parameters
637 reset($cfg['Servers']);
638 while (list($key, $val) = each($cfg['Servers'])) {
639 // Don't use servers with no hostname
640 if ( ($val['connect_type'] == 'tcp') && empty($val['host']) ) {
641 unset($cfg['Servers'][$key]);
644 // Final solution to bug #582890
645 // If we are using a socket connection
646 // and there is nothing in the verbose server name
647 // or the host field, then generate a name for the server
648 // in the form of "Server 2", localized of course!
649 if ( ($val['connect_type'] == 'socket') && empty($val['host']) && empty($val['verbose']) ) {
650 $cfg['Servers'][$key]['verbose'] = sprintf($GLOBALS['strServer'], $key);
651 $val['verbose'] = sprintf($GLOBALS['strServer'],$key);
655 if (empty($server) || !isset($cfg['Servers'][$server]) || !is_array($cfg['Servers'][$server])) {
656 $server = $cfg['ServerDefault'];
661 * If no server is selected, make sure that $cfg['Server'] is empty (so
662 * that nothing will work), and skip server authentication.
663 * We do NOT exit here, but continue on without logging into any server.
664 * This way, the welcome page will still come up (with no server info) and
665 * present a choice of servers in the case that there are multiple servers
666 * and '$cfg['ServerDefault'] = 0' is set.
668 if ($server == 0) {
669 $cfg['Server'] = array();
673 * Otherwise, set up $cfg['Server'] and do the usual login stuff.
675 else if (isset($cfg['Servers'][$server])) {
676 $cfg['Server'] = $cfg['Servers'][$server];
678 // Check how the config says to connect to the server
679 $server_port = (empty($cfg['Server']['port']))
680 ? ''
681 : ':' . $cfg['Server']['port'];
682 if (strtolower($cfg['Server']['connect_type']) == 'tcp') {
683 $cfg['Server']['socket'] = '';
685 $server_socket = (empty($cfg['Server']['socket']) || PMA_PHP_INT_VERSION < 30010)
686 ? ''
687 : ':' . $cfg['Server']['socket'];
688 if (PMA_PHP_INT_VERSION >= 40300) {
689 $client_flags = ($cfg['Server']['compress'] ? MYSQL_CLIENT_COMPRESS : 0);
692 // Gets the authentication library that fits the $cfg['Server'] settings
693 // and run authentication
694 include('./libraries/auth/' . $cfg['Server']['auth_type'] . '.auth.lib.php3');
695 if (!PMA_auth_check()) {
696 PMA_auth();
697 } else {
698 PMA_auth_set_user();
701 // Check IP-based Allow/Deny rules as soon as possible to reject the
702 // user
703 // Based on mod_access in Apache:
704 // http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/aaa/mod_access.c?rev=1.37&content-type=text/vnd.viewcvs-markup
705 // Look at: "static int check_dir_access(request_rec *r)"
706 // Robbat2 - May 10, 2002
707 if (isset($cfg['Server']['AllowDeny']) && $cfg['Server']['AllowDeny']['order']) {
708 include('./libraries/ip_allow_deny.lib.php3');
710 $allowDeny_forbidden = FALSE; // default
711 if ($cfg['Server']['AllowDeny']['order'] == 'allow,deny') {
712 $allowDeny_forbidden = TRUE;
713 if (PMA_allowDeny('allow')) {
714 $allowDeny_forbidden = FALSE;
716 if (PMA_allowDeny('deny')) {
717 $allowDeny_forbidden = TRUE;
719 } else if ($cfg['Server']['AllowDeny']['order'] == 'deny,allow') {
720 if (PMA_allowDeny('deny')) {
721 $allowDeny_forbidden = TRUE;
723 if (PMA_allowDeny('allow')) {
724 $allowDeny_forbidden = FALSE;
726 } else if ($cfg['Server']['AllowDeny']['order'] == 'explicit') {
727 if (PMA_allowDeny('allow')
728 && !PMA_allowDeny('deny')) {
729 $allowDeny_forbidden = FALSE;
730 } else {
731 $allowDeny_forbidden = TRUE;
733 } // end if... else if... else if
735 // Ejects the user if banished
736 if ($allowDeny_forbidden) {
737 PMA_auth_fails();
739 unset($allowDeny_forbidden); //Clean up after you!
740 } // end if
742 // The user can work with only some databases
743 if (isset($cfg['Server']['only_db']) && $cfg['Server']['only_db'] != '') {
744 if (is_array($cfg['Server']['only_db'])) {
745 $dblist = $cfg['Server']['only_db'];
746 } else {
747 $dblist[] = $cfg['Server']['only_db'];
749 } // end if
751 if (PMA_PHP_INT_VERSION >= 40000) {
752 $bkp_track_err = @ini_set('track_errors', 1);
755 // Try to connect MySQL with the control user profile (will be used to
756 // get the privileges list for the current user but the true user link
757 // must be open after this one so it would be default one for all the
758 // scripts)
759 if ($cfg['Server']['controluser'] != '') {
760 if (PMA_PHP_INT_VERSION >= 40300) {
761 $dbh = @$connect_func(
762 $cfg['Server']['host'] . $server_port . $server_socket,
763 $cfg['Server']['controluser'],
764 $cfg['Server']['controlpass'],
765 FALSE,
766 $client_flags
768 } else {
769 $dbh = @$connect_func(
770 $cfg['Server']['host'] . $server_port . $server_socket,
771 $cfg['Server']['controluser'],
772 $cfg['Server']['controlpass']
775 if ($dbh == FALSE) {
776 if (PMA_mysql_error()) {
777 $conn_error = PMA_mysql_error();
778 } else if (isset($php_errormsg)) {
779 $conn_error = $php_errormsg;
780 } else {
781 $conn_error = 'Cannot connect: invalid settings.';
783 $local_query = $connect_func . '('
784 . $cfg['Server']['host'] . $server_port . $server_socket . ', '
785 . $cfg['Server']['controluser'] . ', '
786 . $cfg['Server']['controlpass']
787 . (PMA_PHP_INT_VERSION >= 40300 ? ', FALSE, ' . $client_flags : '')
788 . ')';
789 if (empty($GLOBALS['is_header_sent'])) {
790 include('./header.inc.php3');
792 //PMA_mysqlDie($conn_error, $local_query, FALSE);
793 PMA_mysqlDie($conn_error, '', FALSE);
794 } // end if
795 } // end if
797 // Pass #1 of DB-Config to read in master level DB-Config will go here
798 // Robbat2 - May 11, 2002
800 // Connects to the server (validates user's login)
801 if (PMA_PHP_INT_VERSION >= 40300) {
802 $userlink = @$connect_func(
803 $cfg['Server']['host'] . $server_port . $server_socket,
804 $cfg['Server']['user'],
805 $cfg['Server']['password'],
806 FALSE,
807 $client_flags
809 } else {
810 $userlink = @$connect_func(
811 $cfg['Server']['host'] . $server_port . $server_socket,
812 $cfg['Server']['user'],
813 $cfg['Server']['password']
817 if ($userlink == FALSE) {
818 PMA_auth_fails();
819 } // end if
821 // Pass #2 of DB-Config to read in user level DB-Config will go here
822 // Robbat2 - May 11, 2002
824 if (PMA_PHP_INT_VERSION >= 40000) {
825 @ini_set('track_errors', $bkp_track_err);
828 // If controluser isn't defined, use the current user settings to get
829 // his rights
830 if ($cfg['Server']['controluser'] == '') {
831 $dbh = $userlink;
834 // Runs the "defines.lib.php3" for the second time to get the mysql
835 // release number
836 include('./libraries/defines.lib.php3');
838 // if 'only_db' is set for the current user, there is no need to check for
839 // available databases in the "mysql" db
840 $dblist_cnt = count($dblist);
841 if ($dblist_cnt) {
842 $true_dblist = array();
843 $is_show_dbs = TRUE;
844 for ($i = 0; $i < $dblist_cnt; $i++) {
845 if ($is_show_dbs && ereg('(^|[^\])(_|%)', $dblist[$i])) {
846 $local_query = 'SHOW DATABASES LIKE \'' . $dblist[$i] . '\'';
847 $rs = PMA_mysql_query($local_query, $dbh);
848 // "SHOW DATABASES" statement is disabled
849 if ($i == 0
850 && (PMA_mysql_error() && mysql_errno() == 1045)) {
851 $true_dblist[] = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i]));
852 $is_show_dbs = FALSE;
854 // Debug
855 // else if (PMA_mysql_error()) {
856 // PMA_mysqlDie('', $local_query, FALSE);
857 // }
858 while ($row = @PMA_mysql_fetch_row($rs)) {
859 $true_dblist[] = $row[0];
860 } // end while
861 if ($rs) {
862 mysql_free_result($rs);
864 } else {
865 $true_dblist[] = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i]));
866 } // end if... else...
867 } // end for
868 $dblist = $true_dblist;
869 unset($true_dblist);
870 } // end if
872 // 'only_db' is empty for the current user...
873 else {
874 // ... first checks whether the "safe_show_database" is on or not
875 // (if MYSQL supports this)
876 if (PMA_MYSQL_INT_VERSION >= 32330) {
877 $is_safe_show_dbs = FALSE;
878 if (PMA_MYSQL_INT_VERSION >= 40002) {
879 $is_safe_show_dbs = 'ON';
881 else {
882 $local_query = 'SHOW VARIABLES LIKE \'safe\\_show\\_database\'';
883 $rs = PMA_mysql_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE);
884 $is_safe_show_dbs = ($rs) ? @PMA_mysql_result($rs, 0, 'Value') : FALSE;
885 mysql_free_result($rs);
887 // ... and if on, try to get the available dbs list
888 if ($is_safe_show_dbs && strtoupper($is_safe_show_dbs) != 'OFF') {
889 $uva_alldbs = mysql_list_dbs($userlink);
890 while ($uva_row = PMA_mysql_fetch_array($uva_alldbs)) {
891 $dblist[] = $uva_row[0];
892 } // end while
893 $dblist_cnt = count($dblist);
894 unset($uva_alldbs);
895 } // end if ($is_safe_show_dbs)
896 } //end if (PMA_MYSQL_INT_VERSION)
898 // ... else checks for available databases in the "mysql" db
899 if (!$dblist_cnt) {
900 $auth_query = 'SELECT User, Select_priv '
901 . 'FROM mysql.user '
902 . 'WHERE User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\'';
903 $rs = PMA_mysql_query($auth_query, $dbh); // Debug: or PMA_mysqlDie('', $auth_query, FALSE);
904 } // end
905 } // end if (!$dblist_cnt)
907 // Access to "mysql" db allowed and dblist still empty -> gets the
908 // usable db list
909 if (!$dblist_cnt
910 && ($rs && @mysql_numrows($rs))) {
911 $row = PMA_mysql_fetch_array($rs);
912 mysql_free_result($rs);
913 // Correction uva 19991215
914 // Previous code assumed database "mysql" admin table "db" column
915 // "db" contains literal name of user database, and works if so.
916 // Mysql usage generally (and uva usage specifically) allows this
917 // column to contain regular expressions (we have all databases
918 // owned by a given student/faculty/staff beginning with user i.d.
919 // and governed by default by a single set of privileges with
920 // regular expression as key). This breaks previous code.
921 // This maintenance is to fix code to work correctly for regular
922 // expressions.
923 if ($row['Select_priv'] != 'Y') {
925 // 1. get allowed dbs from the "mysql.db" table
926 // lem9: User can be blank (anonymous user)
927 $local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE Select_priv = \'Y\' AND (User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\' OR User = \'\')';
928 $rs = PMA_mysql_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE);
929 if ($rs && @mysql_numrows($rs)) {
930 // Will use as associative array of the following 2 code
931 // lines:
932 // the 1st is the only line intact from before
933 // correction,
934 // the 2nd replaces $dblist[] = $row['Db'];
935 $uva_mydbs = array();
936 // Code following those 2 lines in correction continues
937 // populating $dblist[], as previous code did. But it is
938 // now populated with actual database names instead of
939 // with regular expressions.
940 while ($row = PMA_mysql_fetch_array($rs)) {
941 // loic1: all databases cases - part 1
942 if (empty($row['Db']) || $row['Db'] == '%') {
943 $uva_mydbs['%'] = 1;
944 break;
946 // loic1: avoid multiple entries for dbs
947 if (!isset($uva_mydbs[$row['Db']])) {
948 $uva_mydbs[$row['Db']] = 1;
950 } // end while
951 mysql_free_result($rs);
952 $uva_alldbs = mysql_list_dbs($dbh);
953 // loic1: all databases cases - part 2
954 if (isset($uva_mydbs['%'])) {
955 while ($uva_row = PMA_mysql_fetch_array($uva_alldbs)) {
956 $dblist[] = $uva_row[0];
957 } // end while
958 } // end if
959 else {
960 while ($uva_row = PMA_mysql_fetch_array($uva_alldbs)) {
961 $uva_db = $uva_row[0];
962 if (isset($uva_mydbs[$uva_db]) && $uva_mydbs[$uva_db] == 1) {
963 $dblist[] = $uva_db;
964 $uva_mydbs[$uva_db] = 0;
965 } else if (!isset($dblist[$uva_db])) {
966 reset($uva_mydbs);
967 while (list($uva_matchpattern, $uva_value) = each($uva_mydbs)) {
968 // loic1: fixed bad regexp
969 // TODO: db names may contain characters
970 // that are regexp instructions
971 $re = '(^|(\\\\\\\\)+|[^\])';
972 $uva_regex = ereg_replace($re . '%', '\\1.*', ereg_replace($re . '_', '\\1.{1}', $uva_matchpattern));
973 // Fixed db name matching
974 // 2000-08-28 -- Benjamin Gandon
975 if (ereg('^' . $uva_regex . '$', $uva_db)) {
976 $dblist[] = $uva_db;
977 break;
979 } // end while
980 } // end if ... else if....
981 } // end while
982 } // end else
983 mysql_free_result($uva_alldbs);
984 unset($uva_mydbs);
985 } // end if
987 // 2. get allowed dbs from the "mysql.tables_priv" table
988 $local_query = 'SELECT DISTINCT Db FROM mysql.tables_priv WHERE Table_priv LIKE \'%Select%\' AND User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\'';
989 $rs = PMA_mysql_query($local_query, $dbh); // Debug: or PMA_mysqlDie('', $local_query, FALSE);
990 if ($rs && @mysql_numrows($rs)) {
991 while ($row = PMA_mysql_fetch_array($rs)) {
992 if (PMA_isInto($row['Db'], $dblist) == -1) {
993 $dblist[] = $row['Db'];
995 } // end while
996 mysql_free_result($rs);
997 } // end if
998 } // end if
999 } // end building available dbs from the "mysql" db
1001 } // end server connecting
1003 * Missing server hostname
1005 else {
1006 echo $strHostEmpty;
1011 * Get the list and number of available databases.
1013 * @param string the url to go back to in case of error
1015 * @return boolean always true
1017 * @global array the list of available databases
1018 * @global integer the number of available databases
1020 function PMA_availableDatabases($error_url = '')
1022 global $dblist;
1023 global $num_dbs;
1025 $num_dbs = count($dblist);
1027 // 1. A list of allowed databases has already been defined by the
1028 // authentification process -> gets the available databases list
1029 if ($num_dbs) {
1030 $true_dblist = array();
1031 for ($i = 0; $i < $num_dbs; $i++) {
1032 $dblink = @PMA_mysql_select_db($dblist[$i]);
1033 if ($dblink) {
1034 $true_dblist[] = $dblist[$i];
1035 } // end if
1036 } // end for
1037 $dblist = array();
1038 $dblist = $true_dblist;
1039 unset($true_dblist);
1040 $num_dbs = count($dblist);
1041 } // end if
1043 // 2. Allowed database list is empty -> gets the list of all databases
1044 // on the server
1045 else {
1046 $dbs = mysql_list_dbs() or PMA_mysqlDie('', 'SHOW DATABASES;', FALSE, $error_url);
1047 $num_dbs = ($dbs) ? @mysql_num_rows($dbs) : 0;
1048 $real_num_dbs = 0;
1049 for ($i = 0; $i < $num_dbs; $i++) {
1050 $db_name_tmp = PMA_mysql_dbname($dbs, $i);
1051 $dblink = @PMA_mysql_select_db($db_name_tmp);
1052 if ($dblink) {
1053 $dblist[] = $db_name_tmp;
1054 $real_num_dbs++;
1056 } // end for
1057 mysql_free_result($dbs);
1058 $num_dbs = $real_num_dbs;
1059 } // end else
1061 return TRUE;
1062 } // end of the 'PMA_availableDatabases()' function
1066 /* ----------------------- Set of misc functions ----------------------- */
1070 * Adds backquotes on both sides of a database, table or field name.
1071 * Since MySQL 3.23.6 this allows to use non-alphanumeric characters in
1072 * these names.
1074 * @param mixed the database, table or field name to "backquote" or
1075 * array of it
1076 * @param boolean a flag to bypass this function (used by dump
1077 * functions)
1079 * @return mixed the "backquoted" database, table or field name if the
1080 * current MySQL release is >= 3.23.6, the original one
1081 * else
1083 * @access public
1085 function PMA_backquote($a_name, $do_it = TRUE)
1087 if ($do_it
1088 && PMA_MYSQL_INT_VERSION >= 32306
1089 && !empty($a_name) && $a_name != '*') {
1091 if (is_array($a_name)) {
1092 $result = array();
1093 reset($a_name);
1094 while(list($key, $val) = each($a_name)) {
1095 $result[$key] = '`' . $val . '`';
1097 return $result;
1098 } else {
1099 return '`' . $a_name . '`';
1101 } else {
1102 return $a_name;
1104 } // end of the 'PMA_backquote()' function
1108 * Format a string so it can be passed to a javascript function.
1109 * This function is used to displays a javascript confirmation box for
1110 * "DROP/DELETE/ALTER" queries.
1112 * @param string the string to format
1113 * @param boolean whether to add backquotes to the string or not
1115 * @return string the formated string
1117 * @access public
1119 function PMA_jsFormat($a_string = '', $add_backquotes = TRUE)
1121 if (is_string($a_string)) {
1122 $a_string = str_replace('"', '&quot;', $a_string);
1123 $a_string = str_replace('\\', '\\\\', $a_string);
1124 $a_string = str_replace('\'', '\\\'', $a_string);
1125 $a_string = str_replace('#', '\\#', $a_string);
1126 $a_string = str_replace("\012", '\\\\n', $a_string);
1127 $a_string = str_replace("\015", '\\\\r', $a_string);
1130 return (($add_backquotes) ? PMA_backquote($a_string) : $a_string);
1131 } // end of the 'PMA_jsFormat()' function
1135 * Defines the <CR><LF> value depending on the user OS.
1137 * @return string the <CR><LF> value to use
1139 * @access public
1141 function PMA_whichCrlf()
1143 $the_crlf = "\n";
1145 // The 'PMA_USR_OS' constant is defined in "./libraries/defines.lib.php3"
1146 // Win case
1147 if (PMA_USR_OS == 'Win') {
1148 $the_crlf = "\r\n";
1150 // Mac case
1151 else if (PMA_USR_OS == 'Mac') {
1152 $the_crlf = "\r";
1154 // Others
1155 else {
1156 $the_crlf = "\n";
1159 return $the_crlf;
1160 } // end of the 'PMA_whichCrlf()' function
1164 * Counts and displays the number of records in a table
1166 * Last revision 13 July 2001: Patch for limiting dump size from
1167 * vinay@sanisoft.com & girish@sanisoft.com
1169 * @param string the current database name
1170 * @param string the current table name
1171 * @param boolean whether to retain or to displays the result
1173 * @return mixed the number of records if retain is required, true else
1175 * @access public
1177 function PMA_countRecords($db, $table, $ret = FALSE)
1179 $result = PMA_mysql_query('SELECT COUNT(*) AS num FROM ' . PMA_backquote($db) . '.' . PMA_backquote($table));
1180 $num = ($result) ? PMA_mysql_result($result, 0, 'num') : 0;
1181 mysql_free_result($result);
1182 if ($ret) {
1183 return $num;
1184 } else {
1185 echo number_format($num, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
1186 return TRUE;
1188 } // end of the 'PMA_countRecords()' function
1192 * Displays a message at the top of the "main" (right) frame
1194 * @param string the message to display
1196 * @global array the configuration array
1198 * @access public
1200 function PMA_showMessage($message)
1202 global $cfg;
1204 // Reloads the navigation frame via JavaScript if required
1205 if (isset($GLOBALS['reload']) && $GLOBALS['reload']) {
1206 echo "\n";
1207 $reload_url = './left.php3?' . PMA_generate_common_url((isset($GLOBALS['db']) ? $GLOBALS['db'] : ''), '', '&');
1209 <script type="text/javascript" language="javascript1.2">
1210 <!--
1211 if (typeof(window.parent) != 'undefined'
1212 && typeof(window.parent.frames['nav']) != 'undefined') {
1213 window.parent.frames['nav'].location.replace('<?php echo $reload_url; ?>');
1215 //-->
1216 </script>
1217 <?php
1218 unset($GLOBALS['reload']);
1221 // Corrects the tooltip text via JS if required
1222 else if (!empty($GLOBALS['table']) && $cfg['ShowTooltip'] && PMA_MYSQL_INT_VERSION >= 32303) {
1223 $result = @PMA_mysql_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], TRUE) . '\'');
1224 if ($result) {
1225 $tbl_status = PMA_mysql_fetch_array($result, MYSQL_ASSOC);
1226 $tooltip = (empty($tbl_status['Comment']))
1227 ? ''
1228 : $tbl_status['Comment'] . ' ';
1229 $tooltip .= '(' . $tbl_status['Rows'] . ' ' . $GLOBALS['strRows'] . ')';
1230 mysql_free_result($result);
1231 $md5_tbl = md5($GLOBALS['table']);
1232 echo "\n";
1234 <script type="text/javascript" language="javascript1.2">
1235 <!--
1236 if (typeof(document.getElementById) != 'undefined'
1237 && typeof(window.parent.frames['nav']) != 'undefined'
1238 && typeof(window.parent.frames['nav'].document) != 'undefined' && typeof(window.parent.frames['nav'].document) != 'unknown'
1239 && typeof(window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>')) != 'undefined'
1240 && typeof(window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>').title) == 'string') {
1241 window.parent.frames['nav'].document.getElementById('<?php echo 'tbl_' . $md5_tbl; ?>').title = '<?php echo PMA_jsFormat($tooltip, FALSE); ?>';
1243 //-->
1244 </script>
1245 <?php
1246 } // end if
1247 } // end if... else if
1249 // Checks if the table needs to be repaired after a TRUNCATE query.
1250 if (PMA_MYSQL_INT_VERSION >= 40000
1251 && isset($GLOBALS['table']) && isset($GLOBALS['sql_query'])
1252 && $GLOBALS['sql_query'] == 'TRUNCATE TABLE ' . PMA_backquote($GLOBALS['table'])) {
1253 if (!isset($tbl_status)) {
1254 $result = @PMA_mysql_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], TRUE) . '\'');
1255 if ($result) {
1256 $tbl_status = PMA_mysql_fetch_array($result, MYSQL_ASSOC);
1257 mysql_free_result($result);
1260 if (isset($tbl_status) && (int) $tbl_status['Index_length'] > 1024) {
1261 @PMA_mysql_query('REPAIR TABLE ' . PMA_backquote($GLOBALS['table']));
1264 unset($tbl_status);
1266 echo "\n";
1268 <div align="<?php echo $GLOBALS['cell_align_left']; ?>">
1269 <table border="<?php echo $cfg['Border']; ?>" cellpadding="5">
1270 <tr>
1271 <td bgcolor="<?php echo $cfg['ThBgcolor']; ?>">
1272 <b><?php echo $message; ?></b><br />
1273 </td>
1274 </tr>
1275 <?php
1276 if ($cfg['ShowSQL'] == TRUE && !empty($GLOBALS['sql_query'])) {
1277 // Basic url query part
1278 $url_qpart = '?' . PMA_generate_common_url(isset($GLOBALS['db']) ? $GLOBALS['db'] : '', isset($GLOBALS['table']) ? $GLOBALS['table'] : '');
1279 echo "\n";
1281 <tr>
1282 <td bgcolor="<?php echo $cfg['BgcolorOne']; ?>">
1283 <?php
1284 echo "\n";
1285 // Html format the query to be displayed
1286 // The nl2br function isn't used because its result isn't a valid
1287 // xhtml1.0 statement before php4.0.5 ("<br>" and not "<br />")
1288 // If we want to show some sql code it is easiest to create it here
1289 /* SQL-Parser-Analyzer */
1290 $sqlnr = 1;
1291 if (!empty($GLOBALS['show_as_php'])) {
1292 $new_line = '\';<br />' . "\n" . ' $sql .= \'';
1294 if (isset($new_line)) {
1295 /* SQL-Parser-Analyzer */
1296 $query_base = htmlspecialchars($GLOBALS['sql_query']);
1297 /* SQL-Parser-Analyzer */
1298 $query_base = ereg_replace("((\015\012)|(\015)|(\012))+", $new_line, $query_base);
1299 } else {
1300 $query_base = $GLOBALS['sql_query'];
1302 if (!empty($GLOBALS['show_as_php'])) {
1303 $query_base = '$sql = \'' . PMA_sqlAddslashes($query_base);
1304 } else if (!empty($GLOBALS['validatequery'])) {
1305 $query_base = PMA_validateSQL($query_base);
1306 } else {
1307 $parsed_sql = PMA_SQP_parse($query_base);
1308 $query_base = PMA_formatSql($parsed_sql);
1311 // Prepares links that may be displayed to edit/explain the query
1312 // (don't go to default pages, we must go to the page
1313 // where the query box is available)
1314 // (also, I don't see why we should check the goto variable)
1316 //if (!isset($GLOBALS['goto'])) {
1317 //$edit_target = (isset($GLOBALS['table'])) ? $cfg['DefaultTabTable'] : $cfg['DefaultTabDatabase'];
1318 $edit_target = isset($GLOBALS['db']) ? (isset($GLOBALS['table']) ? 'tbl_properties.php3' : 'db_details.php3') : '';
1319 //} else if ($GLOBALS['goto'] != 'main.php3') {
1320 // $edit_target = $GLOBALS['goto'];
1321 //} else {
1322 // $edit_target = '';
1325 if (isset($cfg['SQLQuery']['Edit'])
1326 && ($cfg['SQLQuery']['Edit'] == TRUE )
1327 && (!empty($edit_target))) {
1329 $onclick = '';
1330 if ($cfg['QueryFrameJS'] && $cfg['QueryFrame']) {
1331 $onclick = 'onclick="focus_querywindow(); return false;"';
1334 $edit_link = '&nbsp;[<a href="'
1335 . $edit_target
1336 . $url_qpart
1337 . '&amp;sql_query=' . urlencode($GLOBALS['sql_query']) . '&amp;show_query=1#querybox" ' . $onclick . '>' . $GLOBALS['strEdit'] . '</a>]';
1338 } else {
1339 $edit_link = '';
1342 // Want to have the query explained (Mike Beck 2002-05-22)
1343 // but only explain a SELECT (that has not been explained)
1344 /* SQL-Parser-Analyzer */
1345 if (isset($cfg['SQLQuery']['Explain'])
1346 && $cfg['SQLQuery']['Explain'] == TRUE) {
1348 // Detect if we are validating as well
1349 // To preserve the validate uRL data
1350 if (!empty($GLOBALS['validatequery'])) {
1351 $explain_link_validate = '&amp;validatequery=1';
1352 } else {
1353 $explain_link_validate = '';
1356 $explain_link = '&nbsp;[<a href="sql.php3'
1357 . $url_qpart
1358 . $explain_link_validate
1359 . '&amp;sql_query=';
1361 if (eregi('^SELECT[[:space:]]+', $GLOBALS['sql_query'])) {
1362 $explain_link .= urlencode('EXPLAIN ' . $GLOBALS['sql_query']) . '">' . $GLOBALS['strExplain'];
1363 } else if (eregi('^EXPLAIN[[:space:]]+SELECT[[:space:]]+', $GLOBALS['sql_query'])) {
1364 $explain_link .= substr($GLOBALS['sql_query'], 8) . '">' . $GLOBALS['strNoExplain'];
1365 } else {
1366 $explain_link = '';
1368 if(!empty($explain_link)) {
1369 $explain_link .= '</a>]';
1371 } else {
1372 $explain_link = '';
1373 } //show explain
1375 // Also we would like to get the SQL formed in some nice
1376 // php-code (Mike Beck 2002-05-22)
1377 if (isset($cfg['SQLQuery']['ShowAsPHP'])
1378 && $cfg['SQLQuery']['ShowAsPHP'] == TRUE) {
1379 $php_link = '&nbsp;[<a href="sql.php3'
1380 . $url_qpart
1381 . '&amp;show_query=1'
1382 . '&amp;sql_query=' . urlencode($GLOBALS['sql_query'])
1383 . '&amp;show_as_php=';
1385 if (!empty($GLOBALS['show_as_php'])) {
1386 $php_link .= '0">' . $GLOBALS['strNoPhp'];
1387 } else {
1388 $php_link .= '1">' . $GLOBALS['strPhp'];
1390 $php_link .= '</a>]';
1391 } else {
1392 $php_link = '';
1393 } //show as php
1395 if (isset($cfg['SQLValidator']['use'])
1396 && $cfg['SQLValidator']['use'] == TRUE
1397 && isset($cfg['SQLQuery']['Validate'])
1398 && $cfg['SQLQuery']['Validate'] == TRUE) {
1399 $validate_link = '&nbsp;[<a href="sql.php3'
1400 . $url_qpart
1401 . '&amp;show_query=1'
1402 . '&amp;sql_query=' . urlencode($GLOBALS['sql_query'])
1403 . '&amp;validatequery=';
1404 if (!empty($GLOBALS['validatequery'])) {
1405 $validate_link .= '0">' . $GLOBALS['strNoValidateSQL'] ;
1406 } else {
1407 $validate_link .= '1">'. $GLOBALS['strValidateSQL'] ;
1409 $validate_link .= '</a>]';
1410 } else {
1411 $validate_link = '';
1412 } //validator
1414 // Displays the message
1415 echo ' ' . $GLOBALS['strSQLQuery'] . '&nbsp;:';
1416 if (!empty($edit_target)) {
1417 echo $edit_link . $explain_link . $php_link . $validate_link;
1419 echo '<br />' . "\n";
1420 echo ' ' . $query_base;
1421 // If a 'LIMIT' clause has been programatically added to the query
1422 // displays it
1423 if (!empty($GLOBALS['sql_limit_to_append'])) {
1424 if (!empty($GLOBALS['show_as_php'])) {
1425 echo $GLOBALS['sql_limit_to_append'];
1426 } else if (!empty($GLOBALS['validatequery'])) {
1427 // skip the extra bit here
1428 } else {
1429 echo '&nbsp;' . PMA_formatSql(PMA_SQP_parse($GLOBALS['sql_limit_to_append']));
1433 //Clean up the end of the PHP
1434 if (!empty($GLOBALS['show_as_php'])) {
1435 echo '\';';
1437 echo "\n";
1439 </td>
1440 </tr>
1441 <?php
1443 echo "\n";
1445 </table>
1446 </div><br />
1447 <?php
1448 } // end of the 'PMA_showMessage()' function
1452 * Displays a link to the official MySQL documentation
1454 * @param chapter of "HTML, one page per chapter" documentation
1455 * @param contains name of page/anchor that is being linked
1457 * @return string the html link
1459 * @access public
1461 function PMA_showMySQLDocu($chapter, $link)
1463 if (!empty($GLOBALS['cfg']['MySQLManualBase'])) {
1464 if (!empty($GLOBALS['cfg']['MySQLManualType'])) {
1465 switch ($GLOBALS['cfg']['MySQLManualType']) {
1466 case 'old':
1467 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
1468 case 'chapters':
1469 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/manual_' . $chapter . '.html#' . $link . '" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
1470 case 'big':
1471 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '#' . $link . '" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
1472 case 'none':
1473 return '';
1474 case 'searchable':
1475 default:
1476 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
1478 } else {
1479 // no Type defined, show the old one
1480 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
1482 } else {
1483 // no URL defined
1484 if (!empty($GLOBALS['cfg']['ManualBaseShort'])) {
1485 // the old configuration
1486 return '[<a href="' . $GLOBALS['cfg']['MySQLManualBase'] . '/' . $link[0] . '/' . $link[1] . '/' . $link . '.html" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
1487 } else {
1488 return '';
1491 } // end of the 'PMA_showDocuShort()' function
1495 * Formats $value to byte view
1497 * @param double the value to format
1498 * @param integer the sensitiveness
1499 * @param integer the number of decimals to retain
1501 * @return array the formatted value and its unit
1503 * @access public
1505 * @author staybyte
1506 * @version 1.2 - 18 July 2002
1508 function PMA_formatByteDown($value, $limes = 6, $comma = 0)
1510 $dh = pow(10, $comma);
1511 $li = pow(10, $limes);
1512 $return_value = $value;
1513 $unit = $GLOBALS['byteUnits'][0];
1515 for ( $d = 6, $ex = 15; $d >= 1; $d--, $ex-=3 ) {
1516 if (isset($GLOBALS['byteUnits'][$d]) && $value >= $li * pow(10, $ex)) {
1517 $value = round($value / ( pow(1024, $d) / $dh) ) /$dh;
1518 $unit = $GLOBALS['byteUnits'][$d];
1519 break 1;
1520 } // end if
1521 } // end for
1523 if ($unit != $GLOBALS['byteUnits'][0]) {
1524 $return_value = number_format($value, $comma, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
1525 } else {
1526 $return_value = number_format($value, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
1529 return array($return_value, $unit);
1530 } // end of the 'PMA_formatByteDown' function
1534 * Ensures a database/table/field's name is not a reserved word (for MySQL
1535 * releases < 3.23.6)
1537 * @param string the name to check
1538 * @param string the url to go back in case of error
1540 * @return boolean true if the name is valid (no return else)
1542 * @access public
1544 * @author Dell'Aiera Pol; Olivier Blin
1546 function PMA_checkReservedWords($the_name, $error_url)
1548 // The name contains caracters <> a-z, A-Z and "_" -> not a reserved
1549 // word
1550 if (!ereg('^[a-zA-Z_]+$', $the_name)) {
1551 return TRUE;
1554 // Else do the work
1555 $filename = 'badwords.txt';
1556 if (file_exists($filename)) {
1557 // Builds the reserved words array
1558 $fd = fopen($filename, 'r');
1559 $contents = fread($fd, filesize($filename) - 1);
1560 fclose ($fd);
1561 $word_list = explode("\n", $contents);
1563 // Do the checking
1564 $word_cnt = count($word_list);
1565 for ($i = 0; $i < $word_cnt; $i++) {
1566 if (strtolower($the_name) == $word_list[$i]) {
1567 PMA_mysqlDie(sprintf($GLOBALS['strInvalidName'], $the_name), '', FALSE, $error_url);
1568 } // end if
1569 } // end for
1570 } // end if
1571 } // end of the 'PMA_checkReservedWords' function
1575 * Writes localised date
1577 * @param string the current timestamp
1579 * @return string the formatted date
1581 * @access public
1583 function PMA_localisedDate($timestamp = -1)
1585 global $datefmt, $month, $day_of_week;
1587 if ($timestamp == -1) {
1588 $timestamp = time();
1591 $date = ereg_replace('%[aA]', $day_of_week[(int)strftime('%w', $timestamp)], $datefmt);
1592 $date = ereg_replace('%[bB]', $month[(int)strftime('%m', $timestamp)-1], $date);
1594 return strftime($date, $timestamp);
1595 } // end of the 'PMA_localisedDate()' function
1599 * Prints out a tab for tabbed navigation.
1600 * If the variables $link and $args ar left empty, an inactive tab is created
1602 * @param string the text to be displayed as link
1603 * @param string main link file, e.g. "test.php3"
1604 * @param string link arguments
1605 * @param string link attributes
1606 * @param string include '?' even though no attributes are set. Can be set empty, should be '?'.
1607 * @param boolean force display TAB as active
1609 * @return string two table cells, the first beeing a separator, the second the tab itself
1611 * @access public
1613 function PMA_printTab($text, $link, $args = '', $attr = '', $sep = '?', $active = false) {
1614 global $PHP_SELF, $cfg;
1615 global $db_details_links_count_tabs;
1617 if ((basename($PHP_SELF) == $link || $active)
1618 && ($text != $GLOBALS['strEmpty'] && $text != $GLOBALS['strDrop'])) {
1619 $bgcolor = 'silver';
1620 } else {
1621 $bgcolor = '#DFDFDF';
1624 $db_details_links_count_tabs++;
1625 if (!empty($attr)) {
1626 $attr = ' ' . $attr;
1629 if ($cfg['LightTabs']) {
1630 $out = '';
1631 if (strlen($link) > 0) {
1632 $out .= '<a href="' . $link . $sep . $args . '"' . $attr . '>'
1633 . '<nobr><b>' . $text . '</b></a></nobr>';
1634 } else {
1635 $out .= '<nobr><b>' . $text . '</b></nobr>';
1637 $out = '[ ' . $out . ' ]&nbsp;&nbsp;&nbsp;';
1638 } else {
1639 $out = "\n" . ' '
1640 . '<td bgcolor="' . $bgcolor . '" align="center" width="64" nowrap="nowrap" class="tab">'
1641 . "\n" . ' ';
1642 if (strlen($link) > 0) {
1643 $out .= '<a href="' . $link . $sep . $args . '"' . $attr . '>'
1644 . '<nobr><b>' . $text . '</b></a></nobr>';
1645 } else {
1646 $out .= '<nobr><b>' . $text . '</b></nobr>';
1648 $out .= "\n" . ' '
1649 . '</td>'
1650 . "\n" . ' '
1651 . '<td width="8">&nbsp;</td>';
1654 return $out;
1655 } // end of the 'PMA_printTab()' function
1659 * Displays a link, or a button if the link's URL is too large, to
1660 * accommodate some browsers' limitations
1662 * @param string the URL
1663 * @param string the link message
1664 * @param string js confirmation
1666 * @return string the results to be echoed or saved in an array
1668 function PMA_linkOrButton($url, $message, $js_conf)
1670 if (strlen($url) <= 2047) {
1671 $onclick_url = (empty($js_conf) ? '' : ' onclick="return confirmLink(this, \'' . $js_conf . '\')"');
1672 $link_or_button = ' <a href="' . $url . '"' . $onclick_url . '>' . "\n"
1673 . ' ' . $message . '</a>' . "\n";
1675 else {
1676 $edit_url_parts = parse_url($url);
1677 $query_parts = explode('&', $edit_url_parts['query']);
1678 $link_or_button = ' <form action="'
1679 . $edit_url_parts['path']
1680 . '" method="post">' . "\n";
1681 reset ($query_parts);
1682 while (list(, $query_pair) = each($query_parts)) {
1683 list($eachvar, $eachval) = explode('=', $query_pair);
1684 $link_or_button .= ' <input type="hidden" name="' . str_replace('amp;', '', $eachvar) . '" value="' . htmlspecialchars(urldecode($eachval)) . '" />' . "\n";
1685 } // end while
1686 $link_or_button .= ' <input type="submit" value="'
1687 . htmlspecialchars($message) . '" />' . "\n" . '</form>' . "\n";
1688 } // end if... else...
1690 return $link_or_button;
1691 } // end of the 'PMA_linkOrButton()' function
1695 * Returns a given timespan value in a readable format.
1697 * @param int the timespan
1699 * @return string the formatted value
1701 function PMA_timespanFormat($seconds)
1703 $return_string = '';
1704 $days = floor($seconds / 86400);
1705 if ($days > 0) {
1706 $seconds -= $days * 86400;
1708 $hours = floor($seconds / 3600);
1709 if ($days > 0 || $hours > 0) {
1710 $seconds -= $hours * 3600;
1712 $minutes = floor($seconds / 60);
1713 if ($days > 0 || $hours > 0 || $minutes > 0) {
1714 $seconds -= $minutes * 60;
1716 return sprintf($GLOBALS['timespanfmt'], (string)$days, (string)$hours, (string)$minutes, (string)$seconds);
1720 if (!function_exists('in_array')) {
1722 * Searches $haystack for $needle and returns TRUE if it is found in
1723 * the array, FALSE otherwise.
1725 * @param mixed the 'needle'
1726 * @param array the 'haystack'
1728 * @return boolean has $needle been found or not?
1730 function in_array($needle, $haystack) {
1731 while (list(, $value) = each($haystack)) {
1732 if ($value == $haystack) {
1733 return TRUE;
1736 return FALSE;
1741 * Takes a string and outputs each character on a line for itself. Used mainly for horizontalflipped display mode.
1742 * Takes care of special html-characters.
1743 * Fulfills todo-item http://sourceforge.net/tracker/index.php?func=detail&aid=544361&group_id=23067&atid=377411
1745 * @param string The string
1746 * @param string The seperator (defaults to "<br />\n")
1748 * @access public
1749 * @author Garvin Hicking <me@supergarv.de>
1750 * @return string The flipped string
1752 function PMA_flipstring($string, $seperator = "<br />\n") {
1753 $format_string = '';
1754 $charbuff = false;
1756 for ($i = 0; $i <= strlen($string); $i++) {
1757 $char = substr($string, $i, 1);
1758 $append = false;
1760 if ($char == '&') {
1761 $format_string .= $charbuff;
1762 $charbuff = $char;
1763 $append = true;
1764 } elseif (!empty($charbuff)) {
1765 $charbuff .= $char;
1766 } elseif ($char == ';' && !empty($charbuff)) {
1767 $format_string .= $charbuff;
1768 $charbuff = false;
1769 $append = true;
1771 else
1773 $format_string .= $char;
1774 $append = true;
1777 if ($append && ($i != strlen($string))) {
1778 $format_string .= $seperator;
1782 return $format_string;
1785 // Kanji encoding convert feature appended by Y.Kawada (2002/2/20)
1786 if (PMA_PHP_INT_VERSION >= 40006
1787 && @function_exists('mb_convert_encoding')
1788 && strpos(' ' . $lang, 'ja-')
1789 && file_exists('./libraries/kanji-encoding.lib.php3')) {
1790 include('./libraries/kanji-encoding.lib.php3');
1791 define('PMA_MULTIBYTE_ENCODING', 1);
1792 } // end if
1794 // garvin: moved from read_dump.php3 because this should be used in tbl_replace_fields.php3 as well.
1795 if (!function_exists('is_uploaded_file')) {
1797 * Emulates the 'is_uploaded_file()' function for old php versions.
1798 * Grabbed at the php manual:
1799 * http://www.php.net/manual/en/features.file-upload.php
1801 * @param string the name of the file to check
1803 * @return boolean wether the file has been uploaded or not
1805 * @access public
1807 function is_uploaded_file($filename) {
1808 if (!$tmp_file = @get_cfg_var('upload_tmp_dir')) {
1809 $tmp_file = tempnam('','');
1810 $deleted = @unlink($tmp_file);
1811 $tmp_file = dirname($tmp_file);
1813 $tmp_file .= '/' . basename($filename);
1815 // User might have trailing slash in php.ini...
1816 return (ereg_replace('/+', '/', $tmp_file) == $filename);
1817 } // end of the 'is_uploaded_file()' emulated function
1818 } // end if
1820 } // $__PMA_COMMON_LIB__