3 // vim: expandtab sw=4 ts=4 sts=4:
6 * Misc stuff and functions used by almost all the scripts.
7 * Among other things, it contains the advanced authentication work.
11 * Order of sections for common.lib.php:
13 * the include of libraries/defines_mysql.lib.php must be after the connection
14 * to db to get the MySql version
16 * the authentication libraries must be before the connection to db
18 * ... so the required order is:
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
31 * - load of mysql extension (if necessary) label_loading_mysql
32 * - loading of an authentication library label_
34 * - authentication work
35 * - load of the libraries/defines_mysql.lib.php library to get the MySQL
40 * For now, avoid warnings of E_STRICT mode
41 * (this must be done before function definitions)
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
);
49 error_reporting($old_error_reporting);
51 unset($old_error_reporting);
55 * Avoid object cloning errors
58 @ini_set
('zend.ze1_compatibility_mode',false);
61 /******************************************************************************/
62 /* definition of functions LABEL_definition_of_functions */
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.
68 * @param string The path to check
70 * @return string The secured path
73 * @author Marc Delisle (lem9@users.sourceforge.net)
75 function PMA_securePath($path)
78 $path = preg_replace('@\.\.*@', '.', $path);
84 * returns array with dbs grouped with extended infos
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()
101 * @return array db list
103 function PMA_getDbList()
105 if (empty($GLOBALS['dblist'])) {
106 PMA_availableDatabases();
108 $dblist = $GLOBALS['dblist'];
111 foreach ($dblist as $key => $db) {
112 // garvin: Get comments from PMA comments table
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);
122 if ($GLOBALS['cfg']['LeftFrameDBTree']
123 && $GLOBALS['cfg']['LeftFrameDBSeparator']
124 && strstr($db, $GLOBALS['cfg']['LeftFrameDBSeparator']))
126 // use strpos instead of strrpos; it seems more common to
127 // have the db name, the separator, then the rest which
128 // might contain a separator
129 // like dbname_the_rest
130 $pos = strpos($db, $GLOBALS['cfg']['LeftFrameDBSeparator']);
131 $group = substr($db, 0, $pos);
132 $disp_name_cut = substr($db, $pos);
135 $disp_name_cut = $db;
139 if ($db_tooltip && $GLOBALS['cfg']['ShowTooltipAliasDB']) {
140 $disp_name = $db_tooltip;
141 $disp_name_cut = $db_tooltip;
145 $dbgroups[$group][$db] = array(
147 'disp_name_cut' => $disp_name_cut,
148 'disp_name' => $disp_name,
149 'comment' => $db_tooltip,
150 'num_tables' => PMA_getTableCount($db),
152 } // end foreach ($dblist as $db)
157 * returns html code for select form element with dbs
159 * @return string html code select
161 function PMA_getHtmlSelectDb($selected = '')
163 $dblist = PMA_getDbList();
164 // TODO: IE can not handle different text directions in select boxes
165 // so, as mostly names will be in english, we set the whole selectbox to LTR
167 $return = '<select name="db" id="lightm_db" xml:lang="en" dir="ltr"'
168 .' onchange="if (this.value != \'\') window.parent.openDb(this.value);">' . "\n"
169 .'<option value="" dir="' . $GLOBALS['text_dir'] . '">(' . $GLOBALS['strDatabases'] . ') ...</option>'
171 foreach ($dblist as $group => $dbs) {
172 if (count($dbs) > 1) {
173 $return .= '<optgroup label="' . htmlspecialchars($group)
175 // wether display db_name cuted by the group part
181 foreach ($dbs as $db) {
182 $return .= '<option value="' . $db['name'] . '"'
183 .' title="' . htmlspecialchars($db['comment']) . '"';
184 if ($db['name'] == $selected) {
185 $return .= ' selected="selected"';
187 $return .= '>' . htmlspecialchars($cut ?
$db['disp_name_cut'] : $db['disp_name'])
188 .' (' . $db['num_tables'] . ')</option>' . "\n";
190 if (count($dbs) > 1) {
191 $return .= '</optgroup>' . "\n";
194 $return .= '</select>';
200 * returns count of tables in given db
202 * @param string $db database to count tables for
203 * @return integer count of tables in $db
205 function PMA_getTableCount($db)
207 $tables = PMA_DBI_try_query(
208 'SHOW TABLES FROM ' . PMA_backquote($db) . ';',
209 null, PMA_DBI_QUERY_STORE
);
211 $num_tables = PMA_DBI_num_rows($tables);
212 PMA_DBI_free_result($tables);
222 * Get the complete list of Databases a user can access
224 * @param boolean whether to include check on failed 'only_db' operations
225 * @param resource database handle (superuser)
226 * @param integer amount of databases inside the 'only_db' container
227 * @param resource possible resource from a failed previous query
228 * @param resource database handle (user)
229 * @param array configuration
230 * @param array previous list of databases
232 * @return array all databases a user has access to
236 function PMA_safe_db_list($only_db_check, $controllink, $dblist_cnt, $userlink,
239 if ($only_db_check == false) {
240 // try to get the available dbs list
241 // use userlink by default
242 $dblist = PMA_DBI_get_dblist();
243 $dblist_cnt = count($dblist);
245 // PMA_DBI_get_dblist() relies on the ability to run "SHOW DATABASES".
246 // On servers started with --skip-show-database, this is not possible
247 // so we have here a fallback method, which relies on the controluser
248 // being able to access the "mysql" db, as explained in the doc.
251 $auth_query = 'SELECT User, Select_priv '
253 . 'WHERE User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\'';
254 $rs = PMA_DBI_try_query($auth_query, $controllink);
258 // Access to "mysql" db allowed and dblist still empty -> gets the
260 if (!$dblist_cnt && ($rs && @PMA_DBI_num_rows
($rs))) {
261 $row = PMA_DBI_fetch_assoc($rs);
262 PMA_DBI_free_result($rs);
263 // Correction uva 19991215
264 // Previous code assumed database "mysql" admin table "db" column
265 // "db" contains literal name of user database, and works if so.
266 // Mysql usage generally (and uva usage specifically) allows this
267 // column to contain regular expressions (we have all databases
268 // owned by a given student/faculty/staff beginning with user i.d.
269 // and governed by default by a single set of privileges with
270 // regular expression as key). This breaks previous code.
271 // This maintenance is to fix code to work correctly for regular
273 if ($row['Select_priv'] != 'Y') {
275 // 1. get allowed dbs from the "mysql.db" table
276 // lem9: User can be blank (anonymous user)
277 $local_query = 'SELECT DISTINCT Db FROM mysql.db WHERE Select_priv = \'Y\' AND (User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\' OR User = \'\')';
278 $rs = PMA_DBI_try_query($local_query, $controllink);
279 if ($rs && @PMA_DBI_num_rows
($rs)) {
280 // Will use as associative array of the following 2 code
282 // the 1st is the only line intact from before
284 // the 2nd replaces $dblist[] = $row['Db'];
285 $uva_mydbs = array();
286 // Code following those 2 lines in correction continues
287 // populating $dblist[], as previous code did. But it is
288 // now populated with actual database names instead of
289 // with regular expressions.
290 while ($row = PMA_DBI_fetch_assoc($rs)) {
291 // loic1: all databases cases - part 1
292 if ( !isset($row['Db']) ||
! strlen($row['Db']) ||
$row['Db'] == '%') {
296 // loic1: avoid multiple entries for dbs
297 if (!isset($uva_mydbs[$row['Db']])) {
298 $uva_mydbs[$row['Db']] = 1;
301 PMA_DBI_free_result($rs);
302 $uva_alldbs = PMA_DBI_query('SHOW DATABASES;', $GLOBALS['controllink']);
303 // loic1: all databases cases - part 2
304 if (isset($uva_mydbs['%'])) {
305 while ($uva_row = PMA_DBI_fetch_row($uva_alldbs)) {
306 $dblist[] = $uva_row[0];
309 while ($uva_row = PMA_DBI_fetch_row($uva_alldbs)) {
310 $uva_db = $uva_row[0];
311 if (isset($uva_mydbs[$uva_db]) && $uva_mydbs[$uva_db] == 1) {
313 $uva_mydbs[$uva_db] = 0;
314 } elseif (!isset($dblist[$uva_db])) {
315 foreach ($uva_mydbs as $uva_matchpattern => $uva_value) {
316 // loic1: fixed bad regexp
317 // TODO: db names may contain characters
318 // that are regexp instructions
319 $re = '(^|(\\\\\\\\)+|[^\])';
320 $uva_regex = ereg_replace($re . '%', '\\1.*', ereg_replace($re . '_', '\\1.{1}', $uva_matchpattern));
321 // Fixed db name matching
322 // 2000-08-28 -- Benjamin Gandon
323 if (ereg('^' . $uva_regex . '$', $uva_db)) {
328 } // end if ... elseif ...
331 PMA_DBI_free_result($uva_alldbs);
335 // 2. get allowed dbs from the "mysql.tables_priv" table
336 $local_query = 'SELECT DISTINCT Db FROM mysql.tables_priv WHERE Table_priv LIKE \'%Select%\' AND User = \'' . PMA_sqlAddslashes($cfg['Server']['user']) . '\'';
337 $rs = PMA_DBI_try_query($local_query, $controllink);
338 if ($rs && @PMA_DBI_num_rows
($rs)) {
339 while ($row = PMA_DBI_fetch_assoc($rs)) {
340 if (!in_array($row['Db'], $dblist)) {
341 $dblist[] = $row['Db'];
344 PMA_DBI_free_result($rs);
347 } // end building available dbs from the "mysql" db
353 * Converts numbers like 10M into bytes
355 * @param string $size
356 * @return integer $size
358 function get_real_size($size = 0)
363 $scan['MB'] = 1048576;
364 $scan['Mb'] = 1048576;
365 $scan['M'] = 1048576;
366 $scan['m'] = 1048576;
372 while (list($key) = each($scan)) {
373 if ((strlen($size) > strlen($key))
374 && (substr($size, strlen($size) - strlen($key)) == $key)) {
375 $size = substr($size, 0, strlen($size) - strlen($key)) * $scan[$key];
380 } // end function get_real_size()
386 * @uses extension_loaded()
388 * @uses function_exists()
392 * @uses ob_get_contents()
393 * @uses ob_end_clean()
398 * @param string $module name if module to load
399 * @return boolean success loading module
401 function PMA_dl($module)
403 static $dl_allowed = null;
405 if (extension_loaded($module)) {
409 if (null === $dl_allowed) {
410 if (!@ini_get
('safe_mode')
411 && @ini_get
('enable_dl')
412 && @function_exists
('dl')) {
414 phpinfo(INFO_GENERAL
); /* Only general info */
415 $a = strip_tags(ob_get_contents());
417 if (preg_match('@Thread Safety[[:space:]]*enabled@', $a)) {
418 if (preg_match('@Server API[[:space:]]*\(CGI\|CLI\)@', $a)) {
435 /* Once we require PHP >= 4.3, we might use PHP_SHLIB_SUFFIX here */
436 if (strtoupper(substr(PHP_OS
, 0, 3)) === 'WIN') {
437 $module_file = 'php_' . $module . '.dll';
438 } elseif (PHP_OS
=='HP-UX') {
439 $module_file = $module . '.sl';
441 $module_file = $module . '.so';
444 return @dl
($module_file);
448 * merges array recursive like array_merge_recursive() but keyed-values are
449 * always overwritten.
451 * array PMA_array_merge_recursive(array $array1[, array $array2[, array ...]])
453 * @see http://php.net/array_merge
454 * @see http://php.net/array_merge_recursive
455 * @uses func_num_args()
456 * @uses func_get_arg()
458 * @uses call_user_func_array()
459 * @param array array to merge
460 * @param array array to merge
462 * @return array merged array
464 function PMA_array_merge_recursive()
466 switch(func_num_args()) {
471 // when does that happen?
472 return func_get_arg(0);
475 $args = func_get_args();
476 if (!is_array($args[0]) ||
!is_array($args[1])) {
479 foreach ($args[1] as $key2 => $value2) {
480 if (isset($args[0][$key2]) && !is_int($key2)) {
481 $args[0][$key2] = PMA_array_merge_recursive($args[0][$key2],
484 // we erase the parent array, otherwise we cannot override a directive that
485 // contains array elements, like this:
486 // (in config.default.php) $cfg['ForeignKeyDropdownOrder'] = array('id-content','content-id');
487 // (in config.inc.php) $cfg['ForeignKeyDropdownOrder'] = array('content-id');
488 if (is_int($key2) && $key2 == 0) {
491 $args[0][$key2] = $value2;
497 $args = func_get_args();
498 $args[1] = PMA_array_merge_recursive($args[0], $args[1]);
500 return call_user_func_array('PMA_array_merge_recursive', $args);
506 * calls $function vor every element in $array recursively
508 * @param array $array array to walk
509 * @param string $function function to call for every array element
511 function PMA_arrayWalkRecursive(&$array, $function, $apply_to_keys_also = false)
513 foreach ($array as $key => $value) {
514 if (is_array($value)) {
515 PMA_arrayWalkRecursive($array[$key], $function, $apply_to_keys_also);
517 $array[$key] = $function($value);
520 if ($apply_to_keys_also && is_string($key)) {
521 $new_key = $function($key);
522 if ($new_key != $key) {
523 $array[$new_key] = $array[$key];
531 * boolean phpMyAdmin.PMA_checkPageValidity(string &$page, array $whitelist)
533 * checks given given $page against given $whitelist and returns true if valid
534 * it ignores optionaly query paramters in $page (script.php?ignored)
540 * @param string &$page page to check
541 * @param array $whitelist whitelist to check page against
542 * @return boolean whether $page is valid or not (in $whitelist or not)
544 function PMA_checkPageValidity(&$page, $whitelist)
546 if (! isset($page) ||
!is_string($page)) {
550 if (in_array($page, $whitelist)) {
552 } elseif (in_array(substr($page, 0, strpos($page . '?', '?')), $whitelist)) {
555 $_page = urldecode($page);
556 if (in_array(substr($_page, 0, strpos($_page . '?', '?')), $whitelist)) {
564 * trys to find the value for the given environment vriable name
566 * searchs in $_SERVER, $_ENV than trys getenv() and apache_getenv()
569 * @param string $var_name variable name
570 * @return string value of $var or empty string
572 function PMA_getenv($var_name) {
573 if (isset($_SERVER[$var_name])) {
574 return $_SERVER[$var_name];
575 } elseif (isset($_ENV[$var_name])) {
576 return $_ENV[$var_name];
577 } elseif (getenv($var_name)) {
578 return getenv($var_name);
579 } elseif (function_exists('apache_getenv')
580 && apache_getenv($var_name, true)) {
581 return apache_getenv($var_name, true);
588 * include here only libraries which contain only function definitions
591 /* Input sanitizing */
592 require_once './libraries/sanitizing.lib.php';
593 require_once './libraries/Theme.class.php';
594 require_once './libraries/Theme_Manager.class.php';
595 require_once './libraries/Config.class.php';
596 require_once './libraries/Table.class.php';
600 if (!defined('PMA_MINIMUM_COMMON')) {
603 * string PMA_getIcon(string $icon)
605 * @uses $GLOBALS['pmaThemeImage']
606 * @param $icon name of icon
607 * @return html img tag
609 function PMA_getIcon($icon, $alternate = '')
611 if ($GLOBALS['cfg']['PropertiesIconic']) {
612 return '<img src="' . $GLOBALS['pmaThemeImage'] . $icon . '"'
613 . ' title="' . $alternate . '" alt="' . $alternate . '"'
614 . ' class="icon" width="16" height="16" />';
621 * Displays the maximum size for an upload
623 * @param integer the size
625 * @return string the message
629 function PMA_displayMaximumUploadSize($max_upload_size)
631 list($max_size, $max_unit) = PMA_formatByteDown($max_upload_size);
632 return '(' . sprintf($GLOBALS['strMaximumSize'], $max_size, $max_unit) . ')';
636 * Generates a hidden field which should indicate to the browser
637 * the maximum size for upload
639 * @param integer the size
641 * @return string the INPUT field
645 function PMA_generateHiddenMaxFileSize($max_size)
647 return '<input type="hidden" name="MAX_FILE_SIZE" value="' .$max_size . '" />';
651 * Add slashes before "'" and "\" characters so a value containing them can
652 * be used in a sql comparison.
654 * @param string the string to slash
655 * @param boolean whether the string will be used in a 'LIKE' clause
656 * (it then requires two more escaped sequences) or not
657 * @param boolean whether to treat cr/lfs as escape-worthy entities
658 * (converts \n to \\n, \r to \\r)
660 * @param boolean whether this function is used as part of the
661 * "Create PHP code" dialog
663 * @return string the slashed string
667 function PMA_sqlAddslashes($a_string = '', $is_like = false, $crlf = false, $php_code = false)
670 $a_string = str_replace('\\', '\\\\\\\\', $a_string);
672 $a_string = str_replace('\\', '\\\\', $a_string);
676 $a_string = str_replace("\n", '\n', $a_string);
677 $a_string = str_replace("\r", '\r', $a_string);
678 $a_string = str_replace("\t", '\t', $a_string);
682 $a_string = str_replace('\'', '\\\'', $a_string);
684 $a_string = str_replace('\'', '\'\'', $a_string);
688 } // end of the 'PMA_sqlAddslashes()' function
692 * Add slashes before "_" and "%" characters for using them in MySQL
693 * database, table and field names.
694 * Note: This function does not escape backslashes!
696 * @param string the string to escape
698 * @return string the escaped string
702 function PMA_escape_mysql_wildcards($name)
704 $name = str_replace('_', '\\_', $name);
705 $name = str_replace('%', '\\%', $name);
708 } // end of the 'PMA_escape_mysql_wildcards()' function
711 * removes slashes before "_" and "%" characters
712 * Note: This function does not unescape backslashes!
714 * @param string $name the string to escape
715 * @return string the escaped string
718 function PMA_unescape_mysql_wildcards($name)
720 $name = str_replace('\\_', '_', $name);
721 $name = str_replace('\\%', '%', $name);
724 } // end of the 'PMA_unescape_mysql_wildcards()' function
727 * removes quotes (',",`) from a quoted string
729 * checks if the sting is quoted and removes this quotes
731 * @param string $quoted_string string to remove quotes from
732 * @param string $quote type of quote to remove
733 * @return string unqoted string
735 function PMA_unQuote($quoted_string, $quote = null)
739 if (null === $quote) {
747 foreach ($quotes as $quote) {
748 if (substr($quoted_string, 0, 1) === $quote
749 && substr($quoted_string, -1, 1) === $quote ) {
750 $unquoted_string = substr($quoted_string, 1, -1);
751 // replace escaped quotes
752 $unquoted_string = str_replace($quote . $quote, $quote, $unquoted_string);
753 return $unquoted_string;
757 return $quoted_string;
763 * @param mixed pre-parsed SQL structure
765 * @return string the formatted sql
767 * @global array the configuration array
768 * @global boolean whether the current statement is a multiple one or not
772 * @author Robin Johnson <robbat2@users.sourceforge.net>
774 function PMA_formatSql($parsed_sql, $unparsed_sql = '')
778 // Check that we actually have a valid set of parsed data
780 // first check for the SQL parser having hit an error
781 if (PMA_SQP_isError()) {
784 // then check for an array
785 if (!is_array($parsed_sql)) {
786 // We don't so just return the input directly
787 // This is intended to be used for when the SQL Parser is turned off
788 $formatted_sql = '<pre>' . "\n"
789 . (($cfg['SQP']['fmtType'] == 'none' && $unparsed_sql != '') ?
$unparsed_sql : $parsed_sql) . "\n"
791 return $formatted_sql;
796 switch ($cfg['SQP']['fmtType']) {
798 if ($unparsed_sql != '') {
799 $formatted_sql = "<pre>\n" . PMA_SQP_formatNone(array('raw' => $unparsed_sql)) . "\n</pre>";
801 $formatted_sql = PMA_SQP_formatNone($parsed_sql);
805 $formatted_sql = PMA_SQP_formatHtml($parsed_sql, 'color');
808 //$formatted_sql = PMA_SQP_formatText($parsed_sql);
809 $formatted_sql = PMA_SQP_formatHtml($parsed_sql, 'text');
815 return $formatted_sql;
816 } // end of the "PMA_formatSql()" function
820 * Displays a link to the official MySQL documentation
822 * @param string chapter of "HTML, one page per chapter" documentation
823 * @param string contains name of page/anchor that is being linked
824 * @param bool whether to use big icon (like in left frame)
826 * @return string the html link
830 function PMA_showMySQLDocu($chapter, $link, $big_icon = false)
834 if ($cfg['MySQLManualType'] == 'none' ||
empty($cfg['MySQLManualBase'])) {
838 // Fixup for newly used names:
839 $chapter = str_replace('_', '-', strtolower($chapter));
840 $link = str_replace('_', '-', strtolower($link));
842 switch ($cfg['MySQLManualType']) {
844 if (empty($chapter)) {
847 $url = $cfg['MySQLManualBase'] . '/' . $chapter . '.html#' . $link;
850 $url = $cfg['MySQLManualBase'] . '#' . $link;
856 $url = $cfg['MySQLManualBase'] . '/' . $link . '.html';
865 if (defined('PMA_MYSQL_INT_VERSION')) {
866 if (PMA_MYSQL_INT_VERSION
< 50000) {
868 if (!empty($GLOBALS['mysql_4_1_doc_lang'])) {
869 $lang = $GLOBALS['mysql_4_1_doc_lang'];
871 } elseif (PMA_MYSQL_INT_VERSION
>= 50100) {
873 if (!empty($GLOBALS['mysql_5_1_doc_lang'])) {
874 $lang = $GLOBALS['mysql_5_1_doc_lang'];
876 } elseif (PMA_MYSQL_INT_VERSION
>= 50000) {
878 if (!empty($GLOBALS['mysql_5_0_doc_lang'])) {
879 $lang = $GLOBALS['mysql_5_0_doc_lang'];
883 $url = $cfg['MySQLManualBase'] . '/' . $mysql . '/' . $lang . '/' . $link . '.html';
888 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>';
889 } elseif ($GLOBALS['cfg']['ReplaceHelpImg']) {
890 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>';
892 return '[<a href="' . $url . '" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
894 } // end of the 'PMA_showMySQLDocu()' function
897 * Displays a hint icon, on mouse over show the hint
899 * @param string the error message
903 function PMA_showHint($hint_message)
905 //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) . '\');" />';
906 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;" />';
910 * Displays a MySQL error message in the right frame.
912 * @param string the error message
913 * @param string the sql query that failed
914 * @param boolean whether to show a "modify" link or not
915 * @param string the "back" link url (full path is not required)
916 * @param boolean EXIT the page?
918 * @global array the configuration array
922 function PMA_mysqlDie($error_message = '', $the_query = '',
923 $is_modify_link = true, $back_url = '',
926 global $cfg, $table, $db, $sql_query;
928 require_once './libraries/header.inc.php';
930 if (!$error_message) {
931 $error_message = PMA_DBI_getError();
933 if (!$the_query && !empty($GLOBALS['sql_query'])) {
934 $the_query = $GLOBALS['sql_query'];
937 // --- Added to solve bug #641765
938 // Robbat2 - 12 January 2003, 9:46PM
939 // Revised, Robbat2 - 13 January 2003, 2:59PM
940 if (!function_exists('PMA_SQP_isError') ||
PMA_SQP_isError()) {
941 $formatted_sql = htmlspecialchars($the_query);
942 } elseif (empty($the_query) ||
trim($the_query) == '') {
945 $formatted_sql = PMA_formatSql(PMA_SQP_parse($the_query), $the_query);
948 echo "\n" . '<!-- PMA-SQL-ERROR -->' . "\n";
949 echo ' <div class="error"><h1>' . $GLOBALS['strError'] . '</h1>' . "\n";
950 // if the config password is wrong, or the MySQL server does not
951 // respond, do not show the query that would reveal the
953 if (!empty($the_query) && !strstr($the_query, 'connect')) {
954 // --- Added to solve bug #641765
955 // Robbat2 - 12 January 2003, 9:46PM
956 // Revised, Robbat2 - 13 January 2003, 2:59PM
957 if (function_exists('PMA_SQP_isError') && PMA_SQP_isError()) {
958 echo PMA_SQP_getErrorString() . "\n";
959 echo '<br />' . "\n";
962 // modified to show me the help on sql errors (Michael Keck)
963 echo ' <p><strong>' . $GLOBALS['strSQLQuery'] . ':</strong>' . "\n";
964 if (strstr(strtolower($formatted_sql), 'select')) { // please show me help to the error on select
965 echo PMA_showMySQLDocu('SQL-Syntax', 'SELECT');
967 if ($is_modify_link && isset($db)) {
969 $doedit_goto = '<a href="tbl_properties.php?' . PMA_generate_common_url($db, $table) . '&sql_query=' . urlencode($the_query) . '&show_query=1">';
971 $doedit_goto = '<a href="db_details.php?' . PMA_generate_common_url($db) . '&sql_query=' . urlencode($the_query) . '&show_query=1">';
973 if ($GLOBALS['cfg']['PropertiesIconic']) {
975 . '<img class="icon" src=" '. $GLOBALS['pmaThemeImage'] . 'b_edit.png" width="16" height="16" alt="' . $GLOBALS['strEdit'] .'" />'
979 . $doedit_goto . $GLOBALS['strEdit'] . '</a>'
985 .' ' . $formatted_sql . "\n"
989 $tmp_mysql_error = ''; // for saving the original $error_message
990 if (!empty($error_message)) {
991 $tmp_mysql_error = strtolower($error_message); // save the original $error_message
992 $error_message = htmlspecialchars($error_message);
993 $error_message = preg_replace("@((\015\012)|(\015)|(\012)){3,}@", "\n\n", $error_message);
995 // modified to show me the help on error-returns (Michael Keck)
996 // (now error-messages-server)
998 . ' <strong>' . $GLOBALS['strMySQLSaid'] . '</strong>'
999 . PMA_showMySQLDocu('Error-messages-server', 'Error-messages-server')
1003 // The error message will be displayed within a CODE segment.
1004 // To preserve original formatting, but allow wordwrapping, we do a couple of replacements
1006 // Replace all non-single blanks with their HTML-counterpart
1007 $error_message = str_replace(' ', ' ', $error_message);
1008 // Replace TAB-characters with their HTML-counterpart
1009 $error_message = str_replace("\t", ' ', $error_message);
1010 // Replace linebreaks
1011 $error_message = nl2br($error_message);
1013 echo '<code>' . "\n"
1014 . $error_message . "\n"
1015 . '</code><br />' . "\n";
1017 // feature request #1036254:
1018 // Add a link by MySQL-Error #1062 - Duplicate entry
1019 // 2004-10-20 by mkkeck
1020 // 2005-01-17 modified by mkkeck bugfix
1021 if (substr($error_message, 1, 4) == '1062') {
1022 // get the duplicate entry
1025 // TODO: what would be the best delimiter, while avoiding
1026 // special characters that can become high-ascii after editing,
1027 // depending upon which editor is used by the developer?
1028 $error_table = array();
1029 if (preg_match('@ALTER\s*TABLE\s*\`([^\`]+)\`@iu', $the_query, $error_table)) {
1030 $error_table = $error_table[1];
1031 } elseif (preg_match('@INSERT\s*INTO\s*\`([^\`]+)\`@iu', $the_query, $error_table)) {
1032 $error_table = $error_table[1];
1033 } elseif (preg_match('@UPDATE\s*\`([^\`]+)\`@iu', $the_query, $error_table)) {
1034 $error_table = $error_table[1];
1035 } elseif (preg_match('@INSERT\s*\`([^\`]+)\`@iu', $the_query, $error_table)) {
1036 $error_table = $error_table[1];
1040 $error_fields = array();
1041 if (preg_match('@\(([^\)]+)\)@i', $the_query, $error_fields)) {
1042 $error_fields = explode(',', $error_fields[1]);
1043 } elseif (preg_match('@(`[^`]+`)\s*=@i', $the_query, $error_fields)) {
1044 $error_fields = explode(',', $error_fields[1]);
1046 if (is_array($error_table) ||
is_array($error_fields)) {
1049 $duplicate_value = array();
1050 preg_match('@\'([^\']+)\'@i', $tmp_mysql_error, $duplicate_value);
1051 $duplicate_value = $duplicate_value[1];
1055 FROM ' . PMA_backquote($error_table) . '
1056 WHERE CONCAT_WS("-", ' . implode(', ', $error_fields) . ')
1057 = "' . PMA_sqlAddslashes($duplicate_value) . '"
1058 ORDER BY ' . implode(', ', $error_fields);
1059 unset($error_table, $error_fields, $duplicate_value);
1061 echo ' <form method="post" action="import.php" style="padding: 0; margin: 0">' ."\n"
1062 .' <input type="hidden" name="sql_query" value="' . htmlentities($sql) . '" />' . "\n"
1063 .' ' . PMA_generate_common_hidden_inputs($db, $table) . "\n"
1064 .' <input type="submit" name="submit" value="' . $GLOBALS['strBrowse'] . '" />' . "\n"
1068 } // end of show duplicate entry
1071 echo '<fieldset class="tblFooters">';
1073 if (!empty($back_url) && $exit) {
1074 $goto_back_url='<a href="' . (strstr($back_url, '?') ?
$back_url . '&no_history=true' : $back_url . '?no_history=true') . '">';
1075 echo '[ ' . $goto_back_url . $GLOBALS['strBack'] . '</a> ]';
1077 echo ' </fieldset>' . "\n\n";
1079 require_once './libraries/footer.inc.php';
1081 } // end of the 'PMA_mysqlDie()' function
1084 * Returns a string formatted with CONVERT ... USING
1085 * if MySQL supports it
1087 * @param string the string itself
1088 * @param string the mode: quoted or unquoted (this one by default)
1090 * @return the formatted string
1094 function PMA_convert_using($string, $mode='unquoted')
1096 if ($mode == 'quoted') {
1097 $possible_quote = "'";
1099 $possible_quote = "";
1102 if (PMA_MYSQL_INT_VERSION
>= 40100) {
1103 list($conn_charset) = explode('_', $GLOBALS['collation_connection']);
1104 $converted_string = "CONVERT(" . $possible_quote . $string . $possible_quote . " USING " . $conn_charset . ")";
1106 $converted_string = $possible_quote . $string . $possible_quote;
1108 return $converted_string;
1112 * Send HTTP header, taking IIS limits into account (600 seems ok)
1114 * @param string $uri the header to send
1115 * @return boolean always true
1117 function PMA_sendHeaderLocation($uri)
1119 if (PMA_IS_IIS
&& strlen($uri) > 600) {
1121 echo '<html><head><title>- - -</title>' . "\n";
1122 echo '<meta http-equiv="expires" content="0">' . "\n";
1123 echo '<meta http-equiv="Pragma" content="no-cache">' . "\n";
1124 echo '<meta http-equiv="Cache-Control" content="no-cache">' . "\n";
1125 echo '<meta http-equiv="Refresh" content="0;url=' .$uri . '">' . "\n";
1126 echo '<script type="text/javascript" language="javascript">' . "\n";
1127 echo '//<![CDATA[' . "\n";
1128 echo 'setTimeout ("window.location = unescape(\'"' . $uri . '"\')",2000); </script>' . "\n";
1129 echo '//]]>' . "\n";
1130 echo '</head>' . "\n";
1131 echo '<body>' . "\n";
1132 echo '<script type="text/javascript" language="javascript">' . "\n";
1133 echo '//<![CDATA[' . "\n";
1134 echo 'document.write (\'<p><a href="' . $uri . '">' . $GLOBALS['strGo'] . '</a></p>\');' . "\n";
1135 echo '//]]>' . "\n";
1136 echo '</script></body></html>' . "\n";
1140 if (strpos($uri, '?') === false) {
1141 header('Location: ' . $uri . '?' . SID
);
1143 $separator = PMA_get_arg_separator();
1144 header('Location: ' . $uri . $separator . SID
);
1147 session_write_close();
1148 // bug #1523784: IE6 does not like 'Refresh: 0', it
1149 // results in a blank page
1150 // (but we need it when coming from the cookie login panel)
1151 if (PMA_IS_IIS
&& defined('PMA_COMING_FROM_COOKIE_LOGIN')) {
1152 header('Refresh: 0; ' . $uri);
1154 header('Location: ' . $uri);
1161 * Get the list and number of available databases.
1163 * @param string the url to go back to in case of error
1165 * @return boolean always true
1167 * @global array the list of available databases
1168 * @global integer the number of available databases
1169 * @global array current configuration
1171 function PMA_availableDatabases($error_url = '')
1177 // 1. A list of allowed databases has already been defined by the
1178 // authentication process -> gets the available databases list
1179 if (count($dblist)) {
1180 foreach ($dblist as $key => $db) {
1181 if (!@PMA_DBI_select_db
($db) ||
(!empty($GLOBALS['cfg']['Server']['hide_db']) && preg_match('/' . $GLOBALS['cfg']['Server']['hide_db'] . '/', $db))) {
1182 unset($dblist[$key]);
1186 // 2. Allowed database list is empty -> gets the list of all databases
1188 elseif (empty($cfg['Server']['only_db'])) {
1189 $dblist = PMA_DBI_get_dblist(); // needed? or PMA_mysqlDie('', 'SHOW DATABASES;', false, $error_url);
1192 $num_dbs = count($dblist);
1194 // natural order for db list; but do not sort if user asked
1195 // for a specific order with the 'only_db' mechanism
1196 if (!is_array($GLOBALS['cfg']['Server']['only_db'])
1197 && $GLOBALS['cfg']['NaturalOrder']) {
1202 } // end of the 'PMA_availableDatabases()' function
1205 * returns array with tables of given db with extended infomation and grouped
1207 * @uses $GLOBALS['cfg']['LeftFrameTableSeparator']
1208 * @uses $GLOBALS['cfg']['LeftFrameTableLevel']
1209 * @uses $GLOBALS['cfg']['ShowTooltipAliasTB']
1210 * @uses $GLOBALS['cfg']['NaturalOrder']
1211 * @uses PMA_DBI_fetch_result()
1212 * @uses PMA_backquote()
1218 * @param string $db name of db
1219 * return array (rekursive) grouped table list
1221 function PMA_getTableList($db, $tables = null)
1223 $sep = $GLOBALS['cfg']['LeftFrameTableSeparator'];
1225 if ( null === $tables ) {
1226 $tables = PMA_DBI_get_tables_full($db);
1227 if ($GLOBALS['cfg']['NaturalOrder']) {
1228 uksort($tables, 'strnatcasecmp');
1232 if (count($tables) < 1) {
1243 $table_groups = array();
1245 foreach ($tables as $table_name => $table) {
1247 // check for correct row count
1248 if (null === $table['Rows']) {
1249 // Do not check exact row count here,
1250 // if row count is invalid possibly the table is defect
1251 // and this would break left frame;
1252 // but we can check row count if this is a view,
1253 // since PMA_Table::countRecords() returns a limited row count
1256 // set this because PMA_Table::countRecords() can use it
1257 $tbl_is_view = PMA_Table
::isView($db, $table['Name']);
1260 $table['Rows'] = PMA_Table
::countRecords($db, $table['Name'],
1265 // in $group we save the reference to the place in $table_groups
1266 // where to store the table info
1267 if ($GLOBALS['cfg']['LeftFrameDBTree']
1268 && $sep && strstr($table_name, $sep))
1270 $parts = explode($sep, $table_name);
1272 $group =& $table_groups;
1274 $group_name_full = '';
1275 while ($i < count($parts) - 1
1276 && $i < $GLOBALS['cfg']['LeftFrameTableLevel']) {
1277 $group_name = $parts[$i] . $sep;
1278 $group_name_full .= $group_name;
1280 if (!isset($group[$group_name])) {
1281 $group[$group_name] = array();
1282 $group[$group_name]['is' . $sep . 'group'] = true;
1283 $group[$group_name]['tab' . $sep . 'count'] = 1;
1284 $group[$group_name]['tab' . $sep . 'group'] = $group_name_full;
1285 } elseif (!isset($group[$group_name]['is' . $sep . 'group'])) {
1286 $table = $group[$group_name];
1287 $group[$group_name] = array();
1288 $group[$group_name][$group_name] = $table;
1290 $group[$group_name]['is' . $sep . 'group'] = true;
1291 $group[$group_name]['tab' . $sep . 'count'] = 1;
1292 $group[$group_name]['tab' . $sep . 'group'] = $group_name_full;
1294 $group[$group_name]['tab' . $sep . 'count']++
;
1296 $group =& $group[$group_name];
1300 if (!isset($table_groups[$table_name])) {
1301 $table_groups[$table_name] = array();
1303 $group =& $table_groups;
1307 if ($GLOBALS['cfg']['ShowTooltipAliasTB']
1308 && $GLOBALS['cfg']['ShowTooltipAliasTB'] !== 'nested') {
1309 // switch tooltip and name
1310 $table['Comment'] = $table['Name'];
1311 $table['disp_name'] = $table['Comment'];
1313 $table['disp_name'] = $table['Name'];
1316 $group[$table_name] = array_merge($default, $table);
1319 return $table_groups;
1322 /* ----------------------- Set of misc functions ----------------------- */
1326 * Adds backquotes on both sides of a database, table or field name.
1327 * and escapes backquotes inside the name with another backquote
1330 * echo PMA_backquote('owner`s db'); // `owner``s db`
1333 * @param mixed $a_name the database, table or field name to "backquote"
1335 * @param boolean $do_it a flag to bypass this function (used by dump
1337 * @return mixed the "backquoted" database, table or field name if the
1338 * current MySQL release is >= 3.23.6, the original one
1342 function PMA_backquote($a_name, $do_it = true)
1348 if (is_array($a_name)) {
1350 foreach ($a_name as $key => $val) {
1351 $result[$key] = PMA_backquote($val);
1356 // '0' is also empty for php :-(
1357 if (strlen($a_name) && $a_name != '*') {
1358 return '`' . str_replace('`', '``', $a_name) . '`';
1362 } // end of the 'PMA_backquote()' function
1366 * Format a string so it can be a string inside JavaScript code inside an
1367 * eventhandler (onclick, onchange, on..., ).
1368 * This function is used to displays a javascript confirmation box for
1369 * "DROP/DELETE/ALTER" queries.
1371 * @uses PMA_escapeJsString()
1372 * @uses PMA_backquote()
1374 * @uses htmlspecialchars()
1375 * @uses str_replace()
1376 * @param string $a_string the string to format
1377 * @param boolean $add_backquotes whether to add backquotes to the string or not
1379 * @return string the formated string
1383 function PMA_jsFormat($a_string = '', $add_backquotes = true)
1385 if (is_string($a_string)) {
1386 $a_string = htmlspecialchars($a_string);
1387 $a_string = PMA_escapeJsString($a_string);
1388 // TODO: what is this good for?
1389 $a_string = str_replace('#', '\\#', $a_string);
1392 return (($add_backquotes) ?
PMA_backquote($a_string) : $a_string);
1393 } // end of the 'PMA_jsFormat()' function
1396 * escapes a string to be inserted as string a JavaScript block
1397 * enclosed by <![CDATA[ ... ]]>
1398 * this requires only to escape ' with \' and end of script block
1401 * @param string $string the string to be escaped
1402 * @return string the escaped string
1404 function PMA_escapeJsString($string)
1406 return strtr($string, array(
1411 '</script' => '</\' + \'script'));
1415 * Defines the <CR><LF> value depending on the user OS.
1417 * @return string the <CR><LF> value to use
1421 function PMA_whichCrlf()
1425 // The 'PMA_USR_OS' constant is defined in "./libraries/defines.lib.php"
1427 if (PMA_USR_OS
== 'Win') {
1431 elseif (PMA_USR_OS
== 'Mac') {
1440 } // end of the 'PMA_whichCrlf()' function
1443 * Reloads navigation if needed.
1445 * @global mixed configuration
1446 * @global bool whether to reload
1450 function PMA_reloadNavigation()
1454 // Reloads the navigation frame via JavaScript if required
1455 if (isset($GLOBALS['reload']) && $GLOBALS['reload']) {
1457 $reload_url = './left.php?' . PMA_generate_common_url((isset($GLOBALS['db']) ?
$GLOBALS['db'] : ''), '', '&');
1459 <script type
="text/javascript" language
="javascript">
1461 if (typeof(window
.parent
) != 'undefined'
1462 && typeof(window
.parent
.frame_navigation
) != 'undefined') {
1463 window
.parent
.goTo('<?php echo $reload_url; ?>');
1468 unset($GLOBALS['reload']);
1473 * Displays a message at the top of the "main" (right) frame
1475 * @param string the message to display
1477 * @global array the configuration array
1481 function PMA_showMessage($message)
1485 // Sanitizes $message
1486 $message = PMA_sanitize($message);
1488 // Corrects the tooltip text via JS if required
1489 if ( isset($GLOBALS['table']) && strlen($GLOBALS['table']) && $cfg['ShowTooltip']) {
1490 $result = PMA_DBI_try_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], true) . '\'');
1492 $tbl_status = PMA_DBI_fetch_assoc($result);
1493 $tooltip = (empty($tbl_status['Comment']))
1495 : $tbl_status['Comment'] . ' ';
1496 $tooltip .= '(' . PMA_formatNumber($tbl_status['Rows'], 0) . ' ' . $GLOBALS['strRows'] . ')';
1497 PMA_DBI_free_result($result);
1498 $uni_tbl = PMA_jsFormat($GLOBALS['db'] . '.' . $GLOBALS['table'], false);
1501 <script type
="text/javascript" language
="javascript">
1503 window
.parent
.updateTableTitle('<?php echo $uni_tbl; ?>', '<?php echo PMA_jsFormat($tooltip, false); ?>');
1508 } // end if ... elseif
1510 // Checks if the table needs to be repaired after a TRUNCATE query.
1511 if (isset($GLOBALS['table']) && isset($GLOBALS['sql_query'])
1512 && $GLOBALS['sql_query'] == 'TRUNCATE TABLE ' . PMA_backquote($GLOBALS['table'])) {
1513 if (!isset($tbl_status)) {
1514 $result = @PMA_DBI_try_query
('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], true) . '\'');
1516 $tbl_status = PMA_DBI_fetch_assoc($result);
1517 PMA_DBI_free_result($result);
1520 if (isset($tbl_status) && (int) $tbl_status['Index_length'] > 1024) {
1521 PMA_DBI_try_query('REPAIR TABLE ' . PMA_backquote($GLOBALS['table']));
1527 <div align
="<?php echo $GLOBALS['cell_align_left']; ?>">
1529 if (!empty($GLOBALS['show_error_header'])) {
1532 <h1
><?php
echo $GLOBALS['strError']; ?
></h1
>
1537 if (isset($GLOBALS['special_message'])) {
1538 echo PMA_sanitize($GLOBALS['special_message']);
1539 unset($GLOBALS['special_message']);
1542 if (!empty($GLOBALS['show_error_header'])) {
1546 if ($cfg['ShowSQL'] == true
1547 && (!empty($GLOBALS['sql_query']) ||
!empty($GLOBALS['display_query']))) {
1548 if (!empty($GLOBALS['display_query'])) {
1549 $local_query = $GLOBALS['display_query'];
1551 if ($cfg['SQP']['fmtType'] == 'none' && !empty($GLOBALS['unparsed_sql'])) {
1552 $local_query = $GLOBALS['unparsed_sql'];
1554 $local_query = $GLOBALS['sql_query'];
1557 // Basic url query part
1558 $url_qpart = '?' . PMA_generate_common_url(isset($GLOBALS['db']) ?
$GLOBALS['db'] : '', isset($GLOBALS['table']) ?
$GLOBALS['table'] : '');
1560 // Html format the query to be displayed
1561 // The nl2br function isn't used because its result isn't a valid
1562 // xhtml1.0 statement before php4.0.5 ("<br>" and not "<br />")
1563 // If we want to show some sql code it is easiest to create it here
1564 /* SQL-Parser-Analyzer */
1566 if (!empty($GLOBALS['show_as_php'])) {
1567 $new_line = '\'<br />' . "\n" . ' . \' ';
1569 if (isset($new_line)) {
1570 /* SQL-Parser-Analyzer */
1571 $query_base = PMA_sqlAddslashes(htmlspecialchars($local_query), false, false, true);
1572 /* SQL-Parser-Analyzer */
1573 $query_base = preg_replace("@((\015\012)|(\015)|(\012))+@", $new_line, $query_base);
1575 $query_base = $local_query;
1578 // Parse SQL if needed
1579 if (isset($GLOBALS['parsed_sql']) && $query_base == $GLOBALS['parsed_sql']['raw']) {
1580 $parsed_sql = $GLOBALS['parsed_sql'];
1582 // when the query is large (for example an INSERT of binary
1583 // data), the parser chokes; so avoid parsing the query
1584 if (strlen($query_base) < 1000) {
1585 $parsed_sql = PMA_SQP_parse($query_base);
1590 if (isset($parsed_sql)) {
1591 $analyzed_display_query = PMA_SQP_analyze($parsed_sql);
1594 // Here we append the LIMIT added for navigation, to
1595 // enable its display. Adding it higher in the code
1596 // to $local_query would create a problem when
1597 // using the Refresh or Edit links.
1599 // Only append it on SELECTs.
1601 // FIXME: what would be the best to do when someone
1602 // hits Refresh: use the current LIMITs ?
1604 if (isset($analyzed_display_query[0]['queryflags']['select_from'])
1605 && isset($GLOBALS['sql_limit_to_append'])) {
1606 $query_base = $analyzed_display_query[0]['section_before_limit'] . "\n" . $GLOBALS['sql_limit_to_append'] . $analyzed_display_query[0]['section_after_limit'];
1607 // Need to reparse query
1608 $parsed_sql = PMA_SQP_parse($query_base);
1611 if (!empty($GLOBALS['show_as_php'])) {
1612 $query_base = '$sql = \'' . $query_base;
1613 } elseif (!empty($GLOBALS['validatequery'])) {
1614 $query_base = PMA_validateSQL($query_base);
1616 if (isset($parsed_sql)) {
1617 $query_base = PMA_formatSql($parsed_sql, $query_base);
1621 // Prepares links that may be displayed to edit/explain the query
1622 // (don't go to default pages, we must go to the page
1623 // where the query box is available)
1624 // (also, I don't see why we should check the goto variable)
1626 //if (!isset($GLOBALS['goto'])) {
1627 //$edit_target = (isset($GLOBALS['table'])) ? $cfg['DefaultTabTable'] : $cfg['DefaultTabDatabase'];
1628 $edit_target = isset($GLOBALS['db']) ?
(isset($GLOBALS['table']) ?
'tbl_properties.php' : 'db_details.php') : 'server_sql.php';
1629 //} elseif ($GLOBALS['goto'] != 'main.php') {
1630 // $edit_target = $GLOBALS['goto'];
1632 // $edit_target = '';
1635 if (isset($cfg['SQLQuery']['Edit'])
1636 && ($cfg['SQLQuery']['Edit'] == true)
1637 && (!empty($edit_target))) {
1639 if ($cfg['EditInWindow'] == true) {
1640 $onclick = 'window.parent.focus_querywindow(\'' . PMA_jsFormat($local_query, false) . '\'); return false;';
1645 $edit_link = $edit_target
1647 . '&sql_query=' . urlencode($local_query)
1648 . '&show_query=1#querybox';
1649 $edit_link = ' [' . PMA_linkOrButton($edit_link, $GLOBALS['strEdit'], array('onclick' => $onclick)) . ']';
1654 // Want to have the query explained (Mike Beck 2002-05-22)
1655 // but only explain a SELECT (that has not been explained)
1656 /* SQL-Parser-Analyzer */
1657 if (isset($cfg['SQLQuery']['Explain'])
1658 && $cfg['SQLQuery']['Explain'] == true) {
1660 // Detect if we are validating as well
1661 // To preserve the validate uRL data
1662 if (!empty($GLOBALS['validatequery'])) {
1663 $explain_link_validate = '&validatequery=1';
1665 $explain_link_validate = '';
1668 $explain_link = 'import.php'
1670 . $explain_link_validate
1671 . '&sql_query=';
1673 if (preg_match('@^SELECT[[:space:]]+@i', $local_query)) {
1674 $explain_link .= urlencode('EXPLAIN ' . $local_query);
1675 $message = $GLOBALS['strExplain'];
1676 } elseif (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $local_query)) {
1677 $explain_link .= urlencode(substr($local_query, 8));
1678 $message = $GLOBALS['strNoExplain'];
1682 if (!empty($explain_link)) {
1683 $explain_link = ' [' . PMA_linkOrButton($explain_link, $message) . ']';
1689 // Also we would like to get the SQL formed in some nice
1690 // php-code (Mike Beck 2002-05-22)
1691 if (isset($cfg['SQLQuery']['ShowAsPHP'])
1692 && $cfg['SQLQuery']['ShowAsPHP'] == true) {
1693 $php_link = 'import.php'
1695 . '&show_query=1'
1696 . '&sql_query=' . urlencode($local_query)
1697 . '&show_as_php=';
1699 if (!empty($GLOBALS['show_as_php'])) {
1701 $message = $GLOBALS['strNoPhp'];
1704 $message = $GLOBALS['strPhp'];
1706 $php_link = ' [' . PMA_linkOrButton($php_link, $message) . ']';
1708 if (isset($GLOBALS['show_as_php']) && $GLOBALS['show_as_php'] == '1') {
1712 . '&show_query=1'
1713 . '&sql_query=' . urlencode($local_query);
1714 $php_link .= ' [' . PMA_linkOrButton($runquery_link, $GLOBALS['strRunQuery']) . ']';
1722 if (isset($cfg['SQLQuery']['Refresh'])
1723 && $cfg['SQLQuery']['Refresh']
1724 && preg_match('@^(SELECT|SHOW)[[:space:]]+@i', $local_query)) {
1726 $refresh_link = 'import.php'
1728 . '&show_query=1'
1729 . (isset($_GET['pos']) ?
'&pos=' . $_GET['pos'] : '')
1730 . '&sql_query=' . urlencode($local_query);
1731 $refresh_link = ' [' . PMA_linkOrButton($refresh_link, $GLOBALS['strRefresh']) . ']';
1736 if (isset($cfg['SQLValidator']['use'])
1737 && $cfg['SQLValidator']['use'] == true
1738 && isset($cfg['SQLQuery']['Validate'])
1739 && $cfg['SQLQuery']['Validate'] == true) {
1740 $validate_link = 'import.php'
1742 . '&show_query=1'
1743 . '&sql_query=' . urlencode($local_query)
1744 . '&validatequery=';
1745 if (!empty($GLOBALS['validatequery'])) {
1746 $validate_link .= '0';
1747 $validate_message = $GLOBALS['strNoValidateSQL'] ;
1749 $validate_link .= '1';
1750 $validate_message = $GLOBALS['strValidateSQL'] ;
1752 $validate_link = ' [' . PMA_linkOrButton($validate_link, $validate_message) . ']';
1754 $validate_link = '';
1756 unset($local_query);
1758 // Displays the message
1759 echo '<fieldset class="">' . "\n";
1760 echo ' <legend>' . $GLOBALS['strSQLQuery'] . ':</legend>';
1761 echo ' ' . $query_base;
1763 //Clean up the end of the PHP
1764 if (!empty($GLOBALS['show_as_php'])) {
1767 echo '</fieldset>' . "\n";
1769 if (!empty($edit_target)) {
1770 echo '<fieldset class="tblFooters">';
1771 echo $edit_link . $explain_link . $php_link . $refresh_link . $validate_link;
1778 } // end of the 'PMA_showMessage()' function
1782 * Formats $value to byte view
1784 * @param double the value to format
1785 * @param integer the sensitiveness
1786 * @param integer the number of decimals to retain
1788 * @return array the formatted value and its unit
1793 * @version 1.2 - 18 July 2002
1795 function PMA_formatByteDown($value, $limes = 6, $comma = 0)
1797 $dh = pow(10, $comma);
1798 $li = pow(10, $limes);
1799 $return_value = $value;
1800 $unit = $GLOBALS['byteUnits'][0];
1802 for ($d = 6, $ex = 15; $d >= 1; $d--, $ex-=3) {
1803 if (isset($GLOBALS['byteUnits'][$d]) && $value >= $li * pow(10, $ex)) {
1804 $value = round($value / (pow(1024, $d) / $dh)) /$dh;
1805 $unit = $GLOBALS['byteUnits'][$d];
1810 if ($unit != $GLOBALS['byteUnits'][0]) {
1811 $return_value = number_format($value, $comma, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
1813 $return_value = number_format($value, 0, $GLOBALS['number_decimal_separator'], $GLOBALS['number_thousands_separator']);
1816 return array($return_value, $unit);
1817 } // end of the 'PMA_formatByteDown' function
1820 * Formats $value to the given length and appends SI prefixes
1821 * $comma is not substracted from the length
1822 * with a $length of 0 no truncation occurs, number is only formated
1823 * to the current locale
1825 * echo PMA_formatNumber(123456789, 6); // 123,457 k
1826 * echo PMA_formatNumber(-123456789, 4, 2); // -123.46 M
1827 * echo PMA_formatNumber(-0.003, 6); // -3 m
1828 * echo PMA_formatNumber(0.003, 3, 3); // 0.003
1829 * echo PMA_formatNumber(0.00003, 3, 2); // 0.03 m
1830 * echo PMA_formatNumber(0, 6); // 0
1832 * @param double $value the value to format
1833 * @param integer $length the max length
1834 * @param integer $comma the number of decimals to retain
1835 * @param boolean $only_down do not reformat numbers below 1
1837 * @return string the formatted value and its unit
1841 * @author staybyte, sebastian mendel
1842 * @version 1.1.0 - 2005-10-27
1844 function PMA_formatNumber($value, $length = 3, $comma = 0, $only_down = false)
1846 if ($length === 0) {
1847 return number_format($value,
1849 $GLOBALS['number_decimal_separator'],
1850 $GLOBALS['number_thousands_separator']);
1853 // this units needs no translation, ISO
1874 // we need at least 3 digits to be displayed
1875 if (3 > $length +
$comma) {
1876 $length = 3 - $comma;
1879 // check for negativ value to retain sign
1882 $value = abs($value);
1887 $dh = pow(10, $comma);
1888 $li = pow(10, $length);
1892 for ($d = 8; $d >= 0; $d--) {
1893 if (isset($units[$d]) && $value >= $li * pow(1000, $d-1)) {
1894 $value = round($value / (pow(1000, $d) / $dh)) /$dh;
1899 } elseif (!$only_down && (float) $value !== 0.0) {
1900 for ($d = -8; $d <= 8; $d++
) {
1901 if (isset($units[$d]) && $value <= $li * pow(1000, $d-1)) {
1902 $value = round($value / (pow(1000, $d) / $dh)) /$dh;
1907 } // end if ($value >= 1) elseif (!$only_down && (float) $value !== 0.0)
1909 $value = number_format($value,
1911 $GLOBALS['number_decimal_separator'],
1912 $GLOBALS['number_thousands_separator']);
1914 return $sign . $value . ' ' . $unit;
1915 } // end of the 'PMA_formatNumber' function
1918 * Extracts ENUM / SET options from a type definition string
1920 * @param string The column type definition
1922 * @return array The options or
1923 * boolean false in case of an error.
1927 function PMA_getEnumSetOptions($type_def)
1929 $open = strpos($type_def, '(');
1930 $close = strrpos($type_def, ')');
1931 if (!$open ||
!$close) {
1934 $options = substr($type_def, $open +
2, $close - $open - 3);
1935 $options = explode('\',\'', $options);
1937 } // end of the 'PMA_getEnumSetOptions' function
1940 * Writes localised date
1942 * @param string the current timestamp
1944 * @return string the formatted date
1948 function PMA_localisedDate($timestamp = -1, $format = '')
1950 global $datefmt, $month, $day_of_week;
1952 if ($format == '') {
1956 if ($timestamp == -1) {
1957 $timestamp = time();
1960 $date = preg_replace('@%[aA]@', $day_of_week[(int)strftime('%w', $timestamp)], $format);
1961 $date = preg_replace('@%[bB]@', $month[(int)strftime('%m', $timestamp)-1], $date);
1963 return strftime($date, $timestamp);
1964 } // end of the 'PMA_localisedDate()' function
1968 * returns a tab for tabbed navigation.
1969 * If the variables $link and $args ar left empty, an inactive tab is created
1971 * @uses array_merge()
1973 * $GLOBALS['strEmpty']
1974 * $GLOBALS['strDrop']
1975 * $GLOBALS['active_page']
1976 * $GLOBALS['PHP_SELF']
1978 * PMA_generate_common_url()
1979 * $GLOBALS['url_query']
1981 * $GLOBALS['cfg']['MainPageIconic']
1982 * $GLOBALS['pmaThemeImage']
1986 * @param array $tab array with all options
1987 * @return string html code for one tab, a link if valid otherwise a span
1990 function PMA_getTab($tab)
2003 $tab = array_merge($defaults, $tab);
2005 // determine additionnal style-class
2006 if (empty($tab['class'])) {
2007 if ($tab['text'] == $GLOBALS['strEmpty']
2008 ||
$tab['text'] == $GLOBALS['strDrop']) {
2009 $tab['class'] = 'caution';
2010 } elseif (!empty($tab['active'])
2011 ||
(isset($GLOBALS['active_page'])
2012 && $GLOBALS['active_page'] == $tab['link'])
2013 ||
basename(PMA_getenv('PHP_SELF')) == $tab['link'])
2015 $tab['class'] = 'active';
2020 if (!empty($tab['link'])) {
2021 $tab['link'] = htmlentities($tab['link']);
2022 $tab['link'] = $tab['link'] . $tab['sep']
2023 .(empty($GLOBALS['url_query']) ?
2024 PMA_generate_common_url() : $GLOBALS['url_query']);
2025 if (!empty($tab['args'])) {
2026 foreach ($tab['args'] as $param => $value) {
2027 $tab['link'] .= '&' . urlencode($param) . '='
2028 . urlencode($value);
2033 // display icon, even if iconic is disabled but the link-text is missing
2034 if (($GLOBALS['cfg']['MainPageIconic'] ||
empty($tab['text']))
2035 && isset($tab['icon'])) {
2036 $image = '<img class="icon" src="' . htmlentities($GLOBALS['pmaThemeImage'])
2037 .'%1$s" width="16" height="16" alt="%2$s" />%2$s';
2038 $tab['text'] = sprintf($image, htmlentities($tab['icon']), $tab['text']);
2040 // check to not display an empty link-text
2041 elseif (empty($tab['text'])) {
2043 trigger_error('empty linktext in function ' . __FUNCTION__
. '()',
2047 if (!empty($tab['link'])) {
2048 $out = '<a class="tab' . htmlentities($tab['class']) . '"'
2049 .' href="' . $tab['link'] . '" ' . $tab['attr'] . '>'
2050 . $tab['text'] . '</a>';
2052 $out = '<span class="tab' . htmlentities($tab['class']) . '">'
2053 . $tab['text'] . '</span>';
2057 } // end of the 'PMA_getTab()' function
2060 * returns html-code for a tab navigation
2062 * @uses PMA_getTab()
2063 * @uses htmlentities()
2064 * @param array $tabs one element per tab
2065 * @param string $tag_id id used for the html-tag
2066 * @return string html-code for tab-navigation
2068 function PMA_getTabs($tabs, $tag_id = 'topmenu')
2071 '<div id="' . htmlentities($tag_id) . 'container">' . "\n"
2072 .'<ul id="' . htmlentities($tag_id) . '">' . "\n";
2074 foreach ($tabs as $tab) {
2075 $tab_navigation .= '<li>' . PMA_getTab($tab) . '</li>' . "\n";
2080 .'<div class="clearfloat"></div>'
2083 return $tab_navigation;
2088 * Displays a link, or a button if the link's URL is too large, to
2089 * accommodate some browsers' limitations
2091 * @param string the URL
2092 * @param string the link message
2093 * @param mixed $tag_params string: js confirmation
2094 * array: additional tag params (f.e. style="")
2095 * @param boolean $new_form we set this to false when we are already in
2096 * a form, to avoid generating nested forms
2098 * @return string the results to be echoed or saved in an array
2100 function PMA_linkOrButton($url, $message, $tag_params = array(),
2101 $new_form = true, $strip_img = false, $target = '')
2103 if (! is_array($tag_params)) {
2105 $tag_params = array();
2107 $tag_params['onclick'] = 'return confirmLink(this, \'' . $tmp . '\')';
2111 if (! empty($target)) {
2112 $tag_params['target'] = htmlentities($target);
2115 $tag_params_strings = array();
2116 foreach ($tag_params as $par_name => $par_value) {
2117 // htmlspecialchars() only on non javascript
2118 $par_value = substr($par_name, 0, 2) == 'on'
2120 : htmlspecialchars($par_value);
2121 $tag_params_strings[] = $par_name . '="' . $par_value . '"';
2124 // previously the limit was set to 2047, it seems 1000 is better
2125 if (strlen($url) <= 1000) {
2126 // no whitespace within an <a> else Safari will make it part of the link
2127 $ret = "\n" . '<a href="' . $url . '" '
2128 . implode(' ', $tag_params_strings) . '>'
2129 . $message . '</a>' . "\n";
2131 // no spaces (linebreaks) at all
2132 // or after the hidden fields
2133 // IE will display them all
2135 // add class=link to submit button
2136 if (empty($tag_params['class'])) {
2137 $tag_params['class'] = 'link';
2140 // decode encoded url separators
2141 $separator = PMA_get_arg_separator();
2142 // on most places separator is still hard coded ...
2143 if ($separator !== '&') {
2144 // ... so always replace & with $separator
2145 $url = str_replace(htmlentities('&'), $separator, $url);
2146 $url = str_replace('&', $separator, $url);
2148 $url = str_replace(htmlentities($separator), $separator, $url);
2151 $url_parts = parse_url($url);
2152 $query_parts = explode($separator, $url_parts['query']);
2154 $ret = '<form action="' . $url_parts['path'] . '" class="link"'
2155 . ' method="post"' . $target . ' style="display: inline;">';
2157 $subname_close = '';
2160 $query_parts[] = 'redirect=' . $url_parts['path'];
2161 if (empty($GLOBALS['subform_counter'])) {
2162 $GLOBALS['subform_counter'] = 0;
2164 $GLOBALS['subform_counter']++
;
2166 $subname_open = 'subform[' . $GLOBALS['subform_counter'] . '][';
2167 $subname_close = ']';
2168 $submit_name = ' name="usesubform[' . $GLOBALS['subform_counter'] . ']"';
2170 foreach ($query_parts as $query_pair) {
2171 list($eachvar, $eachval) = explode('=', $query_pair);
2172 $ret .= '<input type="hidden" name="' . $subname_open . $eachvar
2173 . $subname_close . '" value="'
2174 . htmlspecialchars(urldecode($eachval)) . '" />';
2177 if (stristr($message, '<img')) {
2179 $message = trim(strip_tags($message));
2180 $ret .= '<input type="submit"' . $submit_name . ' '
2181 . implode(' ', $tag_params_strings)
2182 . ' value="' . htmlspecialchars($message) . '" />';
2184 $ret .= '<input type="image"' . $submit_name . ' '
2185 . implode(' ', $tag_params_strings)
2186 . ' src="' . preg_replace(
2187 '/^.*\ssrc="([^"]*)".*$/si', '\1', $message) . '"'
2188 . ' value="' . htmlspecialchars(
2189 preg_replace('/^.*\salt="([^"]*)".*$/si', '\1',
2194 $message = trim(strip_tags($message));
2195 $ret .= '<input type="submit"' . $submit_name . ' '
2196 . implode(' ', $tag_params_strings)
2197 . ' value="' . htmlspecialchars($message) . '" />';
2202 } // end if... else...
2205 } // end of the 'PMA_linkOrButton()' function
2209 * Returns a given timespan value in a readable format.
2211 * @param int the timespan
2213 * @return string the formatted value
2215 function PMA_timespanFormat($seconds)
2217 $return_string = '';
2218 $days = floor($seconds / 86400);
2220 $seconds -= $days * 86400;
2222 $hours = floor($seconds / 3600);
2223 if ($days > 0 ||
$hours > 0) {
2224 $seconds -= $hours * 3600;
2226 $minutes = floor($seconds / 60);
2227 if ($days > 0 ||
$hours > 0 ||
$minutes > 0) {
2228 $seconds -= $minutes * 60;
2230 return sprintf($GLOBALS['timespanfmt'], (string)$days, (string)$hours, (string)$minutes, (string)$seconds);
2234 * Takes a string and outputs each character on a line for itself. Used
2235 * mainly for horizontalflipped display mode.
2236 * Takes care of special html-characters.
2237 * Fulfills todo-item
2238 * http://sf.net/tracker/?func=detail&aid=544361&group_id=23067&atid=377411
2240 * @param string The string
2241 * @param string The Separator (defaults to "<br />\n")
2244 * @author Garvin Hicking <me@supergarv.de>
2245 * @return string The flipped string
2247 function PMA_flipstring($string, $Separator = "<br />\n")
2249 $format_string = '';
2252 for ($i = 0; $i < strlen($string); $i++
) {
2253 $char = $string{$i};
2257 $format_string .= $charbuff;
2260 } elseif (!empty($charbuff)) {
2262 } elseif ($char == ';' && !empty($charbuff)) {
2263 $format_string .= $charbuff;
2267 $format_string .= $char;
2271 if ($append && ($i != strlen($string))) {
2272 $format_string .= $Separator;
2276 return $format_string;
2281 * Function added to avoid path disclosures.
2282 * Called by each script that needs parameters, it displays
2283 * an error message and, by default, stops the execution.
2285 * Not sure we could use a strMissingParameter message here,
2286 * would have to check if the error message file is always available
2288 * @param array The names of the parameters needed by the calling
2290 * @param boolean Stop the execution?
2291 * (Set this manually to false in the calling script
2292 * until you know all needed parameters to check).
2293 * @param boolean Whether to include this list in checking for special params.
2294 * @global string path to current script
2295 * @global boolean flag whether any special variable was required
2298 * @author Marc Delisle (lem9@users.sourceforge.net)
2300 function PMA_checkParameters($params, $die = true, $request = true)
2302 global $PHP_SELF, $checked_special;
2304 if (!isset($checked_special)) {
2305 $checked_special = false;
2308 $reported_script_name = basename($PHP_SELF);
2309 $found_error = false;
2310 $error_message = '';
2312 foreach ($params as $param) {
2313 if ($request && $param != 'db' && $param != 'table') {
2314 $checked_special = true;
2317 if (!isset($GLOBALS[$param])) {
2318 $error_message .= $reported_script_name . ': Missing parameter: ' . $param . ' <a href="./Documentation.html#faqmissingparameters" target="documentation"> (FAQ 2.8)</a><br />';
2319 $found_error = true;
2323 require_once './libraries/header_meta_style.inc.php';
2324 echo '</head><body><p>' . $error_message . '</p></body></html>';
2332 * Function to generate unique condition for specified row.
2334 * @uses PMA_MYSQL_INT_VERSION
2335 * @uses $GLOBALS['analyzed_sql'][0]
2336 * @uses PMA_DBI_field_flags()
2337 * @uses PMA_backquote()
2338 * @uses PMA_sqlAddslashes()
2341 * @uses preg_replace()
2342 * @param resource $handle current query result
2343 * @param integer $fields_cnt number of fields
2344 * @param array $fields_meta meta information about fields
2345 * @param array $row current row
2348 * @author Michal Cihar (michal@cihar.com)
2349 * @return string calculated condition
2351 function PMA_getUvaCondition($handle, $fields_cnt, $fields_meta, $row)
2355 $uva_nonprimary_condition = '';
2357 for ($i = 0; $i < $fields_cnt; ++
$i) {
2358 $field_flags = PMA_DBI_field_flags($handle, $i);
2359 $meta = $fields_meta[$i];
2361 // do not use an alias in a condition
2362 if (! isset($meta->orgname
) ||
! strlen($meta->orgname
)) {
2363 $meta->orgname
= $meta->name
;
2365 if (isset($GLOBALS['analyzed_sql'][0]['select_expr'])
2366 && is_array($GLOBALS['analyzed_sql'][0]['select_expr'])) {
2367 foreach ($GLOBALS['analyzed_sql'][0]['select_expr']
2369 // need (string) === (string)
2370 // '' !== 0 but '' == 0
2371 if ((string) $select_expr['alias'] === (string) $meta->name
) {
2372 $meta->orgname
= $select_expr['column'];
2380 // to fix the bug where float fields (primary or not)
2381 // can't be matched because of the imprecision of
2382 // floating comparison, use CONCAT
2383 // (also, the syntax "CONCAT(field) IS NULL"
2384 // that we need on the next "if" will work)
2385 if ($meta->type
== 'real') {
2386 $condition = ' CONCAT(' . PMA_backquote($meta->table
) . '.'
2387 . PMA_backquote($meta->orgname
) . ') ';
2389 // string and blob fields have to be converted using
2390 // the system character set (always utf8) since
2391 // mysql4.1 can use different charset for fields.
2392 if (PMA_MYSQL_INT_VERSION
>= 40100
2393 && ($meta->type
== 'string' ||
$meta->type
== 'blob')) {
2394 $condition = ' CONVERT(' . PMA_backquote($meta->table
) . '.'
2395 . PMA_backquote($meta->orgname
) . ' USING utf8) ';
2397 $condition = ' ' . PMA_backquote($meta->table
) . '.'
2398 . PMA_backquote($meta->orgname
) . ' ';
2400 } // end if... else...
2402 if (!isset($row[$i]) ||
is_null($row[$i])) {
2403 $condition .= 'IS NULL AND';
2405 // timestamp is numeric on some MySQL 4.1
2406 if ($meta->numeric && $meta->type
!= 'timestamp') {
2407 $condition .= '= ' . $row[$i] . ' AND';
2408 } elseif ($meta->type
== 'blob'
2409 // hexify only if this is a true not empty BLOB
2410 && stristr($field_flags, 'BINARY')
2411 && !empty($row[$i])) {
2412 // use a CAST if possible, to avoid problems
2413 // if the field contains wildcard characters % or _
2414 if (PMA_MYSQL_INT_VERSION
< 40002) {
2415 $condition .= 'LIKE 0x' . bin2hex($row[$i]) . ' AND';
2417 $condition .= '= CAST(0x' . bin2hex($row[$i])
2418 . ' AS BINARY) AND';
2421 $condition .= '= \''
2422 . PMA_sqlAddslashes($row[$i], false, true) . '\' AND';
2425 if ($meta->primary_key
> 0) {
2426 $primary_key .= $condition;
2427 } elseif ($meta->unique_key
> 0) {
2428 $unique_key .= $condition;
2430 $uva_nonprimary_condition .= $condition;
2433 // Correction uva 19991216: prefer primary or unique keys
2434 // for condition, but use conjunction of all values if no
2437 $uva_condition = $primary_key;
2438 } elseif ($unique_key) {
2439 $uva_condition = $unique_key;
2441 $uva_condition = $uva_nonprimary_condition;
2444 return preg_replace('|\s?AND$|', '', $uva_condition);
2448 * Function to generate unique condition for specified row.
2450 * @param string name of button element
2451 * @param string class of button element
2452 * @param string name of image element
2453 * @param string text to display
2454 * @param string image to display
2457 * @author Michal Cihar (michal@cihar.com)
2459 function PMA_buttonOrImage($button_name, $button_class, $image_name, $text,
2462 global $pmaThemeImage, $propicon;
2464 /* Opera has trouble with <input type="image"> */
2465 /* IE has trouble with <button> */
2466 if (PMA_USR_BROWSER_AGENT
!= 'IE') {
2467 echo '<button class="' . $button_class . '" type="submit"'
2468 .' name="' . $button_name . '" value="' . $text . '"'
2469 .' title="' . $text . '">' . "\n"
2470 .'<img class="icon" src="' . $pmaThemeImage . $image . '"'
2471 .' title="' . $text . '" alt="' . $text . '" width="16"'
2473 .($propicon == 'both' ?
' ' . $text : '') . "\n"
2474 .'</button>' . "\n";
2476 echo '<input type="image" name="' . $image_name . '" value="'
2477 . $text . '" title="' . $text . '" src="' . $pmaThemeImage
2479 . ($propicon == 'both' ?
' ' . $text : '') . "\n";
2484 * Generate a pagination selector for browsing resultsets
2486 * @param string URL for the JavaScript
2487 * @param string Number of rows in the pagination set
2488 * @param string current page number
2489 * @param string number of total pages
2490 * @param string If the number of pages is lower than this
2491 * variable, no pages will be ommitted in
2493 * @param string How many rows at the beginning should always
2495 * @param string How many rows at the end should always
2497 * @param string Percentage of calculation page offsets to
2498 * hop to a next page
2499 * @param string Near the current page, how many pages should
2500 * be considered "nearby" and displayed as
2504 * @author Garvin Hicking (pma@supergarv.de)
2506 function PMA_pageselector($url, $rows, $pageNow = 1, $nbTotalPage = 1,
2507 $showAll = 200, $sliceStart = 5, $sliceEnd = 5, $percent = 20,
2510 $gotopage = $GLOBALS['strPageNumber']
2511 . ' <select name="goToPage" onchange="goToUrl(this, \''
2512 . $url . '\');">' . "\n";
2513 if ($nbTotalPage < $showAll) {
2514 $pages = range(1, $nbTotalPage);
2518 // Always show first X pages
2519 for ($i = 1; $i <= $sliceStart; $i++
) {
2523 // Always show last X pages
2524 for ($i = $nbTotalPage - $sliceEnd; $i <= $nbTotalPage; $i++
) {
2528 // garvin: Based on the number of results we add the specified
2529 // $percent percentate to each page number,
2530 // so that we have a representing page number every now and then to
2531 // immideately jump to specific pages.
2532 // As soon as we get near our currently chosen page ($pageNow -
2533 // $range), every page number will be
2536 $x = $nbTotalPage - $sliceEnd;
2537 $met_boundary = false;
2539 if ($i >= ($pageNow - $range) && $i <= ($pageNow +
$range)) {
2540 // If our pageselector comes near the current page, we use 1
2541 // counter increments
2543 $met_boundary = true;
2545 // We add the percentate increment to our current page to
2546 // hop to the next one in range
2547 $i = $i +
floor($nbTotalPage / $percent);
2549 // Make sure that we do not cross our boundaries.
2550 if ($i > ($pageNow - $range) && !$met_boundary) {
2551 $i = $pageNow - $range;
2555 if ($i > 0 && $i <= $x) {
2560 // Since because of ellipsing of the current page some numbers may be double,
2561 // we unify our array:
2563 $pages = array_unique($pages);
2566 foreach ($pages as $i) {
2567 if ($i == $pageNow) {
2568 $selected = 'selected="selected" style="font-weight: bold"';
2572 $gotopage .= ' <option ' . $selected . ' value="' . (($i - 1) * $rows) . '">' . $i . '</option>' . "\n";
2575 $gotopage .= ' </select>';
2581 * @TODO add documentation
2583 function PMA_userDir($dir)
2587 if (substr($dir, -1) != '/') {
2591 return str_replace('%u', $cfg['Server']['user'], $dir);
2595 * returns html code for db link to default db page
2597 * @uses $GLOBALS['cfg']['DefaultTabDatabase']
2598 * @uses $GLOBALS['db']
2599 * @uses $GLOBALS['strJumpToDB']
2600 * @uses PMA_generate_common_url()
2601 * @param string $database
2602 * @return string html link to default db page
2604 function PMA_getDbLink($database = null)
2606 if (!strlen($database)) {
2607 if (!strlen($GLOBALS['db'])) {
2610 $database = $GLOBALS['db'];
2612 $database = PMA_unescape_mysql_wildcards($database);
2615 return '<a href="' . $GLOBALS['cfg']['DefaultTabDatabase'] . '?' . PMA_generate_common_url($database) . '"'
2616 .' title="' . sprintf($GLOBALS['strJumpToDB'], htmlspecialchars($database)) . '">'
2617 .htmlspecialchars($database) . '</a>';
2623 * @uses PMA_Config::isHttps()
2624 * @uses PMA_Config::getCookiePath()
2627 * @param string $cookie name of cookie to remove
2628 * @return boolean result of setcookie()
2630 function PMA_removeCookie($cookie)
2632 return setcookie($cookie, '', time() - 3600,
2633 PMA_Config
::getCookiePath(), '', PMA_Config
::isHttps());
2637 * sets cookie if value is different from current cokkie value,
2638 * or removes if value is equal to default
2640 * @uses PMA_Config::isHttps()
2641 * @uses PMA_Config::getCookiePath()
2643 * @uses PMA_removeCookie()
2646 * @param string $cookie name of cookie to remove
2647 * @param mixed $value new cookie value
2648 * @param string $default default value
2649 * @return boolean result of setcookie()
2651 function PMA_setCookie($cookie, $value, $default = null)
2653 if (strlen($value) && null !== $default && $value === $default
2654 && isset($_COOKIE[$cookie])) {
2655 // remove cookie, default value is used
2656 return PMA_removeCookie($cookie);
2659 if (! strlen($value) && isset($_COOKIE[$cookie])) {
2660 // remove cookie, value is empty
2661 return PMA_removeCookie($cookie);
2664 if (! isset($_COOKIE[$cookie]) ||
$_COOKIE[$cookie] !== $value) {
2665 // set cookie with new value
2666 return setcookie($cookie, $value, time() +
60*60*24*30,
2667 PMA_Config
::getCookiePath(), '', PMA_Config
::isHttps());
2670 // cookie has already $value as value
2676 * include here only libraries which contain only function definitions
2677 * no code im main()!
2680 * Include URL/hidden inputs generating.
2682 require_once './libraries/url_generating.lib.php';
2687 /******************************************************************************/
2688 /* start procedural code label_start_procedural */
2691 * protect against older PHP versions' bug about GLOBALS overwrite
2692 * (no need to localize this message :))
2693 * but what if script.php?GLOBALS[admin]=1&GLOBALS[_REQUEST]=1 ???
2695 if (isset($_REQUEST['GLOBALS']) ||
isset($_FILES['GLOBALS'])
2696 ||
isset($_SERVER['GLOBALS']) ||
isset($_COOKIE['GLOBALS'])
2697 ||
isset($_ENV['GLOBALS'])) {
2698 die('GLOBALS overwrite attempt');
2702 * Check for numeric keys
2703 * (if register_globals is on, numeric key can be found in $GLOBALS)
2706 foreach ($GLOBALS as $key => $dummy) {
2707 if (is_numeric($key)) {
2708 die('numeric key detected');
2713 * just to be sure there was no import (registering) before here
2714 * we empty the global space
2716 $variables_whitelist = array (
2728 foreach (get_defined_vars() as $key => $value) {
2729 if (!in_array($key, $variables_whitelist)) {
2733 unset($key, $value);
2737 * check if a subform is submitted
2740 if (isset($_POST['usesubform'])) {
2741 // if a subform is present and should be used
2742 // the rest of the form is deprecated
2743 $subform_id = key($_POST['usesubform']);
2744 $subform = $_POST['subform'][$subform_id];
2746 $_REQUEST = $subform;
2747 if (isset($_POST['redirect'])
2748 && $_POST['redirect'] != basename(PMA_getenv('PHP_SELF'))) {
2749 $__redirect = $_POST['redirect'];
2750 unset($_POST['redirect']);
2751 } // end if (isset($_POST['redirect']))
2752 unset($subform_id, $subform);
2753 } // end if (isset($_POST['usesubform']))
2754 // end check if a subform is submitted
2756 if (get_magic_quotes_gpc()) {
2757 PMA_arrayWalkRecursive($_GET, 'stripslashes', true);
2758 PMA_arrayWalkRecursive($_POST, 'stripslashes', true);
2759 PMA_arrayWalkRecursive($_COOKIE, 'stripslashes', true);
2760 PMA_arrayWalkRecursive($_REQUEST, 'stripslashes', true);
2764 * include deprecated grab_globals only if required
2766 if (empty($__redirect) && !defined('PMA_NO_VARIABLES_IMPORT')) {
2767 require './libraries/grab_globals.lib.php';
2771 * include session handling after the globals, to avoid overwriting
2773 require_once './libraries/session.inc.php';
2776 * init some variables LABEL_variables_init
2780 * @var array $GLOBALS['PMA_errors'] holds errors
2782 $GLOBALS['PMA_errors'] = array();
2785 * @var array $GLOBALS['url_params'] holds params to be passed to next page
2787 $GLOBALS['url_params'] = array();
2790 * @var array whitelist for $goto
2792 $goto_whitelist = array(
2793 //'browse_foreigners.php',
2800 'db_details_export.php',
2801 'db_details_importdocsql.php',
2802 'db_details_qbe.php',
2803 'db_details_structure.php',
2805 'db_operations.php',
2808 //'Documentation.html',
2821 'server_binlog.php',
2822 'server_collations.php',
2823 'server_databases.php',
2824 'server_engines.php',
2825 'server_export.php',
2826 'server_import.php',
2827 'server_privileges.php',
2828 'server_processlist.php',
2830 'server_status.php',
2831 'server_variables.php',
2839 'tbl_move_copy.php',
2840 'tbl_printview.php',
2841 'tbl_properties.php',
2842 'tbl_properties_export.php',
2843 'tbl_properties_operations.php',
2844 'tbl_properties_structure.php',
2847 'tbl_row_action.php',
2850 'transformation_overview.php',
2851 'transformation_wrapper.php',
2853 'user_password.php',
2857 * check $__redirect against whitelist
2859 if (! PMA_checkPageValidity($__redirect, $goto_whitelist)) {
2864 * @var string $goto holds page that should be displayed
2866 // Security fix: disallow accessing serious server files via "?goto="
2867 if (PMA_checkPageValidity($_REQUEST['goto'], $goto_whitelist)) {
2868 $GLOBALS['goto'] = $_REQUEST['goto'];
2869 $GLOBALS['url_params']['goto'] = $_REQUEST['goto'];
2871 unset($_REQUEST['goto'], $_GET['goto'], $_POST['goto'], $_COOKIE['goto']);
2872 $GLOBALS['goto'] = '';
2876 * @var string $back returning page
2878 if (PMA_checkPageValidity($_REQUEST['back'], $goto_whitelist)) {
2879 $GLOBALS['back'] = $_REQUEST['back'];
2881 unset($_REQUEST['back'], $_GET['back'], $_POST['back'], $_COOKIE['back']);
2885 * Check whether user supplied token is valid, if not remove any
2886 * possibly dangerous stuff from request.
2888 if ((isset($_REQUEST['token']) && !is_string($_REQUEST['token'])) ||
empty($_REQUEST['token']) ||
$_SESSION[' PMA_token '] != $_REQUEST['token']) {
2889 /* List of parameters which are allowed from unsafe source */
2890 $allow_list = array(
2891 'db', 'table', 'lang', 'server', 'convcharset', 'collation_connection', 'target',
2894 /* Cookie preferences */
2895 'pma_lang', 'pma_charset', 'pma_collation_connection', 'pma_convcharset',
2896 /* Possible login form */
2897 'pma_servername', 'pma_username', 'pma_password',
2899 // do not check only $_REQUEST because it could have been overwritten
2900 // and use type casting because the variables could have become
2902 $keys = array_keys(array_merge((array)$_REQUEST, (array)$_GET, (array)$_POST, (array)$_COOKIE));
2904 /* Remove any non allowed stuff from requests */
2905 foreach($keys as $key) {
2906 if (!in_array($key, $allow_list)) {
2907 unset($_REQUEST[$key]);
2909 unset($_POST[$key]);
2910 unset($GLOBALS[$key]);
2912 // we require it to be a string
2913 if (isset($_REQUEST[$key]) && is_string($_REQUEST[$key])) {
2914 $_REQUEST[$key] = htmlspecialchars($_REQUEST[$key], ENT_QUOTES
);
2916 unset($_REQUEST[$key]);
2918 if (isset($_POST[$key]) && is_string($_POST[$key])) {
2919 $_POST[$key] = htmlspecialchars($_POST[$key], ENT_QUOTES
);
2921 unset($_POST[$key]);
2923 if (isset($_COOKIE[$key]) && is_string($_COOKIE[$key])) {
2924 $_COOKIE[$key] = htmlspecialchars($_COOKIE[$key], ENT_QUOTES
);
2926 unset($_COOKIE[$key]);
2928 if (isset($_GET[$key]) && is_string($_GET[$key])) {
2929 $_GET[$key] = htmlspecialchars($_GET[$key], ENT_QUOTES
);
2939 * @var string $convcharset
2940 * @see also select_lang.lib.php
2942 if (isset($_REQUEST['convcharset'])) {
2943 $convcharset = strip_tags($_REQUEST['convcharset']);
2947 * @var string $db current selected database
2949 if (isset($_REQUEST['db']) && is_string($_REQUEST['db'])) {
2950 // can we strip tags from this?
2951 // only \ and / is not allowed in db names for MySQL
2952 $GLOBALS['db'] = $_REQUEST['db'];
2953 $GLOBALS['url_params']['db'] = $GLOBALS['db'];
2955 $GLOBALS['db'] = '';
2959 * @var string $db current selected database
2961 if (isset($_REQUEST['table']) && is_string($_REQUEST['table'])) {
2962 // can we strip tags from this?
2963 // only \ and / is not allowed in table names for MySQL
2964 $GLOBALS['table'] = $_REQUEST['table'];
2965 $GLOBALS['url_params']['table'] = $GLOBALS['table'];
2967 $GLOBALS['table'] = '';
2971 * @var string $sql_query sql query to be executed
2973 if (isset($_REQUEST['sql_query']) && is_string($_REQUEST['sql_query'])) {
2974 $GLOBALS['sql_query'] = $_REQUEST['sql_query'];
2977 //$_REQUEST['set_theme'] // checked later in this file LABEL_theme_setup
2978 //$_REQUEST['server']; // checked later in this file
2979 //$_REQUEST['lang']; // checked by LABEL_loading_language_file
2983 /******************************************************************************/
2984 /* parsing config file LABEL_parsing_config_file */
2986 if (empty($_SESSION['PMA_Config'])) {
2988 * We really need this one!
2990 if (!function_exists('preg_replace')) {
2991 header('Location: error.php'
2992 . '?lang=' . urlencode($available_languages[$lang][2])
2993 . '&dir=' . urlencode($text_dir)
2994 . '&type=' . urlencode($strError)
2995 . '&error=' . urlencode(
2996 strtr(sprintf($strCantLoad, 'pcre'),
2997 array('<br />' => '[br]')))
3003 $_SESSION['PMA_Config'] = new PMA_Config('./config.inc.php');
3005 } elseif (version_compare(phpversion(), '5', 'lt')) {
3006 $_SESSION['PMA_Config']->__wakeup();
3009 if (!defined('PMA_MINIMUM_COMMON')) {
3010 $_SESSION['PMA_Config']->checkPmaAbsoluteUri();
3014 $_SESSION['PMA_Config']->enableBc();
3018 * check https connection
3020 if ($_SESSION['PMA_Config']->get('ForceSSL')
3021 && !$_SESSION['PMA_Config']->get('is_https')) {
3022 PMA_sendHeaderLocation(
3023 preg_replace('/^http/', 'https',
3024 $_SESSION['PMA_Config']->get('PmaAbsoluteUri'))
3025 . PMA_generate_common_url($_GET));
3030 /******************************************************************************/
3031 /* loading language file LABEL_loading_language_file */
3034 * Added messages while developing:
3036 if (file_exists('./lang/added_messages.php')) {
3037 include './lang/added_messages.php';
3041 * Includes the language file if it hasn't been included yet
3043 require './libraries/language.lib.php';
3047 * check for errors occured while loading config
3049 if ($_SESSION['PMA_Config']->error_config_file
) {
3050 $GLOBALS['PMA_errors'][] = $strConfigFileError
3052 . ($_SESSION['PMA_Config']->getSource() == './config.inc.php' ?
3053 '<a href="show_config_errors.php"'
3054 .' target="_blank">' . $_SESSION['PMA_Config']->getSource() . '</a>'
3056 '<a href="' . $_SESSION['PMA_Config']->getSource() . '"'
3057 .' target="_blank">' . $_SESSION['PMA_Config']->getSource() . '</a>');
3059 if ($_SESSION['PMA_Config']->error_config_default_file
) {
3060 $GLOBALS['PMA_errors'][] = sprintf($strConfigDefaultFileError,
3061 $_SESSION['PMA_Config']->default_source
);
3063 if ($_SESSION['PMA_Config']->error_pma_uri
) {
3064 $GLOBALS['PMA_errors'][] = sprintf($strPmaUriError);
3068 * Servers array fixups.
3069 * $default_server comes from PMA_Config::enableBc()
3070 * @todo merge into PMA_Config
3072 // Do we have some server?
3073 if (!isset($cfg['Servers']) ||
count($cfg['Servers']) == 0) {
3074 // No server => create one with defaults
3075 $cfg['Servers'] = array(1 => $default_server);
3077 // We have server(s) => apply default config
3078 $new_servers = array();
3080 foreach ($cfg['Servers'] as $server_index => $each_server) {
3082 // Detect wrong configuration
3083 if (!is_int($server_index) ||
$server_index < 1) {
3084 $GLOBALS['PMA_errors'][] = sprintf($strInvalidServerIndex, $server_index);
3087 $each_server = array_merge($default_server, $each_server);
3089 // Don't use servers with no hostname
3090 if ($each_server['connect_type'] == 'tcp' && empty($each_server['host'])) {
3091 $GLOBALS['PMA_errors'][] = sprintf($strInvalidServerHostname, $server_index);
3094 // Final solution to bug #582890
3095 // If we are using a socket connection
3096 // and there is nothing in the verbose server name
3097 // or the host field, then generate a name for the server
3098 // in the form of "Server 2", localized of course!
3099 if ($each_server['connect_type'] == 'socket' && empty($each_server['host']) && empty($each_server['verbose'])) {
3100 $each_server['verbose'] = $GLOBALS['strServer'] . $server_index;
3103 $new_servers[$server_index] = $each_server;
3105 $cfg['Servers'] = $new_servers;
3106 unset($new_servers, $server_index, $each_server);
3110 unset($default_server);
3113 /******************************************************************************/
3114 /* setup themes LABEL_theme_setup */
3116 if (! isset($_SESSION['PMA_Theme_Manager'])) {
3117 $_SESSION['PMA_Theme_Manager'] = new PMA_Theme_Manager
;
3119 $_SESSION['PMA_Theme_Manager']->checkConfig();
3122 if (isset($_REQUEST['set_theme'])) {
3123 // if user submit a theme
3124 $_SESSION['PMA_Theme_Manager']->setActiveTheme($_REQUEST['set_theme']);
3127 $_SESSION['PMA_Theme'] = $_SESSION['PMA_Theme_Manager']->theme
;
3130 $GLOBALS['theme'] = $_SESSION['PMA_Theme']->getName();
3131 $GLOBALS['pmaThemePath'] = $_SESSION['PMA_Theme']->getPath();
3132 $GLOBALS['pmaThemeImage'] = $_SESSION['PMA_Theme']->getImgPath();
3135 * load layout file if exists
3137 if (@file_exists
($_SESSION['PMA_Theme']->getLayoutFile())) {
3138 include $_SESSION['PMA_Theme']->getLayoutFile();
3139 // @todo remove if all themes are update use Navi instead of Left as frame name
3140 if (! isset($GLOBALS['cfg']['NaviWidth'])
3141 && isset($GLOBALS['cfg']['LeftWidth'])) {
3142 $GLOBALS['cfg']['NaviWidth'] = $GLOBALS['cfg']['LeftWidth'];
3146 if (! defined('PMA_MINIMUM_COMMON')) {
3148 * Charset conversion.
3150 require_once './libraries/charset_conversion.lib.php';
3155 require_once './libraries/string.lib.php';
3158 * @var array database list
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.
3170 if (isset($_REQUEST['server']) && is_string($_REQUEST['server']) && ! empty($_REQUEST['server']) && ! empty($cfg['Servers'][$_REQUEST['server']])) {
3171 $GLOBALS['server'] = $_REQUEST['server'];
3172 $cfg['Server'] = $cfg['Servers'][$GLOBALS['server']];
3174 if (!empty($cfg['Servers'][$cfg['ServerDefault']])) {
3175 $GLOBALS['server'] = $cfg['ServerDefault'];
3176 $cfg['Server'] = $cfg['Servers'][$GLOBALS['server']];
3178 $GLOBALS['server'] = 0;
3179 $cfg['Server'] = array();
3182 $GLOBALS['url_params']['server'] = $GLOBALS['server'];
3185 if (!empty($cfg['Server'])) {
3188 * Loads the proper database interface for this server
3190 require_once './libraries/database_interface.lib.php';
3192 // Gets the authentication library that fits the $cfg['Server'] settings
3193 // and run authentication
3195 // (for a quick check of path disclosure in auth/cookies:)
3196 $coming_from_common = true;
3198 // to allow HTTP or http
3199 $cfg['Server']['auth_type'] = strtolower($cfg['Server']['auth_type']);
3200 if (!file_exists('./libraries/auth/' . $cfg['Server']['auth_type'] . '.auth.lib.php')) {
3201 header('Location: error.php'
3202 . '?lang=' . urlencode($available_languages[$lang][2])
3203 . '&dir=' . urlencode($text_dir)
3204 . '&type=' . urlencode($strError)
3205 . '&error=' . urlencode(
3206 $strInvalidAuthMethod . ' '
3207 . $cfg['Server']['auth_type'])
3212 require_once './libraries/auth/' . $cfg['Server']['auth_type'] . '.auth.lib.php';
3213 if (!PMA_auth_check()) {
3216 PMA_auth_set_user();
3219 // Check IP-based Allow/Deny rules as soon as possible to reject the
3221 // Based on mod_access in Apache:
3222 // http://cvs.apache.org/viewcvs.cgi/httpd-2.0/modules/aaa/mod_access.c?rev=1.37&content-type=text/vnd.viewcvs-markup
3223 // Look at: "static int check_dir_access(request_rec *r)"
3224 // Robbat2 - May 10, 2002
3225 if (isset($cfg['Server']['AllowDeny'])
3226 && isset($cfg['Server']['AllowDeny']['order'])) {
3228 require_once './libraries/ip_allow_deny.lib.php';
3230 $allowDeny_forbidden = false; // default
3231 if ($cfg['Server']['AllowDeny']['order'] == 'allow,deny') {
3232 $allowDeny_forbidden = true;
3233 if (PMA_allowDeny('allow')) {
3234 $allowDeny_forbidden = false;
3236 if (PMA_allowDeny('deny')) {
3237 $allowDeny_forbidden = true;
3239 } elseif ($cfg['Server']['AllowDeny']['order'] == 'deny,allow') {
3240 if (PMA_allowDeny('deny')) {
3241 $allowDeny_forbidden = true;
3243 if (PMA_allowDeny('allow')) {
3244 $allowDeny_forbidden = false;
3246 } elseif ($cfg['Server']['AllowDeny']['order'] == 'explicit') {
3247 if (PMA_allowDeny('allow')
3248 && !PMA_allowDeny('deny')) {
3249 $allowDeny_forbidden = false;
3251 $allowDeny_forbidden = true;
3253 } // end if ... elseif ... elseif
3255 // Ejects the user if banished
3256 if ($allowDeny_forbidden) {
3259 unset($allowDeny_forbidden); //Clean up after you!
3263 if (!$cfg['Server']['AllowRoot'] && $cfg['Server']['user'] == 'root') {
3264 $allowDeny_forbidden = true;
3266 unset($allowDeny_forbidden); //Clean up after you!
3269 // The user can work with only some databases
3270 if (isset($cfg['Server']['only_db']) && $cfg['Server']['only_db'] != '') {
3271 if (is_array($cfg['Server']['only_db'])) {
3272 $dblist = $cfg['Server']['only_db'];
3274 $dblist[] = $cfg['Server']['only_db'];
3278 $bkp_track_err = @ini_set
('track_errors', 1);
3280 // Try to connect MySQL with the control user profile (will be used to
3281 // get the privileges list for the current user but the true user link
3282 // must be open after this one so it would be default one for all the
3284 if ($cfg['Server']['controluser'] != '') {
3285 $controllink = PMA_DBI_connect($cfg['Server']['controluser'],
3286 $cfg['Server']['controlpass'], true);
3288 $controllink = PMA_DBI_connect($cfg['Server']['user'],
3289 $cfg['Server']['password'], true);
3290 } // end if ... else
3292 // Pass #1 of DB-Config to read in master level DB-Config will go here
3293 // Robbat2 - May 11, 2002
3295 // Connects to the server (validates user's login)
3296 $userlink = PMA_DBI_connect($cfg['Server']['user'],
3297 $cfg['Server']['password'], false);
3299 // Pass #2 of DB-Config to read in user level DB-Config will go here
3300 // Robbat2 - May 11, 2002
3302 @ini_set
('track_errors', $bkp_track_err);
3303 unset($bkp_track_err);
3305 /* If we auto switched to utf-8 we need to reread messages here */
3306 if (defined('PMA_LANG_RELOAD')) {
3307 require './libraries/language.lib.php';
3313 require_once './libraries/sqlparser.lib.php';
3316 * SQL Validator interface code
3318 require_once './libraries/sqlvalidator.lib.php';
3320 // if 'only_db' is set for the current user, there is no need to check for
3321 // available databases in the "mysql" db
3322 $dblist_cnt = count($dblist);
3324 $true_dblist = array();
3325 $is_show_dbs = true;
3327 $dblist_asterisk_bool = false;
3328 for ($i = 0; $i < $dblist_cnt; $i++
) {
3330 // The current position
3331 if ($dblist[$i] == '*' && $dblist_asterisk_bool == false) {
3332 $dblist_asterisk_bool = true;
3333 $dblist_full = PMA_safe_db_list(false, $controllink, false,
3334 $userlink, $cfg, $dblist);
3335 foreach ($dblist_full as $dbl_val) {
3336 if (!in_array($dbl_val, $dblist)) {
3337 $true_dblist[] = $dbl_val;
3342 } elseif ($dblist[$i] == '*') {
3343 // We don't want more than one asterisk inside our 'only_db'.
3346 if ($is_show_dbs && preg_match('/(^|[^\\\\])(_|%)/', $dblist[$i])) {
3347 $local_query = 'SHOW DATABASES LIKE \'' . $dblist[$i] . '\'';
3348 // here, a PMA_DBI_query() could fail silently
3349 // if SHOW DATABASES is disabled
3350 $rs = PMA_DBI_try_query($local_query, $userlink);
3352 if ($i == 0 && ! $rs) {
3353 $error_code = substr(PMA_DBI_getError($userlink), 1, 4);
3354 if ($error_code == 1227 ||
$error_code == 1045) {
3355 // "SHOW DATABASES" statement is disabled or not allowed to user
3356 $true_dblist[] = str_replace('\\_', '_', str_replace('\\%', '%', $dblist[$i]));
3357 $is_show_dbs = false;
3362 // elseif (PMA_DBI_getError($controllink)) {
3363 // PMA_mysqlDie(PMA_DBI_getError($controllink), $local_query, false);
3365 while ($row = @PMA_DBI_fetch_row
($rs)) {
3366 $true_dblist[] = $row[0];
3369 PMA_DBI_free_result($rs);
3372 $true_dblist[] = str_replace('\\_', '_',
3373 str_replace('\\%', '%', $dblist[$i]));
3374 } // end if... else...
3376 $dblist = $true_dblist;
3377 unset($true_dblist, $i, $dbl_val);
3378 $only_db_check = true;
3381 // 'only_db' is empty for the current user...
3383 $only_db_check = false;
3384 } // end if (!$dblist_cnt)
3386 if (isset($dblist_full) && !count($dblist_full)) {
3387 $dblist = PMA_safe_db_list($only_db_check, $controllink,
3388 $dblist_cnt, $userlink, $cfg, $dblist);
3390 unset($only_db_check, $dblist_full);
3392 } // end server connecting
3395 // Kanji encoding convert feature appended by Y.Kawada (2002/2/20)
3396 if (@function_exists
('mb_convert_encoding')
3397 && strpos(' ' . $lang, 'ja-')
3398 && file_exists('./libraries/kanji-encoding.lib.php')) {
3399 require_once './libraries/kanji-encoding.lib.php';
3400 define('PMA_MULTIBYTE_ENCODING', 1);
3404 * save some settings in cookies
3406 PMA_setCookie('pma_lang', $GLOBALS['lang']);
3407 PMA_setCookie('pma_charset', $GLOBALS['convcharset']);
3408 PMA_setCookie('pma_collation_connection', $GLOBALS['collation_connection']);
3410 $_SESSION['PMA_Theme_Manager']->setThemeCookie();
3412 } // end if !defined('PMA_MINIMUM_COMMON')
3414 if (!empty($__redirect) && in_array($__redirect, $goto_whitelist)) {
3415 // to handle bug #1388167
3416 if (isset($_GET['is_js_confirmed'])) {
3417 $is_js_confirmed = 1;
3419 require $__redirect;