!C99Shell v. 2.0 [PHP 7 Update] [25.02.2019]!

Software: nginx/1.23.4. PHP/5.6.40-65+ubuntu20.04.1+deb.sury.org+1 

uname -a: Linux foro-restaurado-2 5.15.0-1040-oracle #46-Ubuntu SMP Fri Jul 14 21:47:21 UTC 2023
aarch64
 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/usr/share/nginx/html/phpMY/libraries/   drwxrwxr-x
Free 83.33 GB of 96.73 GB (86.15%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     common.lib.php (127.84 KB)      -rw-rw-r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
 * Misc functions used all over the scripts.
 *
 * @package PhpMyAdmin
 */

/**
 * Detects which function to use for PMA_pow.
 *
 * @return string Function name.
 */
function PMA_detect_pow()
{
    if (
function_exists('bcpow')) {
        
// BCMath Arbitrary Precision Mathematics Function
        
return 'bcpow';
    } elseif (
function_exists('gmp_pow')) {
        
// GMP Function
        
return 'gmp_pow';
    } else {
        
// PHP function
        
return 'pow';
    }
}

/**
 * Exponential expression / raise number into power
 *
 * @param string $base         base to raise
 * @param string $exp          exponent to use
 * @param mixed  $use_function pow function to use, or false for auto-detect
 *
 * @return mixed string or float
 */
function PMA_pow($base$exp$use_function false)
{
    static 
$pow_function null;

    if (
null == $pow_function) {
        
$pow_function PMA_detect_pow();
    }

    if (! 
$use_function) {
        
$use_function $pow_function;
    }

    if (
$exp && 'pow' != $use_function) {
        return 
false;
    }
    switch (
$use_function) {
    case 
'bcpow' :
        
// bcscale() needed for testing PMA_pow() with base values < 1
        
bcscale(10);
        
$pow bcpow($base$exp);
        break;
    case 
'gmp_pow' :
         
$pow gmp_strval(gmp_pow($base$exp));
        break;
    case 
'pow' :
        
$base = (float) $base;
        
$exp = (int) $exp;
        
$pow pow($base$exp);
        break;
    default:
        
$pow $use_function($base$exp);
    }

    return 
$pow;
}

/**
 * Returns an HTML IMG tag for a particular icon from a theme,
 * which may be an actual file or an icon from a sprite.
 * This function takes into account the PropertiesIconic
 * configuration setting and wraps the image tag in a span tag.
 *
 * @param string  $icon       name of icon file
 * @param string  $alternate  alternate text
 * @param boolean $force_text whether to force alternate text to be displayed
 *
 * @return string an html snippet
 */
function PMA_getIcon($icon$alternate ''$force_text false)
{
    
// $cfg['PropertiesIconic'] is true or both
    
$include_icon = ($GLOBALS['cfg']['PropertiesIconic'] !== false);
    
// $cfg['PropertiesIconic'] is false or both
    // OR we have no $include_icon
    
$include_text = ($force_text || true !== $GLOBALS['cfg']['PropertiesIconic']);

    
// Always use a span (we rely on this in js/sql.js)
    
$button '<span class="nowrap">';
    if (
$include_icon) {
        
$button .= PMA_getImage($icon$alternate);
    }
    if (
$include_icon && $include_text) {
        
$button .= ' ';
    }
    if (
$include_text) {
        
$button .= $alternate;
    }
    
$button .= '</span>';

    return 
$button;
}

/**
 * Returns an HTML IMG tag for a particular image from a theme,
 * which may be an actual file or an icon from a sprite
 *
 * @param string $image      The name of the file to get
 * @param string $alternate  Used to set 'alt' and 'title' attributes of the image
 * @param array  $attributes An associative array of other attributes
 *
 * @return string an html IMG tag
 */
function PMA_getImage($image$alternate ''$attributes = array())
{
    static 
$sprites// cached list of available sprites (if any)

    
$url       '';
    
$is_sprite false;
    
$alternate htmlspecialchars($alternate);

    
// If it's the first time this function is called
    
if (! isset($sprites)) {
        
// Try to load the list of sprites
        
if (is_readable($_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php')) {
            include_once 
$_SESSION['PMA_Theme']->getPath() . '/sprites.lib.php';
            
$sprites PMA_sprites();
        } else {
            
// No sprites are available for this theme
            
$sprites = array();
        }
    }
    
// Check if we have the requested image as a sprite
    //  and set $url accordingly
    
$class str_replace(array('.gif','.png'), ''$image);
    if (
array_key_exists($class$sprites)) {
        
$is_sprite true;
        
$url 'themes/dot.gif';
    } else {
        
$url $GLOBALS['pmaThemeImage'] . $image;
    }
    
// set class attribute
    
if ($is_sprite) {
        if (isset(
$attributes['class'])) {
            
$attributes['class'] = "icon ic_$class " $attributes['class'];
        } else {
            
$attributes['class'] = "icon ic_$class";
        }
    }
    
// set all other attributes
    
$attr_str '';
    foreach (
$attributes as $key => $value) {
        if (! 
in_array($key, array('alt''title'))) {
            
$attr_str .= $key=\"$value\"";
        }
    }
    
// override the alt attribute
    
if (isset($attributes['alt'])) {
        
$alt $attributes['alt'];
    } else {
        
$alt $alternate;
    }
    
// override the title attribute
    
if (isset($attributes['title'])) {
        
$title $attributes['title'];
    } else {
        
$title $alternate;
    }
    
// generate the IMG tag
    
$template '<img src="%s" title="%s" alt="%s"%s />';
    
$retval sprintf($template$url$title$alt$attr_str);

    return 
$retval;
}

/**
 * Displays the maximum size for an upload
 *
 * @param integer $max_upload_size the size
 *
 * @return string the message
 *
 * @access  public
 */
function PMA_displayMaximumUploadSize($max_upload_size)
{
    
// I have to reduce the second parameter (sensitiveness) from 6 to 4
    // to avoid weird results like 512 kKib
    
list($max_size$max_unit) = PMA_formatByteDown($max_upload_size4);
    return 
'(' sprintf(__('Max: %s%s'), $max_size$max_unit) . ')';
}

/**
 * Generates a hidden field which should indicate to the browser
 * the maximum size for upload
 *
 * @param integer $max_size the size
 *
 * @return string the INPUT field
 *
 * @access  public
 */
function PMA_generateHiddenMaxFileSize($max_size)
{
    return 
'<input type="hidden" name="MAX_FILE_SIZE" value="' .$max_size '" />';
}

/**
 * Add slashes before "'" and "\" characters so a value containing them can
 * be used in a sql comparison.
 *
 * @param string $a_string the string to slash
 * @param bool   $is_like  whether the string will be used in a 'LIKE' clause
 *                         (it then requires two more escaped sequences) or not
 * @param bool   $crlf     whether to treat cr/lfs as escape-worthy entities
 *                         (converts \n to \\n, \r to \\r)
 * @param bool   $php_code whether this function is used as part of the
 *                         "Create PHP code" dialog
 *
 * @return  string   the slashed string
 *
 * @access  public
 */
function PMA_sqlAddSlashes($a_string ''$is_like false$crlf false$php_code false)
{
    if (
$is_like) {
        
$a_string str_replace('\\''\\\\\\\\'$a_string);
    } else {
        
$a_string str_replace('\\''\\\\'$a_string);
    }

    if (
$crlf) {
        
$a_string strtr(
            
$a_string,
            array(
"\n" => '\n'"\r" => '\r'"\t" => '\t')
        );
    }

    if (
$php_code) {
        
$a_string str_replace('\'''\\\''$a_string);
    } else {
        
$a_string str_replace('\'''\'\''$a_string);
    }

    return 
$a_string;
// end of the 'PMA_sqlAddSlashes()' function


/**
 * Add slashes before "_" and "%" characters for using them in MySQL
 * database, table and field names.
 * Note: This function does not escape backslashes!
 *
 * @param string $name the string to escape
 *
 * @return string the escaped string
 *
 * @access  public
 */
function PMA_escape_mysql_wildcards($name)
{
    return 
strtr($name, array('_' => '\\_''%' => '\\%'));
// end of the 'PMA_escape_mysql_wildcards()' function

/**
 * removes slashes before "_" and "%" characters
 * Note: This function does not unescape backslashes!
 *
 * @param string $name the string to escape
 *
 * @return  string   the escaped string
 *
 * @access  public
 */
function PMA_unescape_mysql_wildcards($name)
{
    return 
strtr($name, array('\\_' => '_''\\%' => '%'));
// end of the 'PMA_unescape_mysql_wildcards()' function

/**
 * removes quotes (',",`) from a quoted string
 *
 * checks if the sting is quoted and removes this quotes
 *
 * @param string $quoted_string string to remove quotes from
 * @param string $quote         type of quote to remove
 *
 * @return string unqoted string
 */
function PMA_unQuote($quoted_string$quote null)
{
    
$quotes = array();

    if (
null === $quote) {
        
$quotes[] = '`';
        
$quotes[] = '"';
        
$quotes[] = "'";
    } else {
        
$quotes[] = $quote;
    }

    foreach (
$quotes as $quote) {
        if (
substr($quoted_string01) === $quote
            
&& substr($quoted_string, -11) === $quote
        
) {
            
$unquoted_string substr($quoted_string1, -1);
            
// replace escaped quotes
            
$unquoted_string str_replace(
                
$quote $quote,
                
$quote,
                
$unquoted_string
            
);
            return 
$unquoted_string;
        }
    }

    return 
$quoted_string;
}

/**
 * format sql strings
 *
 * @param mixed  $parsed_sql   pre-parsed SQL structure
 * @param string $unparsed_sql raw SQL string
 *
 * @return string  the formatted sql
 *
 * @global  array    the configuration array
 * @global  boolean  whether the current statement is a multiple one or not
 *
 * @access  public
 * @todo    move into PMA_Sql
 */
function PMA_formatSql($parsed_sql$unparsed_sql '')
{
    global 
$cfg;

    
// Check that we actually have a valid set of parsed data
    // well, not quite
    // first check for the SQL parser having hit an error
    
if (PMA_SQP_isError()) {
        return 
htmlspecialchars($parsed_sql['raw']);
    }
    
// then check for an array
    
if (! is_array($parsed_sql)) {
        
// We don't so just return the input directly
        // This is intended to be used for when the SQL Parser is turned off
        
$formatted_sql "<pre>\n";
        if (
$cfg['SQP']['fmtType'] == 'none' && $unparsed_sql != '') {
            
$formatted_sql .= $unparsed_sql;
        } else {
            
$formatted_sql .= $parsed_sql;
        }
        
$formatted_sql .= "\n</pre>";
        return 
$formatted_sql;
    }

    
$formatted_sql        '';

    switch (
$cfg['SQP']['fmtType']) {
    case 
'none':
        if (
$unparsed_sql != '') {
            
$formatted_sql '<span class="inner_sql"><pre>' "\n"
                
PMA_SQP_formatNone(array('raw' => $unparsed_sql)) . "\n"
                
'</pre></span>';
        } else {
            
$formatted_sql PMA_SQP_formatNone($parsed_sql);
        }
        break;
    case 
'html':
        
$formatted_sql PMA_SQP_formatHtml($parsed_sql'color');
        break;
    case 
'text':
        
$formatted_sql PMA_SQP_formatHtml($parsed_sql'text');
        break;
    default:
        break;
    } 
// end switch

    
return $formatted_sql;
// end of the "PMA_formatSql()" function


/**
 * Displays a link to the official MySQL documentation
 *
 * @param string $chapter   chapter of "HTML, one page per chapter" documentation
 * @param string $link      contains name of page/anchor that is being linked
 * @param bool   $big_icon  whether to use big icon (like in left frame)
 * @param string $anchor    anchor to page part
 * @param bool   $just_open whether only the opening <a> tag should be returned
 *
 * @return  string  the html link
 *
 * @access  public
 */
function PMA_showMySQLDocu($chapter$link$big_icon false$anchor ''$just_open false)
{
    global 
$cfg;

    if (
$cfg['MySQLManualType'] == 'none' || empty($cfg['MySQLManualBase'])) {
        return 
'';
    }

    
// Fixup for newly used names:
    
$chapter str_replace('_''-'strtolower($chapter));
    
$link str_replace('_''-'strtolower($link));

    switch (
$cfg['MySQLManualType']) {
    case 
'chapters':
        if (empty(
$chapter)) {
            
$chapter 'index';
        }
        if (empty(
$anchor)) {
            
$anchor $link;
        }
        
$url $cfg['MySQLManualBase'] . '/' $chapter '.html#' $anchor;
        break;
    case 
'big':
        if (empty(
$anchor)) {
            
$anchor $link;
        }
        
$url $cfg['MySQLManualBase'] . '#' $anchor;
        break;
    case 
'searchable':
        if (empty(
$link)) {
            
$link 'index';
        }
        
$url $cfg['MySQLManualBase'] . '/' $link '.html';
        if (!empty(
$anchor)) {
            
$url .= '#' $anchor;
        }
        break;
    case 
'viewable':
    default:
        if (empty(
$link)) {
            
$link 'index';
        }
        
$mysql '5.5';
        
$lang 'en';
        if (
defined('PMA_MYSQL_INT_VERSION')) {
            if (
PMA_MYSQL_INT_VERSION >= 50600) {
                
$mysql '5.6';
            } else if (
PMA_MYSQL_INT_VERSION >= 50500) {
                
$mysql '5.5';
            } else if (
PMA_MYSQL_INT_VERSION >= 50100) {
                
$mysql '5.1';
            } else {
                
$mysql '5.0';
            }
        }
        
$url $cfg['MySQLManualBase'] . '/' $mysql '/' $lang '/' $link '.html';
        if (!empty(
$anchor)) {
            
$url .= '#' $anchor;
        }
        break;
    }

    
$open_link '<a href="' PMA_linkURL($url) . '" target="mysql_doc">';
    if (
$just_open) {
        return 
$open_link;
    } elseif (
$big_icon) {
        return 
$open_link PMA_getImage('b_sqlhelp.png'__('Documentation')) . '</a>';
    } elseif (
$GLOBALS['cfg']['ReplaceHelpImg']) {
        return 
$open_link PMA_getImage('b_help.png'__('Documentation')) . '</a>';
    } else {
        return 
'[' $open_link __('Documentation') . '</a>]';
    }
// end of the 'PMA_showMySQLDocu()' function


/**
 * Displays a link to the phpMyAdmin documentation
 *
 * @param string $anchor anchor in documentation
 *
 * @return  string  the html link
 *
 * @access  public
 */
function PMA_showDocu($anchor)
{
    if (
$GLOBALS['cfg']['ReplaceHelpImg']) {
        return 
'<a href="Documentation.html#' $anchor '" target="documentation">'
             
PMA_getImage('b_help.png'__('Documentation'))
             . 
'</a>';
    } else {
        return 
'[<a href="Documentation.html#' $anchor '" target="documentation">'
        
__('Documentation') . '</a>]';
    }
// end of the 'PMA_showDocu()' function

/**
 * Displays a link to the PHP documentation
 *
 * @param string $target anchor in documentation
 *
 * @return string  the html link
 *
 * @access  public
 */
function PMA_showPHPDocu($target)
{
    
$url PMA_getPHPDocLink($target);

    if (
$GLOBALS['cfg']['ReplaceHelpImg']) {
        return 
'<a href="' $url '" target="documentation">'
             
PMA_getImage('b_help.png'__('Documentation'))
             . 
'</a>';
    } else {
        return 
'[<a href="' $url '" target="documentation">' __('Documentation') . '</a>]';
    }
// end of the 'PMA_showPHPDocu()' function

/**
 * returns HTML for a footnote marker and add the messsage to the footnotes
 *
 * @param string $message the error message
 * @param bool   $bbcode
 * @param string $type    message types
 *
 * @return  string html code for a footnote marker
 *
 * @access  public
 */
function PMA_showHint($message$bbcode false$type 'notice')
{
    if (
$message instanceof PMA_Message) {
        
$key $message->getHash();
        
$type $message->getLevel();
    } else {
        
$key md5($message);
    }

    if (! isset(
$GLOBALS['footnotes'][$key])) {
        if (empty(
$GLOBALS['footnotes']) || ! is_array($GLOBALS['footnotes'])) {
            
$GLOBALS['footnotes'] = array();
        }
        
$nr count($GLOBALS['footnotes']) + 1;
        
$GLOBALS['footnotes'][$key] = array(
            
'note'      => $message,
            
'type'      => $type,
            
'nr'        => $nr,
        );
    } else {
        
$nr $GLOBALS['footnotes'][$key]['nr'];
    }

    if (
$bbcode) {
        return 
'[sup]' $nr '[/sup]';
    }

    
// footnotemarker used in js/tooltip.js
    
return '<sup class="footnotemarker">' $nr '</sup>' .
           
PMA_getImage('b_help.png''', array('class' => 'footnotemarker footnote_' $nr));
}

/**
 * Displays a MySQL error message in the right frame.
 *
 * @param string $error_message  the error message
 * @param string $the_query      the sql query that failed
 * @param bool   $is_modify_link whether to show a "modify" link or not
 * @param string $back_url       the "back" link url (full path is not required)
 * @param bool   $exit           EXIT the page?
 *
 * @global  string    the curent table
 * @global  string    the current db
 *
 * @access  public
 */
function PMA_mysqlDie($error_message ''$the_query '',
$is_modify_link true$back_url ''$exit true)
{
    global 
$table$db;

    
/**
     * start http output, display html headers
     */
    
include_once './libraries/header.inc.php';

    
$error_msg_output '';

    if (!
$error_message) {
        
$error_message PMA_DBI_getError();
    }
    if (!
$the_query && !empty($GLOBALS['sql_query'])) {
        
$the_query $GLOBALS['sql_query'];
    }

    
// --- Added to solve bug #641765
    
if (!function_exists('PMA_SQP_isError') || PMA_SQP_isError()) {
        
$formatted_sql htmlspecialchars($the_query);
    } elseif (empty(
$the_query) || trim($the_query) == '') {
        
$formatted_sql '';
    } else {
        if (
strlen($the_query) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
            
$formatted_sql htmlspecialchars(substr($the_query0$GLOBALS['cfg']['MaxCharactersInDisplayedSQL'])) . '[...]';
        } else {
            
$formatted_sql PMA_formatSql(PMA_SQP_parse($the_query), $the_query);
        }
    }
    
// ---
    
$error_msg_output .= "\n" '<!-- PMA-SQL-ERROR -->' "\n";
    
$error_msg_output .= '    <div class="error"><h1>' __('Error') . '</h1>' "\n";
    
// if the config password is wrong, or the MySQL server does not
    // respond, do not show the query that would reveal the
    // username/password
    
if (!empty($the_query) && !strstr($the_query'connect')) {
        
// --- Added to solve bug #641765
        
if (function_exists('PMA_SQP_isError') && PMA_SQP_isError()) {
            
$error_msg_output .= PMA_SQP_getErrorString() . "\n";
            
$error_msg_output .= '<br />' "\n";
        }
        
// ---
        // modified to show the help on sql errors
        
$error_msg_output .= '    <p><strong>' __('SQL query') . ':</strong>' "\n";
        if (
strstr(strtolower($formatted_sql), 'select')) {
            
// please show me help to the error on select
            
$error_msg_output .= PMA_showMySQLDocu('SQL-Syntax''SELECT');
        }
        if (
$is_modify_link) {
            
$_url_params = array(
                
'sql_query' => $the_query,
                
'show_query' => 1,
            );
            if (
strlen($table)) {
                
$_url_params['db'] = $db;
                
$_url_params['table'] = $table;
                
$doedit_goto '<a href="tbl_sql.php' PMA_generate_common_url($_url_params) . '">';
            } elseif (
strlen($db)) {
                
$_url_params['db'] = $db;
                
$doedit_goto '<a href="db_sql.php' PMA_generate_common_url($_url_params) . '">';
            } else {
                
$doedit_goto '<a href="server_sql.php' PMA_generate_common_url($_url_params) . '">';
            }

            
$error_msg_output .= $doedit_goto
               
PMA_getIcon('b_edit.png'__('Edit'))
               . 
'</a>';
        } 
// end if
        
$error_msg_output .= '    </p>' "\n"
            
.'    <p>' "\n"
            
.'        ' $formatted_sql "\n"
            
.'    </p>' "\n";
    } 
// end if

    
if (! empty($error_message)) {
        
$error_message preg_replace(
            
"@((\015\012)|(\015)|(\012)){3,}@",
            
"\n\n",
            
$error_message
        
);
    }
    
// modified to show the help on error-returns
    // (now error-messages-server)
    
$error_msg_output .= '<p>' "\n"
            
'    <strong>' __('MySQL said: ') . '</strong>'
            
PMA_showMySQLDocu('Error-messages-server''Error-messages-server')
            . 
"\n"
            
'</p>' "\n";

    
// The error message will be displayed within a CODE segment.
    // To preserve original formatting, but allow wordwrapping,
    // we do a couple of replacements

    // Replace all non-single blanks with their HTML-counterpart
    
$error_message str_replace('  ''&nbsp;&nbsp;'$error_message);
    
// Replace TAB-characters with their HTML-counterpart
    
$error_message str_replace("\t"'&nbsp;&nbsp;&nbsp;&nbsp;'$error_message);
    
// Replace linebreaks
    
$error_message nl2br($error_message);

    
$error_msg_output .= '<code>' "\n"
        
$error_message "\n"
        
'</code><br />' "\n";
    
$error_msg_output .= '</div>';

    
$_SESSION['Import_message']['message'] = $error_msg_output;

    if (
$exit) {
        
/**
         * If in an Ajax request
         * - avoid displaying a Back link
         * - use PMA_ajaxResponse() to transmit the message and exit
         */
        
if ($GLOBALS['is_ajax_request'] == true) {
            
PMA_ajaxResponse($error_msg_outputfalse);
        }
        if (! empty(
$back_url)) {
            if (
strstr($back_url'?')) {
                
$back_url .= '&amp;no_history=true';
            } else {
                
$back_url .= '?no_history=true';
            }

            
$_SESSION['Import_message']['go_back_url'] = $back_url;

            
$error_msg_output .= '<fieldset class="tblFooters">';
            
$error_msg_output .= '[ <a href="' $back_url '">' __('Back') . '</a> ]';
            
$error_msg_output .= '</fieldset>' "\n\n";
        }

        echo 
$error_msg_output;
        
/**
         * display footer and exit
         */
        
include './libraries/footer.inc.php';
    } else {
        echo 
$error_msg_output;
    }
// end of the 'PMA_mysqlDie()' function

/**
 * returns array with tables of given db with extended information and grouped
 *
 * @param string   $db           name of db
 * @param string   $tables       name of tables
 * @param integer  $limit_offset list offset
 * @param int|bool $limit_count  max tables to return
 *
 * @return  array    (recursive) grouped table list
 */
function PMA_getTableList($db$tables null$limit_offset 0$limit_count false)
{
    
$sep $GLOBALS['cfg']['LeftFrameTableSeparator'];

    if (
null === $tables) {
        
$tables PMA_DBI_get_tables_full($dbfalsefalsenull$limit_offset$limit_count);
        if (
$GLOBALS['cfg']['NaturalOrder']) {
            
uksort($tables'strnatcasecmp');
        }
    }

    if (
count($tables) < 1) {
        return 
$tables;
    }

    
$default = array(
        
'Name'      => '',
        
'Rows'      => 0,
        
'Comment'   => '',
        
'disp_name' => '',
    );

    
$table_groups = array();

    
// for blobstreaming - list of blobstreaming tables

    // load PMA configuration
    
$PMA_Config $GLOBALS['PMA_Config'];

    foreach (
$tables as $table_name => $table) {
        
// if BS tables exist
        
if (PMA_BS_IsHiddenTable($table_name)) {
            continue;
        }

        
// check for correct row count
        
if (null === $table['Rows']) {
            
// Do not check exact row count here,
            // if row count is invalid possibly the table is defect
            // and this would break left frame;
            // but we can check row count if this is a view or the
            // information_schema database
            // since PMA_Table::countRecords() returns a limited row count
            // in this case.

            // set this because PMA_Table::countRecords() can use it
            
$tbl_is_view $table['TABLE_TYPE'] == 'VIEW';

            if (
$tbl_is_view || PMA_is_system_schema($db)) {
                
$table['Rows'] = PMA_Table::countRecords($db$table['Name'], falsetrue);
            }
        }

        
// in $group we save the reference to the place in $table_groups
        // where to store the table info
        
if ($GLOBALS['cfg']['LeftFrameDBTree']
            && 
$sep && strstr($table_name$sep)
        ) {
            
$parts explode($sep$table_name);

            
$group =& $table_groups;
            
$i 0;
            
$group_name_full '';
            
$parts_cnt count($parts) - 1;
            while (
$i $parts_cnt
                    
&& $i $GLOBALS['cfg']['LeftFrameTableLevel']) {
                
$group_name $parts[$i] . $sep;
                
$group_name_full .= $group_name;

                if (! isset(
$group[$group_name])) {
                    
$group[$group_name] = array();
                    
$group[$group_name]['is' $sep 'group'] = true;
                    
$group[$group_name]['tab' $sep 'count'] = 1;
                    
$group[$group_name]['tab' $sep 'group'] = $group_name_full;
                } elseif (! isset(
$group[$group_name]['is' $sep 'group'])) {
                    
$table $group[$group_name];
                    
$group[$group_name] = array();
                    
$group[$group_name][$group_name] = $table;
                    unset(
$table);
                    
$group[$group_name]['is' $sep 'group'] = true;
                    
$group[$group_name]['tab' $sep 'count'] = 1;
                    
$group[$group_name]['tab' $sep 'group'] = $group_name_full;
                } else {
                    
$group[$group_name]['tab' $sep 'count']++;
                }
                
$group =& $group[$group_name];
                
$i++;
            }
        } else {
            if (! isset(
$table_groups[$table_name])) {
                
$table_groups[$table_name] = array();
            }
            
$group =& $table_groups;
        }


        if (
$GLOBALS['cfg']['ShowTooltipAliasTB']
            && 
$GLOBALS['cfg']['ShowTooltipAliasTB'] !== 'nested'
            
&& $table['Comment'// do not switch if the comment is empty
            
&& $table['Comment'] != 'VIEW' // happens in MySQL 5.1
        
) {
            
// switch tooltip and name
            
$table['disp_name'] = $table['Comment'];
            
$table['Comment'] = $table['Name'];
        } else {
            
$table['disp_name'] = $table['Name'];
        }

        
$group[$table_name] = array_merge($default$table);
    }

    return 
$table_groups;
}

/* ----------------------- Set of misc functions ----------------------- */


/**
 * Adds backquotes on both sides of a database, table or field name.
 * and escapes backquotes inside the name with another backquote
 *
 * example:
 * <code>
 * echo PMA_backquote('owner`s db'); // `owner``s db`
 *
 * </code>
 *
 * @param mixed   $a_name the database, table or field name to "backquote"
 *                        or array of it
 * @param boolean $do_it  a flag to bypass this function (used by dump
 *                        functions)
 *
 * @return  mixed    the "backquoted" database, table or field name
 *
 * @access  public
 */
function PMA_backquote($a_name$do_it true)
{
    if (
is_array($a_name)) {
        foreach (
$a_name as &$data) {
            
$data PMA_backquote($data$do_it);
        }
        return 
$a_name;
    }

    if (! 
$do_it) {
        global 
$PMA_SQPdata_forbidden_word;

        if (! 
in_array(strtoupper($a_name), $PMA_SQPdata_forbidden_word)) {
            return 
$a_name;
        }
    }

    
// '0' is also empty for php :-(
    
if (strlen($a_name) && $a_name !== '*') {
        return 
'`' str_replace('`''``'$a_name) . '`';
    } else {
        return 
$a_name;
    }
// end of the 'PMA_backquote()' function

/**
 * Defines the <CR><LF> value depending on the user OS.
 *
 * @return  string   the <CR><LF> value to use
 *
 * @access  public
 */
function PMA_whichCrlf()
{
    
// The 'PMA_USR_OS' constant is defined in "./libraries/Config.class.php"
    // Win case
    
if (PMA_USR_OS == 'Win') {
        
$the_crlf "\r\n";
    } else {
        
// Others
        
$the_crlf "\n";
    }

    return 
$the_crlf;
// end of the 'PMA_whichCrlf()' function

/**
 * Reloads navigation if needed.
 *
 * @param bool $jsonly prints out pure JavaScript
 *
 * @access  public
 */
function PMA_reloadNavigation($jsonly=false)
{
    
// Reloads the navigation frame via JavaScript if required
    
if (isset($GLOBALS['reload']) && $GLOBALS['reload']) {
        
// one of the reasons for a reload is when a table is dropped
        // in this case, get rid of the table limit offset, otherwise
        // we have a problem when dropping a table on the last page
        // and the offset becomes greater than the total number of tables
        
unset($_SESSION['tmp_user_values']['table_limit_offset']);
        echo 
"\n";
        
$reload_url './navigation.php?' PMA_generate_common_url($GLOBALS['db'], '''&');
        if (!
$jsonly) {
            echo 
'<script type="text/javascript">' PHP_EOL;
        }
    
?>
//<![CDATA[
if (typeof(window.parent) != 'undefined'
    && typeof(window.parent.frame_navigation) != 'undefined'
    && window.parent.goTo) {
    window.parent.goTo('<?php echo $reload_url?>');
}
//]]>
<?php
        
if (!$jsonly) {
            echo 
'</script>' PHP_EOL;
        }

        unset(
$GLOBALS['reload']);
    }
}

/**
 * displays the message and the query
 * usually the message is the result of the query executed
 *
 * @param string  $message   the message to display
 * @param string  $sql_query the query to display
 * @param string  $type      the type (level) of the message
 * @param boolean $is_view   is this a message after a VIEW operation?
 *
 * @return  string
 *
 * @access  public
 */
function PMA_showMessage($message$sql_query null$type 'notice'$is_view false)
{
    
/*
     * PMA_ajaxResponse uses this function to collect the string of HTML generated
     * for showing the message.  Use output buffering to collect it and return it
     * in a string.  In some special cases on sql.php, buffering has to be disabled
     * and hence we check with $GLOBALS['buffer_message']
     */
    
if ( $GLOBALS['is_ajax_request'] == true && ! isset($GLOBALS['buffer_message']) ) {
        
ob_start();
    }
    global 
$cfg;

    if (
null === $sql_query) {
        if (! empty(
$GLOBALS['display_query'])) {
            
$sql_query $GLOBALS['display_query'];
        } elseif (
$cfg['SQP']['fmtType'] == 'none' && ! empty($GLOBALS['unparsed_sql'])) {
            
$sql_query $GLOBALS['unparsed_sql'];
        } elseif (! empty(
$GLOBALS['sql_query'])) {
            
$sql_query $GLOBALS['sql_query'];
        } else {
            
$sql_query '';
        }
    }

    if (isset(
$GLOBALS['using_bookmark_message'])) {
        
$GLOBALS['using_bookmark_message']->display();
        unset(
$GLOBALS['using_bookmark_message']);
    }

    
// Corrects the tooltip text via JS if required
    // @todo this is REALLY the wrong place to do this - very unexpected here
    
if (! $is_view && strlen($GLOBALS['table']) && $cfg['ShowTooltip']) {
        
$tooltip PMA_Table::sGetToolTip($GLOBALS['db'], $GLOBALS['table']);
        
$uni_tbl PMA_jsFormat($GLOBALS['db'] . '.' $GLOBALS['table'], false);
        echo 
"\n";
        echo 
'<script type="text/javascript">' "\n";
        echo 
'//<![CDATA[' "\n";
        echo 
"if (window.parent.updateTableTitle) window.parent.updateTableTitle('"
            
$uni_tbl "', '" PMA_jsFormat($tooltipfalse) . "');" "\n";
        echo 
'//]]>' "\n";
        echo 
'</script>' "\n";
    } 
// end if ... elseif

    // Checks if the table needs to be repaired after a TRUNCATE query.
    // @todo what about $GLOBALS['display_query']???
    // @todo this is REALLY the wrong place to do this - very unexpected here
    
if (strlen($GLOBALS['table'])
        && 
$GLOBALS['sql_query'] == 'TRUNCATE TABLE ' PMA_backquote($GLOBALS['table'])
    ) {
        if (
PMA_Table::sGetStatusInfo($GLOBALS['db'], $GLOBALS['table'], 'Index_length') > 1024 && !PMA_DRIZZLE) {
            
PMA_DBI_try_query('REPAIR TABLE ' PMA_backquote($GLOBALS['table']));
        }
    }
    unset(
$tbl_status);

    
// In an Ajax request, $GLOBALS['cell_align_left'] may not be defined. Hence,
    // check for it's presence before using it
    
echo '<div id="result_query" align="'
        
. ( isset($GLOBALS['cell_align_left']) ? $GLOBALS['cell_align_left'] : '' )
        . 
'">' "\n";

    if (
$message instanceof PMA_Message) {
        if (isset(
$GLOBALS['special_message'])) {
            
$message->addMessage($GLOBALS['special_message']);
            unset(
$GLOBALS['special_message']);
        }
        
$message->display();
        
$type $message->getLevel();
    } else {
        echo 
'<div class="' $type '">';
        echo 
PMA_sanitize($message);
        if (isset(
$GLOBALS['special_message'])) {
            echo 
PMA_sanitize($GLOBALS['special_message']);
            unset(
$GLOBALS['special_message']);
        }
        echo 
'</div>';
    }

    if (
$cfg['ShowSQL'] == true && ! empty($sql_query)) {
        
// Html format the query to be displayed
        // If we want to show some sql code it is easiest to create it here
        /* SQL-Parser-Analyzer */

        
if (! empty($GLOBALS['show_as_php'])) {
            
$new_line '\\n"<br />' "\n"
                
'&nbsp;&nbsp;&nbsp;&nbsp;. "';
            
$query_base htmlspecialchars(addslashes($sql_query));
            
$query_base preg_replace('/((\015\012)|(\015)|(\012))/'$new_line$query_base);
        } else {
            
$query_base $sql_query;
        }

        
$query_too_big false;

        if (
strlen($query_base) > $cfg['MaxCharactersInDisplayedSQL']) {
            
// when the query is large (for example an INSERT of binary
            // data), the parser chokes; so avoid parsing the query
            
$query_too_big true;
            
$shortened_query_base nl2br(
                
htmlspecialchars(
                    
substr($sql_query0$cfg['MaxCharactersInDisplayedSQL']) . '[...]'
                
)
            );
        } elseif (! empty(
$GLOBALS['parsed_sql'])
         && 
$query_base == $GLOBALS['parsed_sql']['raw']) {
            
// (here, use "! empty" because when deleting a bookmark,
            // $GLOBALS['parsed_sql'] is set but empty
            
$parsed_sql $GLOBALS['parsed_sql'];
        } else {
            
// Parse SQL if needed
            
$parsed_sql PMA_SQP_parse($query_base);
        }

        
// Analyze it
        
if (isset($parsed_sql) && ! PMA_SQP_isError()) {
            
$analyzed_display_query PMA_SQP_analyze($parsed_sql);

            
// Same as below (append LIMIT), append the remembered ORDER BY
            
if ($GLOBALS['cfg']['RememberSorting']
                && isset(
$analyzed_display_query[0]['queryflags']['select_from'])
                && isset(
$GLOBALS['sql_order_to_append'])
            ) {
                
$query_base $analyzed_display_query[0]['section_before_limit']
                    . 
"\n" $GLOBALS['sql_order_to_append']
                    . 
$analyzed_display_query[0]['limit_clause'] . ' '
                    
$analyzed_display_query[0]['section_after_limit'];

                
// Need to reparse query
                
$parsed_sql PMA_SQP_parse($query_base);
                
// update the $analyzed_display_query
                
$analyzed_display_query[0]['section_before_limit'] .= $GLOBALS['sql_order_to_append'];
                
$analyzed_display_query[0]['order_by_clause'] = $GLOBALS['sorted_col'];
            }

            
// Here we append the LIMIT added for navigation, to
            // enable its display. Adding it higher in the code
            // to $sql_query would create a problem when
            // using the Refresh or Edit links.

            // Only append it on SELECTs.

            /**
             * @todo what would be the best to do when someone hits Refresh:
             * use the current LIMITs ?
             */

            
if (isset($analyzed_display_query[0]['queryflags']['select_from'])
                && isset(
$GLOBALS['sql_limit_to_append'])
            ) {
                
$query_base $analyzed_display_query[0]['section_before_limit']
                    . 
"\n" $GLOBALS['sql_limit_to_append']
                    . 
$analyzed_display_query[0]['section_after_limit'];
                
// Need to reparse query
                
$parsed_sql PMA_SQP_parse($query_base);
            }
        }

        if (! empty(
$GLOBALS['show_as_php'])) {
            
$query_base '$sql  = "' $query_base;
        } elseif (! empty(
$GLOBALS['validatequery'])) {
            try {
                
$query_base PMA_validateSQL($query_base);
            } catch (
Exception $e) {
                
PMA_Message::error(__('Failed to connect to SQL validator!'))->display();
            }
        } elseif (isset(
$parsed_sql)) {
            
$query_base PMA_formatSql($parsed_sql$query_base);
        }

        
// Prepares links that may be displayed to edit/explain the query
        // (don't go to default pages, we must go to the page
        // where the query box is available)

        // Basic url query part
        
$url_params = array();
        if (! isset(
$GLOBALS['db'])) {
            
$GLOBALS['db'] = '';
        }
        if (
strlen($GLOBALS['db'])) {
            
$url_params['db'] = $GLOBALS['db'];
            if (
strlen($GLOBALS['table'])) {
                
$url_params['table'] = $GLOBALS['table'];
                
$edit_link 'tbl_sql.php';
            } else {
                
$edit_link 'db_sql.php';
            }
        } else {
            
$edit_link 'server_sql.php';
        }

        
// Want to have the query explained
        // but only explain a SELECT (that has not been explained)
        /* SQL-Parser-Analyzer */
        
$explain_link '';
        
$is_select false;
        if (! empty(
$cfg['SQLQuery']['Explain']) && ! $query_too_big) {
            
$explain_params $url_params;
            
// Detect if we are validating as well
            // To preserve the validate uRL data
            
if (! empty($GLOBALS['validatequery'])) {
                
$explain_params['validatequery'] = 1;
            }
            if (
preg_match('@^SELECT[[:space:]]+@i'$sql_query)) {
                
$explain_params['sql_query'] = 'EXPLAIN ' $sql_query;
                
$_message __('Explain SQL');
                
$is_select true;
            } elseif (
preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i'$sql_query)) {
                
$explain_params['sql_query'] = substr($sql_query8);
                
$_message __('Skip Explain SQL');
            }
            if (isset(
$explain_params['sql_query'])) {
                
$explain_link 'import.php' PMA_generate_common_url($explain_params);
                
$explain_link ' [' PMA_linkOrButton($explain_link$_message) . ']';
            }
        } 
//show explain

        
$url_params['sql_query']  = $sql_query;
        
$url_params['show_query'] = 1;

        
// even if the query is big and was truncated, offer the chance
        // to edit it (unless it's enormous, see PMA_linkOrButton() )
        
if (! empty($cfg['SQLQuery']['Edit'])) {
            if (
$cfg['EditInWindow'] == true) {
                
$onclick 'window.parent.focus_querywindow(\''
                    
PMA_jsFormat($sql_queryfalse) . '\'); return false;';
            } else {
                
$onclick '';
            }

            
$edit_link .= PMA_generate_common_url($url_params) . '#querybox';
            
$edit_link ' [' PMA_linkOrButton($edit_link__('Edit'), array('onclick' => $onclick)) . ']';
        } else {
            
$edit_link '';
        }

        
$url_qpart PMA_generate_common_url($url_params);

        
// Also we would like to get the SQL formed in some nice
        // php-code
        
if (! empty($cfg['SQLQuery']['ShowAsPHP']) && ! $query_too_big) {
            
$php_params $url_params;

            if (! empty(
$GLOBALS['show_as_php'])) {
                
$_message __('Without PHP Code');
            } else {
                
$php_params['show_as_php'] = 1;
                
$_message __('Create PHP Code');
            }

            
$php_link 'import.php' PMA_generate_common_url($php_params);
            
$php_link ' [' PMA_linkOrButton($php_link$_message) . ']';

            if (isset(
$GLOBALS['show_as_php'])) {
                
$runquery_link 'import.php' PMA_generate_common_url($url_params);
                
$php_link .= ' [' PMA_linkOrButton($runquery_link__('Submit Query')) . ']';
            }
        } else {
            
$php_link '';
        } 
//show as php

        // Refresh query
        
if (! empty($cfg['SQLQuery']['Refresh'])
            && ! isset(
$GLOBALS['show_as_php']) // 'Submit query' does the same
            
&& preg_match('@^(SELECT|SHOW)[[:space:]]+@i'$sql_query)
        ) {
            
$refresh_link 'import.php' PMA_generate_common_url($url_params);
            
$refresh_link ' [' PMA_linkOrButton($refresh_link__('Refresh')) . ']';
        } else {
            
$refresh_link '';
        } 
//refresh

        
if (! empty($cfg['SQLValidator']['use'])
            && ! empty(
$cfg['SQLQuery']['Validate'])
        ) {
            
$validate_params $url_params;
            if (!empty(
$GLOBALS['validatequery'])) {
                
$validate_message __('Skip Validate SQL');
            } else {
                
$validate_params['validatequery'] = 1;
                
$validate_message __('Validate SQL');
            }

            
$validate_link 'import.php' PMA_generate_common_url($validate_params);
            
$validate_link ' [' PMA_linkOrButton($validate_link$validate_message) . ']';
        } else {
            
$validate_link '';
        } 
//validator

        
if (!empty($GLOBALS['validatequery'])) {
            echo 
'<div class="sqlvalidate">';
        } else {
            echo 
'<code class="sql">';
        }
        if (
$query_too_big) {
            echo 
$shortened_query_base;
        } else {
            echo 
$query_base;
        }

        
//Clean up the end of the PHP
        
if (! empty($GLOBALS['show_as_php'])) {
            echo 
'";';
        }
        if (!empty(
$GLOBALS['validatequery'])) {
            echo 
'</div>';
        } else {
            echo 
'</code>';
        }

        echo 
'<div class="tools">';
        
// avoid displaying a Profiling checkbox that could
        // be checked, which would reexecute an INSERT, for example
        
if (! empty($refresh_link)) {
            
PMA_profilingCheckbox($sql_query);
        }
        
// if needed, generate an invisible form that contains controls for the
        // Inline link; this way, the behavior of the Inline link does not
        // depend on the profiling support or on the refresh link
        
if (empty($refresh_link) || ! PMA_profilingSupported()) {
            echo 
'<form action="sql.php" method="post">';
            echo 
PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']);
            echo 
'<input type="hidden" name="sql_query" value="'
                
htmlspecialchars($sql_query) . '" />';
            echo 
'</form>';
        }

        
// in the tools div, only display the Inline link when not in ajax
        // mode because 1) it currently does not work and 2) we would
        // have two similar mechanisms on the page for the same goal
        
if ($is_select
            
|| $GLOBALS['is_ajax_request'] === false
            
&& ! $query_too_big
        
) {
            
// see in js/functions.js the jQuery code attached to id inline_edit
            // document.write conflicts with jQuery, hence used $().append()
            
echo "<script type=\"text/javascript\">\n" .
                
"//<![CDATA[\n" .
                
"$('.tools form').last().after('[<a href=\"#\" title=\"" .
                
PMA_escapeJsString(__('Inline edit of this query')) .
                
"\" class=\"inline_edit_sql\">" .
                
PMA_escapeJsString(_pgettext('Inline edit query''Inline')) .
                
"</a>]');\n" .
                
"//]]>\n" .
                
"</script>";
        }
        echo 
$edit_link $explain_link $php_link $refresh_link $validate_link;
        echo 
'</div>';
    }
    echo 
'</div>';
    if (
$GLOBALS['is_ajax_request'] === false) {
        echo 
'<br class="clearfloat" />';
    }

    
// If we are in an Ajax request, we have most probably been called in
    // PMA_ajaxResponse().  Hence, collect the buffer contents and return it
    // to PMA_ajaxResponse(), which will encode it for JSON.
    
if ($GLOBALS['is_ajax_request'] == true
        
&& ! isset($GLOBALS['buffer_message'])
    ) {
        
$buffer_contents =  ob_get_contents();
        
ob_end_clean();
        return 
$buffer_contents;
    }
    return 
null;
// end of the 'PMA_showMessage()' function

/**
 * Verifies if current MySQL server supports profiling
 *
 * @access  public
 *
 * @return  boolean whether profiling is supported
 */
function PMA_profilingSupported()
{
    if (! 
PMA_cacheExists('profiling_supported'true)) {
        
// 5.0.37 has profiling but for example, 5.1.20 does not
        // (avoid a trip to the server for MySQL before 5.0.37)
        // and do not set a constant as we might be switching servers
        
if (defined('PMA_MYSQL_INT_VERSION')
            && 
PMA_MYSQL_INT_VERSION >= 50037
            
&& PMA_DBI_fetch_value("SHOW VARIABLES LIKE 'profiling'")
        ) {
            
PMA_cacheSet('profiling_supported'truetrue);
        } else {
            
PMA_cacheSet('profiling_supported'falsetrue);
        }
    }

    return 
PMA_cacheGet('profiling_supported'true);
}

/**
 * Displays a form with the Profiling checkbox
 *
 * @param string $sql_query sql query
 *
 * @access  public
 */
function PMA_profilingCheckbox($sql_query)
{
    if (
PMA_profilingSupported()) {
        echo 
'<form action="sql.php" method="post">' "\n";
        echo 
PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']);
        echo 
'<input type="hidden" name="sql_query" value="' htmlspecialchars($sql_query) . '" />' "\n";
        echo 
'<input type="hidden" name="profiling_form" value="1" />' "\n";
        
PMA_display_html_checkbox('profiling'__('Profiling'), isset($_SESSION['profiling']), true);
        echo 
'<noscript><input type="submit" value="' __('Go') . '" /></noscript>' "\n";
        echo 
'</form>' "\n";
    }
}

/**
 * Formats $value to byte view
 *
 * @param double $value the value to format
 * @param int    $limes the sensitiveness
 * @param int    $comma the number of decimals to retain
 *
 * @return   array    the formatted value and its unit
 *
 * @access  public
 */
function PMA_formatByteDown($value$limes 6$comma 0)
{
    if (
$value === null) {
        return 
null;
    }

    
$byteUnits = array(
        
/* l10n: shortcuts for Byte */
        
__('B'),
        
/* l10n: shortcuts for Kilobyte */
        
__('KiB'),
        
/* l10n: shortcuts for Megabyte */
        
__('MiB'),
        
/* l10n: shortcuts for Gigabyte */
        
__('GiB'),
        
/* l10n: shortcuts for Terabyte */
        
__('TiB'),
        
/* l10n: shortcuts for Petabyte */
        
__('PiB'),
        
/* l10n: shortcuts for Exabyte */
        
__('EiB')
        );

    
$dh   PMA_pow(10$comma);
    
$li   PMA_pow(10$limes);
    
$unit $byteUnits[0];

    for (
$d 6$ex 15$d >= 1$d--, $ex-=3) {
        if (isset(
$byteUnits[$d]) && $value >= $li PMA_pow(10$ex)) {
            
// use 1024.0 to avoid integer overflow on 64-bit machines
            
$value round($value / (PMA_pow(1024$d) / $dh)) /$dh;
            
$unit $byteUnits[$d];
            break 
1;
        } 
// end if
    
// end for

    
if ($unit != $byteUnits[0]) {
        
// if the unit is not bytes (as represented in current language)
        // reformat with max length of 5
        // 4th parameter=true means do not reformat if value < 1
        
$return_value PMA_formatNumber($value5$commatrue);
    } else {
        
// do not reformat, just handle the locale
        
$return_value PMA_formatNumber($value0);
    }

    return array(
trim($return_value), $unit);
// end of the 'PMA_formatByteDown' function

/**
 * Changes thousands and decimal separators to locale specific values.
 *
 * @param string $value the value
 *
 * @return string
 */
function PMA_localizeNumber($value)
{
    return 
str_replace(
        array(
',''.'),
        array(
            
/* l10n: Thousands separator */
            
__(','),
            
/* l10n: Decimal separator */
            
__('.'),
            ),
        
$value
    
);
}

/**
 * Formats $value to the given length and appends SI prefixes
 * with a $length of 0 no truncation occurs, number is only formated
 * to the current locale
 *
 * examples:
 * <code>
 * echo PMA_formatNumber(123456789, 6);     // 123,457 k
 * echo PMA_formatNumber(-123456789, 4, 2); //    -123.46 M
 * echo PMA_formatNumber(-0.003, 6);        //      -3 m
 * echo PMA_formatNumber(0.003, 3, 3);      //       0.003
 * echo PMA_formatNumber(0.00003, 3, 2);    //       0.03 m
 * echo PMA_formatNumber(0, 6);             //       0
 * </code>
 *
 * @param double  $value          the value to format
 * @param integer $digits_left    number of digits left of the comma
 * @param integer $digits_right   number of digits right of the comma
 * @param boolean $only_down      do not reformat numbers below 1
 * @param boolean $noTrailingZero removes trailing zeros right of the comma
 *                                (default: true)
 *
 * @return  string   the formatted value and its unit
 *
 * @access  public
 */
function PMA_formatNumber($value$digits_left 3$digits_right 0,
$only_down false$noTrailingZero true)
{
    if (
$value==0) {
        return 
'0';
    }

    
$originalValue $value;
    
//number_format is not multibyte safe, str_replace is safe
    
if ($digits_left === 0) {
        
$value number_format($value$digits_right);
        if (
$originalValue != && floatval($value) == 0) {
            
$value ' <' . (PMA_pow(10$digits_right));
        }

        return 
PMA_localizeNumber($value);
    }

    
// this units needs no translation, ISO
    
$units = array(
        -
=> 'y',
        -
=> 'z',
        -
=> 'a',
        -
=> 'f',
        -
=> 'p',
        -
=> 'n',
        -
=> '&micro;',
        -
=> 'm',
        
=> ' ',
        
=> 'k',
        
=> 'M',
        
=> 'G',
        
=> 'T',
        
=> 'P',
        
=> 'E',
        
=> 'Z',
        
=> 'Y'
    
);

    
// check for negative value to retain sign
    
if ($value 0) {
        
$sign '-';
        
$value abs($value);
    } else {
        
$sign '';
    }

    
$dh PMA_pow(10$digits_right);

    
/*
     * This gives us the right SI prefix already,
     * but $digits_left parameter not incorporated
     */
    
$d floor(log10($value) / 3);
    
/*
     * Lowering the SI prefix by 1 gives us an additional 3 zeros
     * So if we have 3,6,9,12.. free digits ($digits_left - $cur_digits)
     * to use, then lower the SI prefix
     */
    
$cur_digits floor(log10($value PMA_pow(1000$d'pow'))+1);
    if (
$digits_left $cur_digits) {
        
$d-= floor(($digits_left $cur_digits)/3);
    }

    if (
$d<&& $only_down) {
        
$d=0;
    }

    
$value round($value / (PMA_pow(1000$d'pow') / $dh)) /$dh;
    
$unit $units[$d];

    
// If we dont want any zeros after the comma just add the thousand seperator
    
if ($noTrailingZero) {
        
$value PMA_localizeNumber(
            
preg_replace('/(?<=\d)(?=(\d{3})+(?!\d))/'','$value)
        );
    } else {
        
//number_format is not multibyte safe, str_replace is safe
        
$value PMA_localizeNumber(number_format($value$digits_right));
    }

    if (
$originalValue!=&& floatval($value) == 0) {
        return 
' <' . (PMA_pow(10$digits_right)) . ' ' $unit;
    }

    return 
$sign $value ' ' $unit;
// end of the 'PMA_formatNumber' function

/**
 * Returns the number of bytes when a formatted size is given
 *
 * @param string $formatted_size the size expression (for example 8MB)
 *
 * @return  integer  The numerical part of the expression (for example 8)
 */
function PMA_extractValueFromFormattedSize($formatted_size)
{
    
$return_value = -1;

    if (
preg_match('/^[0-9]+GB$/'$formatted_size)) {
        
$return_value substr($formatted_size0, -2) * PMA_pow(10243);
    } elseif (
preg_match('/^[0-9]+MB$/'$formatted_size)) {
        
$return_value substr($formatted_size0, -2) * PMA_pow(10242);
    } elseif (
preg_match('/^[0-9]+K$/'$formatted_size)) {
        
$return_value substr($formatted_size0, -1) * PMA_pow(10241);
    }
    return 
$return_value;
}
// end of the 'PMA_extractValueFromFormattedSize' function

/**
 * Writes localised date
 *
 * @param string $timestamp the current timestamp
 * @param string $format    format
 *
 * @return  string   the formatted date
 *
 * @access  public
 */
function PMA_localisedDate($timestamp = -1$format '')
{
    
$month = array(
        
/* l10n: Short month name */
        
__('Jan'),
        
/* l10n: Short month name */
        
__('Feb'),
        
/* l10n: Short month name */
        
__('Mar'),
        
/* l10n: Short month name */
        
__('Apr'),
        
/* l10n: Short month name */
        
_pgettext('Short month name''May'),
        
/* l10n: Short month name */
        
__('Jun'),
        
/* l10n: Short month name */
        
__('Jul'),
        
/* l10n: Short month name */
        
__('Aug'),
        
/* l10n: Short month name */
        
__('Sep'),
        
/* l10n: Short month name */
        
__('Oct'),
        
/* l10n: Short month name */
        
__('Nov'),
        
/* l10n: Short month name */
        
__('Dec'));
    
$day_of_week = array(
        
/* l10n: Short week day name */
        
_pgettext('Short week day name''Sun'),
        
/* l10n: Short week day name */
        
__('Mon'),
        
/* l10n: Short week day name */
        
__('Tue'),
        
/* l10n: Short week day name */
        
__('Wed'),
        
/* l10n: Short week day name */
        
__('Thu'),
        
/* l10n: Short week day name */
        
__('Fri'),
        
/* l10n: Short week day name */
        
__('Sat'));

    if (
$format == '') {
        
/* l10n: See http://www.php.net/manual/en/function.strftime.php */
        
$format __('%B %d, %Y at %I:%M %p');
    }

    if (
$timestamp == -1) {
        
$timestamp time();
    }

    
$date preg_replace(
        
'@%[aA]@',
        
$day_of_week[(int)strftime('%w'$timestamp)],
        
$format
    
);
    
$date preg_replace(
        
'@%[bB]@',
        
$month[(int)strftime('%m'$timestamp)-1],
        
$date
    
);

    return 
strftime($date$timestamp);
// end of the 'PMA_localisedDate()' function


/**
 * returns a tab for tabbed navigation.
 * If the variables $link and $args ar left empty, an inactive tab is created
 *
 * @param array $tab        array with all options
 * @param array $url_params
 *
 * @return  string  html code for one tab, a link if valid otherwise a span
 *
 * @access  public
 */
function PMA_generate_html_tab($tab$url_params = array(), $base_dir='')
{
    
// default values
    
$defaults = array(
        
'text'      => '',
        
'class'     => '',
        
'active'    => null,
        
'link'      => '',
        
'sep'       => '?',
        
'attr'      => '',
        
'args'      => '',
        
'warning'   => '',
        
'fragment'  => '',
        
'id'        => '',
    );

    
$tab array_merge($defaults$tab);

    
// determine additionnal style-class
    
if (empty($tab['class'])) {
        if (! empty(
$tab['active'])
            || 
PMA_isValid($GLOBALS['active_page'], 'identical'$tab['link'])
        ) {
            
$tab['class'] = 'active';
        } elseif (
is_null($tab['active']) && empty($GLOBALS['active_page'])
          && 
basename($GLOBALS['PMA_PHP_SELF']) == $tab['link']
          && empty(
$tab['warning'])) {
            
$tab['class'] = 'active';
        }
    }

    if (!empty(
$tab['warning'])) {
        
$tab['class'] .= ' error';
        
$tab['attr'] .= ' title="' htmlspecialchars($tab['warning']) . '"';
    }

    
// If there are any tab specific URL parameters, merge those with
    // the general URL parameters
    
if (! empty($tab['url_params']) && is_array($tab['url_params'])) {
        
$url_params array_merge($url_params$tab['url_params']);
    }

    
// build the link
    
if (!empty($tab['link'])) {
        
$tab['link'] = htmlentities($tab['link']);
        
$tab['link'] = $tab['link'] . PMA_generate_common_url($url_params);
        if (! empty(
$tab['args'])) {
            foreach (
$tab['args'] as $param => $value) {
                
$tab['link'] .= PMA_get_arg_separator('html') . urlencode($param)
                    . 
'=' urlencode($value);
            }
        }
    }

    if (! empty(
$tab['fragment'])) {
        
$tab['link'] .= $tab['fragment'];
    }

    
// display icon, even if iconic is disabled but the link-text is missing
    
if (($GLOBALS['cfg']['MainPageIconic'] || empty($tab['text']))
        && isset(
$tab['icon'])
    ) {
        
// avoid generating an alt tag, because it only illustrates
        // the text that follows and if browser does not display
        // images, the text is duplicated
        
$tab['text'] = PMA_getImage(htmlentities($tab['icon'])) . $tab['text'];

    } elseif (empty(
$tab['text'])) {
        
// check to not display an empty link-text
        
$tab['text'] = '?';
        
trigger_error(
            
'empty linktext in function ' __FUNCTION__ '()',
            
E_USER_NOTICE
        
);
    }

    
//Set the id for the tab, if set in the params
    
$id_string = ( empty($tab['id']) ? '' ' id="'.$tab['id'].'" ' );
    
$out '<li' . ($tab['class'] == 'active' ' class="active"' '') . '>';

    if (!empty(
$tab['link'])) {
        
$out .= '<a class="tab' htmlentities($tab['class']) . '"'
            
.$id_string
            
.' href="' $tab['link'] . '" ' $tab['attr'] . '>'
            
$tab['text'] . '</a>';
    } else {
        
$out .= '<span class="tab' htmlentities($tab['class']) . '"'.$id_string.'>'
            
$tab['text'] . '</span>';
    }

    
$out .= '</li>';
    return 
$out;
// end of the 'PMA_generate_html_tab()' function

/**
 * returns html-code for a tab navigation
 *
 * @param array  $tabs       one element per tab
 * @param string $url_params
 * @param string $base_dir
 * @param string $menu_id
 *
 * @return  string  html-code for tab-navigation
 */
function PMA_generate_html_tabs($tabs$url_params$base_dir=''$menu_id='topmenu')
{
    
$tab_navigation '<div id="' htmlentities($menu_id) . 'container" class="menucontainer">'
        
.'<ul id="' htmlentities($menu_id) . '">';

    foreach (
$tabs as $tab) {
        
$tab_navigation .= PMA_generate_html_tab($tab$url_params$base_dir);
    }

    
$tab_navigation .=
         
'</ul>' "\n"
        
.'<div class="clearfloat"></div>'
        
.'</div>' "\n";

    return 
$tab_navigation;
}


/**
 * Displays a link, or a button if the link's URL is too large, to
 * accommodate some browsers' limitations
 *
 * @param string  $url        the URL
 * @param string  $message    the link message
 * @param mixed   $tag_params string: js confirmation
 *                            array: additional tag params (f.e. style="")
 * @param boolean $new_form   we set this to false when we are already in
 *                            a  form, to avoid generating nested forms
 * @param boolean $strip_img  whether to strip the image
 * @param string  $target     target
 *
 * @return string  the results to be echoed or saved in an array
 */
function PMA_linkOrButton($url$message$tag_params = array(),
    
$new_form true$strip_img false$target '')
{
    
$url_length strlen($url);
    
// with this we should be able to catch case of image upload
    // into a (MEDIUM) BLOB; not worth generating even a form for these
    
if ($url_length $GLOBALS['cfg']['LinkLengthLimit'] * 100) {
        return 
'';
    }


    if (! 
is_array($tag_params)) {
        
$tmp $tag_params;
        
$tag_params = array();
        if (!empty(
$tmp)) {
            
$tag_params['onclick'] = 'return confirmLink(this, \'' PMA_escapeJsString($tmp) . '\')';
        }
        unset(
$tmp);
    }
    if (! empty(
$target)) {
        
$tag_params['target'] = htmlentities($target);
    }

    
$tag_params_strings = array();
    foreach (
$tag_params as $par_name => $par_value) {
        
// htmlspecialchars() only on non javascript
        
$par_value substr($par_name02) == 'on'
            
$par_value
            
htmlspecialchars($par_value);
        
$tag_params_strings[] = $par_name '="' $par_value '"';
    }

    
$displayed_message '';
    
// Add text if not already added
    
if (stristr($message'<img')
        && (!
$strip_img || $GLOBALS['cfg']['PropertiesIconic'] === true)
        && 
strip_tags($message)==$message
    
) {
        
$displayed_message '<span>'
        
htmlspecialchars(
            
preg_replace('/^.*\salt="([^"]*)".*$/si''\1'$message)
        )
        . 
'</span>';
    }

    
// Suhosin: Check that each query parameter is not above maximum
    
$in_suhosin_limits true;
    if (
$url_length <= $GLOBALS['cfg']['LinkLengthLimit']) {
        if (
$suhosin_get_MaxValueLength ini_get('suhosin.get.max_value_length')) {
            
$query_parts PMA_splitURLQuery($url);
            foreach (
$query_parts as $query_pair) {
                list(
$eachvar$eachval) = explode('='$query_pair);
                if (
strlen($eachval) > $suhosin_get_MaxValueLength) {
                    
$in_suhosin_limits false;
                    break;
                }
            }
        }
    }

    if (
$url_length <= $GLOBALS['cfg']['LinkLengthLimit'] && $in_suhosin_limits) {
        
// no whitespace within an <a> else Safari will make it part of the link
        
$ret "\n" '<a href="' $url '" '
            
implode(' '$tag_params_strings) . '>'
            
$message $displayed_message '</a>' "\n";
    } else {
        
// no spaces (linebreaks) at all
        // or after the hidden fields
        // IE will display them all

        // add class=link to submit button
        
if (empty($tag_params['class'])) {
            
$tag_params['class'] = 'link';
        }

        if (! isset(
$query_parts)) {
            
$query_parts PMA_splitURLQuery($url);
        }
        
$url_parts   parse_url($url);

        if (
$new_form) {
            
$ret '<form action="' $url_parts['path'] . '" class="link"'
                 
' method="post"' $target ' style="display: inline;">';
            
$subname_open   '';
            
$subname_close  '';
            
$submit_link    '#';
        } else {
            
$query_parts[] = 'redirect=' $url_parts['path'];
            if (empty(
$GLOBALS['subform_counter'])) {
                
$GLOBALS['subform_counter'] = 0;
            }
            
$GLOBALS['subform_counter']++;
            
$ret            '';
            
$subname_open   'subform[' $GLOBALS['subform_counter'] . '][';
            
$subname_close  ']';
            
$submit_link    '#usesubform[' $GLOBALS['subform_counter'] . ']=1';
        }
        foreach (
$query_parts as $query_pair) {
            list(
$eachvar$eachval) = explode('='$query_pair);
            
$ret .= '<input type="hidden" name="' $subname_open $eachvar
                
$subname_close '" value="'
                
htmlspecialchars(urldecode($eachval)) . '" />';
        } 
// end while

        
$ret .= "\n" '<a href="' $submit_link '" class="formLinkSubmit" '
        
implode(' '$tag_params_strings) . '>'
        
$message ' ' $displayed_message '</a>' "\n";

        if (
$new_form) {
            
$ret .= '</form>';
        }
    } 
// end if... else...

    
return $ret;
// end of the 'PMA_linkOrButton()' function


/**
 * Splits a URL string by parameter
 *
 * @param string $url the URL
 *
 * @return array  the parameter/value pairs, for example [0] db=sakila
 */
function PMA_splitURLQuery($url)
{
    
// decode encoded url separators
    
$separator   PMA_get_arg_separator();
    
// on most places separator is still hard coded ...
    
if ($separator !== '&') {
        
// ... so always replace & with $separator
        
$url         str_replace(htmlentities('&'), $separator$url);
        
$url         str_replace('&'$separator$url);
    }
    
$url         str_replace(htmlentities($separator), $separator$url);
    
// end decode

    
$url_parts   parse_url($url);
    return 
explode($separator$url_parts['query']);
}

/**
 * Returns a given timespan value in a readable format.
 *
 * @param int $seconds the timespan
 *
 * @return string  the formatted value
 */
function PMA_timespanFormat($seconds)
{
    
$days floor($seconds 86400);
    if (
$days 0) {
        
$seconds -= $days 86400;
    }
    
$hours floor($seconds 3600);
    if (
$days || $hours 0) {
        
$seconds -= $hours 3600;
    }
    
$minutes floor($seconds 60);
    if (
$days || $hours || $minutes 0) {
        
$seconds -= $minutes 60;
    }
    return 
sprintf(
        
__('%s days, %s hours, %s minutes and %s seconds'),
        (string)
$days, (string)$hours, (string)$minutes, (string)$seconds
    
);
}

/**
 * Takes a string and outputs each character on a line for itself. Used
 * mainly for horizontalflipped display mode.
 * Takes care of special html-characters.
 * Fulfills todo-item
 * http://sf.net/tracker/?func=detail&aid=544361&group_id=23067&atid=377411
 *
 * @param string $string    The string
 * @param string $Separator The Separator (defaults to "<br />\n")
 *
 * @access  public
 * @todo    add a multibyte safe function PMA_STR_split()
 *
 * @return  string      The flipped string
 */
function PMA_flipstring($string$Separator "<br />\n")
{
    
$format_string '';
    
$charbuff false;

    for (
$i 0$str_len strlen($string); $i $str_len$i++) {
        
$char $string{$i};
        
$append false;

        if (
$char == '&') {
            
$format_string .= $charbuff;
            
$charbuff $char;
        } elseif (
$char == ';' && !empty($charbuff)) {
            
$format_string .= $charbuff $char;
            
$charbuff false;
            
$append true;
        } elseif (! empty(
$charbuff)) {
            
$charbuff .= $char;
        } else {
            
$format_string .= $char;
            
$append true;
        }

        
// do not add separator after the last character
        
if ($append && ($i != $str_len 1)) {
            
$format_string .= $Separator;
        }
    }

    return 
$format_string;
}

/**
 * Function added to avoid path disclosures.
 * Called by each script that needs parameters, it displays
 * an error message and, by default, stops the execution.
 *
 * Not sure we could use a strMissingParameter message here,
 * would have to check if the error message file is always available
 *
 * @param array $params  The names of the parameters needed by the calling script.
 * @param bool  $die     Stop the execution?
 *                       (Set this manually to false in the calling script
 *                       until you know all needed parameters to check).
 * @param bool  $request Whether to include this list in checking for special params.
 *
 * @global  string  path to current script
 * @global  boolean flag whether any special variable was required
 *
 * @access  public
 * @todo    use PMA_fatalError() if $die === true?
 */
function PMA_checkParameters($params$die true$request true)
{
    global 
$checked_special;

    if (! isset(
$checked_special)) {
        
$checked_special false;
    }

    
$reported_script_name basename($GLOBALS['PMA_PHP_SELF']);
    
$found_error false;
    
$error_message '';

    foreach (
$params as $param) {
        if (
$request && $param != 'db' && $param != 'table') {
            
$checked_special true;
        }

        if (! isset(
$GLOBALS[$param])) {
            
$error_message .= $reported_script_name
                
': ' __('Missing parameter:') . ' '
                
$param
                
PMA_showDocu('faqmissingparameters')
                . 
'<br />';
            
$found_error true;
        }
    }
    if (
$found_error) {
        
/**
         * display html meta tags
         */
        
include_once './libraries/header_meta_style.inc.php';
        echo 
'</head><body><p>' $error_message '</p></body></html>';
        if (
$die) {
            exit();
        }
    }
// end function

/**
 * Function to generate unique condition for specified row.
 *
 * @param resource $handle       current query result
 * @param integer  $fields_cnt   number of fields
 * @param array    $fields_meta  meta information about fields
 * @param array    $row          current row
 * @param boolean  $force_unique generate condition only on pk or unique
 *
 * @access  public
 *
 * @return  array     the calculated condition and whether condition is unique
 */
function PMA_getUniqueCondition($handle$fields_cnt$fields_meta$row$force_unique false)
{
    
$primary_key          '';
    
$unique_key           '';
    
$nonprimary_condition '';
    
$preferred_condition '';
    
$primary_key_array    = array();
    
$unique_key_array     = array();
    
$nonprimary_condition_array = array();
    
$condition_array = array();

    for (
$i 0$i $fields_cnt; ++$i) {
        
$condition   '';
        
$con_key     '';
        
$con_val     '';
        
$field_flags PMA_DBI_field_flags($handle$i);
        
$meta        $fields_meta[$i];

        
// do not use a column alias in a condition
        
if (! isset($meta->orgname) || ! strlen($meta->orgname)) {
            
$meta->orgname $meta->name;

            if (isset(
$GLOBALS['analyzed_sql'][0]['select_expr'])
                && 
is_array($GLOBALS['analyzed_sql'][0]['select_expr'])
            ) {
                foreach (
$GLOBALS['analyzed_sql'][0]['select_expr'] as $select_expr) {
                    
// need (string) === (string)
                    // '' !== 0 but '' == 0
                    
if ((string) $select_expr['alias'] === (string) $meta->name) {
                        
$meta->orgname $select_expr['column'];
                        break;
                    } 
// end if
                
// end foreach
            
}
        }

        
// Do not use a table alias in a condition.
        // Test case is:
        // select * from galerie x WHERE
        //(select count(*) from galerie y where y.datum=x.datum)>1
        //
        // But orgtable is present only with mysqli extension so the
        // fix is only for mysqli.
        // Also, do not use the original table name if we are dealing with
        // a view because this view might be updatable.
        // (The isView() verification should not be costly in most cases
        // because there is some caching in the function).
        
if (isset($meta->orgtable)
            && 
$meta->table != $meta->orgtable
            
&& ! PMA_Table::isView($GLOBALS['db'], $meta->table)
        ) {
            
$meta->table $meta->orgtable;
        }

        
// to fix the bug where float fields (primary or not)
        // can't be matched because of the imprecision of
        // floating comparison, use CONCAT
        // (also, the syntax "CONCAT(field) IS NULL"
        // that we need on the next "if" will work)
        
if ($meta->type == 'real') {
            
$con_key 'CONCAT(' PMA_backquote($meta->table) . '.'
                
PMA_backquote($meta->orgname) . ')';
        } else {
            
$con_key PMA_backquote($meta->table) . '.'
                
PMA_backquote($meta->orgname);
        } 
// end if... else...
        
$condition ' ' $con_key ' ';

        if (! isset(
$row[$i]) || is_null($row[$i])) {
            
$con_val 'IS NULL';
        } else {
            
// timestamp is numeric on some MySQL 4.1
            // for real we use CONCAT above and it should compare to string
            
if ($meta->numeric
                
&& $meta->type != 'timestamp'
                
&& $meta->type != 'real'
            
) {
                
$con_val '= ' $row[$i];
            } elseif ((
$meta->type == 'blob' || $meta->type == 'string')
                
// hexify only if this is a true not empty BLOB or a BINARY
                    
&& stristr($field_flags'BINARY')
                    && !empty(
$row[$i])) {
                
// do not waste memory building a too big condition
                
if (strlen($row[$i]) < 1000) {
                    
// use a CAST if possible, to avoid problems
                    // if the field contains wildcard characters % or _
                    
$con_val '= CAST(0x' bin2hex($row[$i]) . ' AS BINARY)';
                } else {
                    
// this blob won't be part of the final condition
                    
$con_val null;
                }
            } elseif (
in_array($meta->typePMA_getGISDatatypes())
                && ! empty(
$row[$i])
            ) {
                
// do not build a too big condition
                
if (strlen($row[$i]) < 5000) {
                    
$condition .= '=0x' bin2hex($row[$i]) . ' AND';
                } else {
                    
$condition '';
                }
            } elseif (
$meta->type == 'bit') {
                
$con_val "= b'" PMA_printable_bit_value($row[$i], $meta->length) . "'";
            } else {
                
$con_val '= \'' PMA_sqlAddSlashes($row[$i], falsetrue) . '\'';
            }
        }
        if (
$con_val != null) {
            
$condition .= $con_val ' AND';
            if (
$meta->primary_key 0) {
                
$primary_key .= $condition;
                
$primary_key_array[$con_key] = $con_val;
            } elseif (
$meta->unique_key 0) {
                
$unique_key  .= $condition;
                
$unique_key_array[$con_key] = $con_val;
            }
            
$nonprimary_condition .= $condition;
            
$nonprimary_condition_array[$con_key] = $con_val;
        }
    } 
// end for

    // Correction University of Virginia 19991216:
    // prefer primary or unique keys for condition,
    // but use conjunction of all values if no primary key
    
$clause_is_unique true;
    if (
$primary_key) {
        
$preferred_condition $primary_key;
        
$condition_array $primary_key_array;
    } elseif (
$unique_key) {
        
$preferred_condition $unique_key;
        
$condition_array $unique_key_array;
    } elseif (! 
$force_unique) {
        
$preferred_condition $nonprimary_condition;
        
$condition_array $nonprimary_condition_array;
        
$clause_is_unique false;
    }

    
$where_clause trim(preg_replace('|\s?AND$|'''$preferred_condition));
    return(array(
$where_clause$clause_is_unique$condition_array));
// end function

/**
 * Generate a button or image tag
 *
 * @param string $button_name  name of button element
 * @param string $button_class class of button element
 * @param string $image_name   name of image element
 * @param string $text         text to display
 * @param string $image        image to display
 * @param string $value        value
 *
 * @access  public
 */
function PMA_buttonOrImage($button_name$button_class$image_name$text,
    
$image$value '')
{
    if (
$value == '') {
        
$value $text;
    }
    if (
false === $GLOBALS['cfg']['PropertiesIconic']) {
        echo 
' <input type="submit" name="' $button_name '"'
                
.' value="' htmlspecialchars($value) . '"'
                
.' title="' htmlspecialchars($text) . '" />' "\n";
        return;
    }

    
/* Opera has trouble with <input type="image"> */
    /* IE has trouble with <button> */
    
if (PMA_USR_BROWSER_AGENT != 'IE') {
        echo 
'<button class="' $button_class '" type="submit"'
            
.' name="' $button_name '" value="' htmlspecialchars($value) . '"'
            
.' title="' htmlspecialchars($text) . '">' "\n"
            
PMA_getIcon($image$text)
            .
'</button>' "\n";
    } else {
        echo 
'<input type="image" name="' $image_name
            
'" value="' htmlspecialchars($value)
            . 
'" title="' htmlspecialchars($text)
            . 
'" src="' $GLOBALS['pmaThemeImage']. $image '" />'
            
. ($GLOBALS['cfg']['PropertiesIconic'] === 'both'
                
'&nbsp;' htmlspecialchars($text)
                : 
'') . "\n";
    }
// end function

/**
 * Generate a pagination selector for browsing resultsets
 *
 * @param int    $rows        Number of rows in the pagination set
 * @param int    $pageNow     current page number
 * @param int    $nbTotalPage number of total pages
 * @param int    $showAll     If the number of pages is lower than this
 *                            variable, no pages will be omitted in pagination
 * @param int    $sliceStart  How many rows at the beginning should always be shown?
 * @param int    $sliceEnd    How many rows at the end should always be shown?
 * @param int    $percent     Percentage of calculation page offsets to hop to a
 *                            next page
 * @param int    $range       Near the current page, how many pages should
 *                            be considered "nearby" and displayed as well?
 * @param string $prompt      The prompt to display (sometimes empty)
 *
 * @return string
 *
 * @access  public
 */
function PMA_pageselector($rows$pageNow 1$nbTotalPage 1,
    
$showAll 200$sliceStart 5$sliceEnd 5$percent 20,
    
$range 10$prompt '')
{
    
$increment floor($nbTotalPage $percent);
    
$pageNowMinusRange = ($pageNow $range);
    
$pageNowPlusRange = ($pageNow $range);

    
$gotopage $prompt ' <select id="pageselector" ';
    if (
$GLOBALS['cfg']['AjaxEnable']) {
        
$gotopage .= ' class="ajax"';
    }
    
$gotopage .= ' name="pos" >' "\n";
    if (
$nbTotalPage $showAll) {
        
$pages range(1$nbTotalPage);
    } else {
        
$pages = array();

        
// Always show first X pages
        
for ($i 1$i <= $sliceStart$i++) {
            
$pages[] = $i;
        }

        
// Always show last X pages
        
for ($i $nbTotalPage $sliceEnd$i <= $nbTotalPage$i++) {
            
$pages[] = $i;
        }

        
// Based on the number of results we add the specified
        // $percent percentage to each page number,
        // so that we have a representing page number every now and then to
        // immediately jump to specific pages.
        // As soon as we get near our currently chosen page ($pageNow -
        // $range), every page number will be shown.
        
$i $sliceStart;
        
$x $nbTotalPage $sliceEnd;
        
$met_boundary false;
        while (
$i <= $x) {
            if (
$i >= $pageNowMinusRange && $i <= $pageNowPlusRange) {
                
// If our pageselector comes near the current page, we use 1
                // counter increments
                
$i++;
                
$met_boundary true;
            } else {
                
// We add the percentage increment to our current page to
                // hop to the next one in range
                
$i += $increment;

                
// Make sure that we do not cross our boundaries.
                
if ($i $pageNowMinusRange && ! $met_boundary) {
                    
$i $pageNowMinusRange;
                }
            }

            if (
$i && $i <= $x) {
                
$pages[] = $i;
            }
        }

/*
    Add page numbers with "geometrically increasing" distances.

    This helps me a lot when navigating through giant tables.

    Test case: table with 2.28 million sets, 76190 pages. Page of interest is
    between 72376 and 76190.
    Selecting page 72376.
    Now, old version enumerated only +/- 10 pages around 72376 and the
    percentage increment produced steps of about 3000.

    The following code adds page numbers +/- 2,4,8,16,32,64,128,256 etc.
    around the current page.
*/

        
$i $pageNow;
        
$dist 1;
        while (
$i $x) {
            
$dist $dist;
            
$i $pageNow $dist;
            if (
$i && $i <= $x) {
                
$pages[] = $i;
            }
        }

        
$i $pageNow;
        
$dist 1;
        while (
$i >0) {
            
$dist $dist;
            
$i $pageNow $dist;
            if (
$i && $i <= $x) {
                
$pages[] = $i;
            }
        }

        
// Since because of ellipsing of the current page some numbers may be double,
        // we unify our array:
        
sort($pages);
        
$pages array_unique($pages);
    }

    foreach (
$pages as $i) {
        if (
$i == $pageNow) {
            
$selected 'selected="selected" style="font-weight: bold"';
        } else {
            
$selected '';
        }
        
$gotopage .= '                <option ' $selected
            
' value="' . (($i 1) * $rows) . '">' $i '</option>' "\n";
    }

    
$gotopage .= ' </select><noscript><input type="submit" value="'
        
__('Go') . '" /></noscript>';

    return 
$gotopage;
// end function


/**
 * Generate navigation for a list
 *
 * @param int    $count       number of elements in the list
 * @param int    $pos         current position in the list
 * @param array  $_url_params url parameters
 * @param string $script      script name for form target
 * @param string $frame       target frame
 * @param int    $max_count   maximum number of elements to display from the list
 *
 * @access  public
 *
 * @todo    use $pos from $_url_params
 */
function PMA_listNavigator($count$pos$_url_params$script$frame$max_count)
{

    if (
$max_count $count) {
        echo 
'frame_navigation' == $frame
            
'<div id="navidbpageselector">' "\n"
            
'';
        echo 
__('Page number:');
        echo 
'frame_navigation' == $frame '<br />' ' ';

        
// Move to the beginning or to the previous page
        
if ($pos 0) {
            
// patch #474210 - part 1
            
if ($GLOBALS['cfg']['NavigationBarIconic']) {
                
$caption1 '&lt;&lt;';
                
$caption2 ' &lt; ';
                
$title1   ' title="' _pgettext('First page''Begin') . '"';
                
$title2   ' title="' _pgettext('Previous page''Previous') . '"';
            } else {
                
$caption1 _pgettext('First page''Begin') . ' &lt;&lt;';
                
$caption2 _pgettext('Previous page''Previous') . ' &lt;';
                
$title1   '';
                
$title2   '';
            } 
// end if... else...
            
$_url_params['pos'] = 0;
            echo 
'<a' $title1 ' href="' $script
                
PMA_generate_common_url($_url_params) . '" target="'
                
$frame '">' $caption1 '</a>';
            
$_url_params['pos'] = $pos $max_count;
            echo 
'<a' $title2 ' href="' $script
                
PMA_generate_common_url($_url_params) . '" target="'
                
$frame '">' $caption2 '</a>';
        }

        echo 
"\n"'<form action="./'basename($script), '" method="post" target="'$frame'">'"\n";
        echo 
PMA_generate_common_hidden_inputs($_url_params);
        echo 
PMA_pageselector(
            
$max_count,
            
floor(($pos 1) / $max_count) + 1,
            
ceil($count $max_count)
        );
        echo 
'</form>';

        if (
$pos $max_count $count) {
            if (
$GLOBALS['cfg']['NavigationBarIconic']) {
                
$caption3 ' &gt; ';
                
$caption4 '&gt;&gt;';
                
$title3   ' title="' _pgettext('Next page''Next') . '"';
                
$title4   ' title="' _pgettext('Last page''End') . '"';
            } else {
                
$caption3 '&gt; ' _pgettext('Next page''Next');
                
$caption4 '&gt;&gt; ' _pgettext('Last page''End');
                
$title3   '';
                
$title4   '';
            } 
// end if... else...
            
$_url_params['pos'] = $pos $max_count;
            echo 
'<a' $title3 ' href="' $script
                
PMA_generate_common_url($_url_params) . '" target="'
                
$frame '">' $caption3 '</a>';
            
$_url_params['pos'] = floor($count $max_count) * $max_count;
            if (
$_url_params['pos'] == $count) {
                
$_url_params['pos'] = $count $max_count;
            }
            echo 
'<a' $title4 ' href="' $script
                
PMA_generate_common_url($_url_params) . '" target="'
                
$frame '">' $caption4 '</a>';
        }
        echo 
"\n";
        if (
'frame_navigation' == $frame) {
            echo 
'</div>' "\n";
        }
    }
}

/**
 * replaces %u in given path with current user name
 *
 * example:
 * <code>
 * $user_dir = PMA_userDir('/var/pma_tmp/%u/'); // '/var/pma_tmp/root/'
 *
 * </code>
 *
 * @param string $dir with wildcard for user
 *
 * @return  string  per user directory
 */
function PMA_userDir($dir)
{
    
// add trailing slash
    
if (substr($dir, -1) != '/') {
        
$dir .= '/';
    }

    return 
str_replace('%u'$GLOBALS['cfg']['Server']['user'], $dir);
}

/**
 * returns html code for db link to default db page
 *
 * @param string $database database
 *
 * @return  string  html link to default db page
 */
function PMA_getDbLink($database null)
{
    if (! 
strlen($database)) {
        if (! 
strlen($GLOBALS['db'])) {
            return 
'';
        }
        
$database $GLOBALS['db'];
    } else {
        
$database PMA_unescape_mysql_wildcards($database);
    }

    return 
'<a href="' $GLOBALS['cfg']['DefaultTabDatabase'] . '?'
        
PMA_generate_common_url($database) . '" title="'
        
sprintf(
            
__('Jump to database &quot;%s&quot;.'),
            
htmlspecialchars($database)
        )
        . 
'">' htmlspecialchars($database) . '</a>';
}

/**
 * Displays a lightbulb hint explaining a known external bug
 * that affects a functionality
 *
 * @param string $functionality   localized message explaining the func.
 * @param string $component       'mysql' (eventually, 'php')
 * @param string $minimum_version of this component
 * @param string $bugref          bug reference for this component
 */
function PMA_externalBug($functionality$component$minimum_version$bugref)
{
    if (
$component == 'mysql' && PMA_MYSQL_INT_VERSION $minimum_version) {
        echo 
PMA_showHint(
            
sprintf(
                
__('The %s functionality is affected by a known bug, see %s'),
                
$functionality,
                
PMA_linkURL('http://bugs.mysql.com/') . $bugref
            
)
        );
    }
}

/**
 * Generates and echoes an HTML checkbox
 *
 * @param string  $html_field_name the checkbox HTML field
 * @param string  $label           label for checkbox
 * @param boolean $checked         is it initially checked?
 * @param boolean $onclick         should it submit the form on click?
 *
 * @return the HTML for the checkbox
 */
function PMA_display_html_checkbox($html_field_name$label$checked$onclick)
{

    echo 
'<input type="checkbox" name="' $html_field_name '" id="'
        
$html_field_name '"' . ($checked ' checked="checked"' '')
        . (
$onclick ' class="autosubmit"' '') . ' /><label for="'
        
$html_field_name '">' $label '</label>';
}

/**
 * Generates and echoes a set of radio HTML fields
 *
 * @param string  $html_field_name the radio HTML field
 * @param array   $choices         the choices values and labels
 * @param string  $checked_choice  the choice to check by default
 * @param boolean $line_break      whether to add an HTML line break after a choice
 * @param boolean $escape_label    whether to use htmlspecialchars() on label
 * @param string  $class           enclose each choice with a div of this class
 *
 * @return the HTML for the tadio buttons
 */
function PMA_display_html_radio($html_field_name$choices$checked_choice '',
$line_break true$escape_label true$class='')
{
    foreach (
$choices as $choice_value => $choice_label) {
        if (! empty(
$class)) {
            echo 
'<div class="' $class '">';
        }
        
$html_field_id $html_field_name '_' $choice_value;
        echo 
'<input type="radio" name="' $html_field_name '" id="'
            
$html_field_id '" value="' htmlspecialchars($choice_value) . '"';
        if (
$choice_value == $checked_choice) {
            echo 
' checked="checked"';
        }
        echo 
' />' "\n";
        echo 
'<label for="' $html_field_id '">'
            
. ($escape_label htmlspecialchars($choice_label)  : $choice_label)
            . 
'</label>';
        if (
$line_break) {
            echo 
'<br />';
        }
        if (! empty(
$class)) {
            echo 
'</div>';
        }
        echo 
"\n";
    }
}

/**
 * Generates and returns an HTML dropdown
 *
 * @param string $select_name   name for the select element
 * @param array  $choices       choices values
 * @param string $active_choice the choice to select by default
 * @param string $id            id of the select element; can be different in case
 *                              the dropdown is present more than once on the page
 *
 * @return string
 *
 * @todo    support titles
 */
function PMA_generate_html_dropdown($select_name$choices$active_choice$id)
{
    
$result '<select name="' htmlspecialchars($select_name) . '" id="'
        
htmlspecialchars($id) . '">';
    foreach (
$choices as $one_choice_value => $one_choice_label) {
        
$result .= '<option value="' htmlspecialchars($one_choice_value) . '"';
        if (
$one_choice_value == $active_choice) {
            
$result .= ' selected="selected"';
        }
        
$result .= '>' htmlspecialchars($one_choice_label) . '</option>';
    }
    
$result .= '</select>';
    return 
$result;
}

/**
 * Generates a slider effect (jQjuery)
 * Takes care of generating the initial <div> and the link
 * controlling the slider; you have to generate the </div> yourself
 * after the sliding section.
 *
 * @param string $id      the id of the <div> on which to apply the effect
 * @param string $message the message to show as a link
 */
function PMA_generate_slider_effect($id$message)
{
    if (
$GLOBALS['cfg']['InitialSlidersState'] == 'disabled') {
        echo 
'<div id="' $id '">';
        return;
    }
    
/**
     * Bad hack on the next line. document.write() conflicts with jQuery, hence,
     * opening the <div> with PHP itself instead of JavaScript.
     *
     * @todo find a better solution that uses $.append(), the recommended method
     * maybe by using an additional param, the id of the div to append to
     */
    
?>
<div id="<?php echo $id?><?php echo $GLOBALS['cfg']['InitialSlidersState'] == 'closed' ' style="display: none; overflow:auto;"' ''?> class="pma_auto_slider" title="<?php echo htmlspecialchars($message); ?>">
    <?php
}

/**
 * Creates an AJAX sliding toggle button
 * (or and equivalent form when AJAX is disabled)
 *
 * @param string $action      The URL for the request to be executed
 * @param string $select_name The name for the dropdown box
 * @param array  $options     An array of options (see rte_footer.lib.php)
 * @param string $callback    A JS snippet to execute when the request is
 *                            successfully processed
 *
 * @return   string   HTML code for the toggle button
 */
function PMA_toggleButton($action$select_name$options$callback)
{
    
// Do the logic first
    
$link_on "$action&amp;$select_name=" urlencode($options[1]['value']);
    
$link_off "$action&amp;$select_name=" urlencode($options[0]['value']);
    if (
$options[1]['selected'] == true) {
        
$state 'on';
    } else if (
$options[0]['selected'] == true) {
        
$state 'off';
    } else {
        
$state 'on';
    }
    
$selected1 '';
    
$selected0 '';
    if (
$options[1]['selected'] == true) {
        
$selected1 " selected='selected'";
    } else if (
$options[0]['selected'] == true) {
        
$selected0 " selected='selected'";
    }
    
// Generate output
    
$retval  "<!-- TOGGLE START -->\n";
    if (
$GLOBALS['cfg']['AjaxEnable'] && is_readable($_SESSION['PMA_Theme']->getImgPath() . 'toggle-ltr.png')) {
        
$retval .= "<noscript>\n";
    }
    
$retval .= "<div class='wrapper'>\n";
    
$retval .= "    <form action='$action' method='post'>\n";
    
$retval .= "        <select name='$select_name'>\n";
    
$retval .= "            <option value='{$options[1]['value']}'$selected1>";
    
$retval .= "                {$options[1]['label']}\n";
    
$retval .= "            </option>\n";
    
$retval .= "            <option value='{$options[0]['value']}'$selected0>";
    
$retval .= "                {$options[0]['label']}\n";
    
$retval .= "            </option>\n";
    
$retval .= "        </select>\n";
    
$retval .= "        <input type='submit' value='" __('Change') . "'/>\n";
    
$retval .= "    </form>\n";
    
$retval .= "</div>\n";
    if (
$GLOBALS['cfg']['AjaxEnable'] && is_readable($_SESSION['PMA_Theme']->getImgPath() . 'toggle-ltr.png')) {
        
$retval .= "</noscript>\n";
        
$retval .= "<div class='wrapper toggleAjax hide'>\n";
        
$retval .= "    <div class='toggleButton'>\n";
        
$retval .= "        <div title='" __('Click to toggle') . "' class='container $state'>\n";
        
$retval .= "            <img src='{$GLOBALS['pmaThemeImage']}toggle-{$GLOBALS['text_dir']}.png'\n";
        
$retval .= "                 alt='' />\n";
        
$retval .= "            <table cellspacing='0' cellpadding='0'><tr>\n";
        
$retval .= "                <tbody>\n";
        
$retval .= "                <td class='toggleOn'>\n";
        
$retval .= "                    <span class='hide'>$link_on</span>\n";
        
$retval .= "                    <div>";
        
$retval .= str_replace(' ''&nbsp;'$options[1]['label']) . "</div>\n";
        
$retval .= "                </td>\n";
        
$retval .= "                <td><div>&nbsp;</div></td>\n";
        
$retval .= "                <td class='toggleOff'>\n";
        
$retval .= "                    <span class='hide'>$link_off</span>\n";
        
$retval .= "                    <div>";
        
$retval .= str_replace(' ''&nbsp;'$options[0]['label']) . "</div>\n";
        
$retval .= "                    </div>\n";
        
$retval .= "                </tbody>\n";
        
$retval .= "            </tr></table>\n";
        
$retval .= "            <span class='hide callback'>$callback</span>\n";
        
$retval .= "            <span class='hide text_direction'>{$GLOBALS['text_dir']}</span>\n";
        
$retval .= "        </div>\n";
        
$retval .= "    </div>\n";
        
$retval .= "</div>\n";
    }
    
$retval .= "<!-- TOGGLE END -->";

    return 
$retval;
// end PMA_toggleButton()

/**
 * Clears cache content which needs to be refreshed on user change.
 *
 * @return nothing
 */
function PMA_clearUserCache()
{
    
PMA_cacheUnset('is_superuser'true);
}

/**
 * Verifies if something is cached in the session
 *
 * @param string   $var    variable name
 * @param int|true $server server
 *
 * @return boolean
 */
function PMA_cacheExists($var$server 0)
{
    if (
true === $server) {
        
$server $GLOBALS['server'];
    }
    return isset(
$_SESSION['cache']['server_' $server][$var]);
}

/**
 * Gets cached information from the session
 *
 * @param string   $var    varibale name
 * @param int|true $server server
 *
 * @return mixed
 */
function PMA_cacheGet($var$server 0)
{
    if (
true === $server) {
        
$server $GLOBALS['server'];
    }
    if (isset(
$_SESSION['cache']['server_' $server][$var])) {
        return 
$_SESSION['cache']['server_' $server][$var];
    } else {
        return 
null;
    }
}

/**
 * Caches information in the session
 *
 * @param string   $var    variable name
 * @param mixed    $val    value
 * @param int|true $server server
 *
 * @return mixed
 */
function PMA_cacheSet($var$val null$server 0)
{
    if (
true === $server) {
        
$server $GLOBALS['server'];
    }
    
$_SESSION['cache']['server_' $server][$var] = $val;
}

/**
 * Removes cached information from the session
 *
 * @param string   $var    variable name
 * @param int|true $server server
 *
 * @return nothing
 */
function PMA_cacheUnset($var$server 0)
{
    if (
true === $server) {
        
$server $GLOBALS['server'];
    }
    unset(
$_SESSION['cache']['server_' $server][$var]);
}

/**
 * Converts a bit value to printable format;
 * in MySQL a BIT field can be from 1 to 64 bits so we need this
 * function because in PHP, decbin() supports only 32 bits
 *
 * @param numeric $value  coming from a BIT field
 * @param integer $length length
 *
 * @return  string  the printable value
 */
function PMA_printable_bit_value($value$length)
{
    
$printable '';
    for (
$i 0$len_ceiled ceil($length 8); $i $len_ceiled$i++) {
        
$printable .= sprintf('%08d'decbin(ord(substr($value$i1))));
    }
    
$printable substr($printable, -$length);
    return 
$printable;
}

/**
 * Verifies whether the value contains a non-printable character
 *
 * @param string $value value
 *
 * @return  boolean
 */
function PMA_contains_nonprintable_ascii($value)
{
    return 
preg_match('@[^[:print:]]@'$value);
}

/**
 * Converts a BIT type default value
 * for example, b'010' becomes 010
 *
 * @param string $bit_default_value value
 *
 * @return  string the converted value
 */
function PMA_convert_bit_default_value($bit_default_value)
{
    return 
strtr($bit_default_value, array("b" => """'" => ""));
}

/**
 * Extracts the various parts from a field type spec
 *
 * @param string $fieldspec Field specification
 *
 * @return  array associative array containing type, spec_in_brackets
 *          and possibly enum_set_values (another array)
 */
function PMA_extractFieldSpec($fieldspec)
{
    
$first_bracket_pos strpos($fieldspec'(');
    if (
$first_bracket_pos) {
        
$spec_in_brackets chop(
            
substr(
                
$fieldspec,
                
$first_bracket_pos 1,
                (
strrpos($fieldspec')') - $first_bracket_pos 1)
            )
        );
        
// convert to lowercase just to be sure
        
$type strtolower(chop(substr($fieldspec0$first_bracket_pos)));
    } else {
        
$type strtolower($fieldspec);
        
$spec_in_brackets '';
    }

    if (
'enum' == $type || 'set' == $type) {
        
// Define our working vars
        
$enum_set_values PMA_parseEnumSetValues($fieldspecfalse);
        
$printtype $type '(' .  str_replace("','""', '"$spec_in_brackets) . ')';
        
$binary false;
        
$unsigned false;
        
$zerofill false;
    } else {
        
$enum_set_values = array();

        
/* Create printable type name */
        
$printtype strtolower($fieldspec);

        
// Strip the "BINARY" attribute, except if we find "BINARY(" because
        // this would be a BINARY or VARBINARY field type;
        // by the way, a BLOB should not show the BINARY attribute
        // because this is not accepted in MySQL syntax.
        
if (preg_match('@binary@'$printtype) && ! preg_match('@binary[\(]@'$printtype)) {
            
$printtype preg_replace('@binary@'''$printtype);
            
$binary true;
        } else {
            
$binary false;
        }
        
$printtype preg_replace('@zerofill@'''$printtype, -1$zerofill_cnt);
        
$zerofill = ($zerofill_cnt 0);
        
$printtype preg_replace('@unsigned@'''$printtype, -1$unsigned_cnt);
        
$unsigned = ($unsigned_cnt 0);
        
$printtype trim($printtype);

    }

    
$attribute     ' ';
    if (
$binary) {
        
$attribute 'BINARY';
    }
    if (
$unsigned) {
        
$attribute 'UNSIGNED';
    }
    if (
$zerofill) {
        
$attribute 'UNSIGNED ZEROFILL';
    }

    return array(
        
'type' => $type,
        
'spec_in_brackets' => $spec_in_brackets,
        
'enum_set_values'  => $enum_set_values,
        
'print_type' => $printtype,
        
'binary' => $binary,
        
'unsigned' => $unsigned,
        
'zerofill' => $zerofill,
        
'attribute' => $attribute,
    );
}

/**
 * Verifies if this table's engine supports foreign keys
 *
 * @param string $engine engine
 *
 * @return  boolean
 */
function PMA_foreignkey_supported($engine)
{
    
$engine strtoupper($engine);
    if (
'INNODB' == $engine || 'PBXT' == $engine) {
        return 
true;
    } else {
        return 
false;
    }
}

/**
 * Replaces some characters by a displayable equivalent
 *
 * @param string $content content
 *
 * @return  string the content with characters replaced
 */
function PMA_replace_binary_contents($content)
{
    
$result str_replace("\x00"'\0'$content);
    
$result str_replace("\x08"'\b'$result);
    
$result str_replace("\x0a"'\n'$result);
    
$result str_replace("\x0d"'\r'$result);
    
$result str_replace("\x1a"'\Z'$result);
    return 
$result;
}

/**
 * Converts GIS data to Well Known Text format
 *
 * @param binary $data        GIS data
 * @param bool   $includeSRID Add SRID to the WKT
 *
 * @return GIS data in Well Know Text format
 */
function PMA_asWKT($data$includeSRID false)
{
    
// Convert to WKT format
    
$hex bin2hex($data);
    
$wktsql     "SELECT ASTEXT(x'" $hex "')";
    if (
$includeSRID) {
        
$wktsql .= ", SRID(x'" $hex "')";
    }
    
$wktresult  PMA_DBI_try_query($wktsqlnullPMA_DBI_QUERY_STORE);
    
$wktarr     PMA_DBI_fetch_row($wktresult0);
    
$wktval     $wktarr[0];
    if (
$includeSRID) {
        
$srid $wktarr[1];
        
$wktval "'" $wktval "'," $srid;
    }
    @
PMA_DBI_free_result($wktresult);
    return 
$wktval;
}

/**
 * If the string starts with a \r\n pair (0x0d0a) add an extra \n
 *
 * @param string $string string
 *
 * @return  string with the chars replaced
 */

function PMA_duplicateFirstNewline($string)
{
    
$first_occurence strpos($string"\r\n");
    if (
$first_occurence === 0) {
        
$string "\n".$string;
    }
    return 
$string;
}

/**
 * Get the action word corresponding to a script name
 * in order to display it as a title in navigation panel
 *
 * @param string $target a valid value for $cfg['LeftDefaultTabTable'],
 *                       $cfg['DefaultTabTable'] or $cfg['DefaultTabDatabase']
 *
 * @return array
 */
function PMA_getTitleForTarget($target)
{
    
$mapping = array(
        
// Values for $cfg['DefaultTabTable']
        
'tbl_structure.php' =>  __('Structure'),
        
'tbl_sql.php' => __('SQL'),
        
'tbl_select.php' =>__('Search'),
        
'tbl_change.php' =>__('Insert'),
        
'sql.php' => __('Browse'),

        
// Values for $cfg['DefaultTabDatabase']
        
'db_structure.php' => __('Structure'),
        
'db_sql.php' => __('SQL'),
        
'db_search.php' => __('Search'),
        
'db_operations.php' => __('Operations'),
    );
    return 
$mapping[$target];
}

/**
 * Formats user string, expanding @VARIABLES@, accepting strftime format string.
 *
 * @param string   $string  Text where to do expansion.
 * @param function $escape  Function to call for escaping variable values.
 * @param array    $updates Array with overrides for default parameters
 *                 (obtained from GLOBALS).
 *
 * @return string
 */
function PMA_expandUserString($string$escape null$updates = array())
{
    
/* Content */
    
$vars['http_host'] = PMA_getenv('HTTP_HOST') ? PMA_getenv('HTTP_HOST') : '';
    
$vars['server_name'] = $GLOBALS['cfg']['Server']['host'];
    
$vars['server_verbose'] = $GLOBALS['cfg']['Server']['verbose'];
    
$vars['server_verbose_or_name'] = ! empty($GLOBALS['cfg']['Server']['verbose'])
        ? 
$GLOBALS['cfg']['Server']['verbose']
        : 
$GLOBALS['cfg']['Server']['host'];
    
$vars['database'] = $GLOBALS['db'];
    
$vars['table'] = $GLOBALS['table'];
    
$vars['phpmyadmin_version'] = 'phpMyAdmin ' PMA_VERSION;

    
/* Update forced variables */
    
foreach ($updates as $key => $val) {
        
$vars[$key] = $val;
    }

    
/* Replacement mapping */
    /*
     * The __VAR__ ones are for backward compatibility, because user
     * might still have it in cookies.
     */
    
$replace = array(
        
'@HTTP_HOST@' => $vars['http_host'],
        
'@SERVER@' => $vars['server_name'],
        
'__SERVER__' => $vars['server_name'],
        
'@VERBOSE@' => $vars['server_verbose'],
        
'@VSERVER@' => $vars['server_verbose_or_name'],
        
'@DATABASE@' => $vars['database'],
        
'__DB__' => $vars['database'],
        
'@TABLE@' => $vars['table'],
        
'__TABLE__' => $vars['table'],
        
'@PHPMYADMIN@' => $vars['phpmyadmin_version'],
        );

    
/* Optional escaping */
    
if (!is_null($escape)) {
        foreach (
$replace as $key => $val) {
            
$replace[$key] = $escape($val);
        }
    }

    
/* Backward compatibility in 3.5.x */
    
if (strpos($string'@FIELDS@') !== false) {
        
$string strtr($string, array('@FIELDS@' => '@COLUMNS@'));
    }

    
/* Fetch columns list if required */
    
if (strpos($string'@COLUMNS@') !== false) {
        
$columns_list PMA_DBI_get_columns($GLOBALS['db'], $GLOBALS['table']);

        
$column_names = array();
        foreach (
$columns_list as $column) {
            if (! 
is_null($escape)) {
                
$column_names[] = $escape($column['Field']);
            } else {
                
$column_names[] = $field['Field'];
            }
        }

        
$replace['@COLUMNS@'] = implode(','$column_names);
    }

    
/* Do the replacement */
    
return strtr(strftime($string), $replace);
}

/**
 * function that generates a json output for an ajax request and ends script
 * execution
 *
 * @param PMA_Message|string $message    message string containing the
 *                                       html of the message
 * @param bool               $success    success whether the ajax request
 *                                       was successfull
 * @param array              $extra_data extra data  optional -
 *                                       any other data as part of the json request
 *
 * @return nothing
 */
function PMA_ajaxResponse($message$success true$extra_data = array())
{
    
$response = array();
    if ( 
$success == true ) {
        
$response['success'] = true;
        if (
$message instanceof PMA_Message) {
            
$response['message'] = $message->getDisplay();
        } else {
            
$response['message'] = $message;
        }
    } else {
        
$response['success'] = false;
        if (
$message instanceof PMA_Message) {
            
$response['error'] = $message->getDisplay();
        } else {
            
$response['error'] = $message;
        }
    }

    
// If extra_data has been provided, append it to the response array
    
if ( ! empty($extra_data) && count($extra_data) > ) {
        
$response array_merge($response$extra_data);
    }

    
// Set the Content-Type header to JSON so that jQuery parses the
    // response correctly.
    //
    // At this point, other headers might have been sent;
    // even if $GLOBALS['is_header_sent'] is true,
    // we have to send these additional headers.
    
if (!defined('TESTSUITE')) {
        
header('Cache-Control: no-cache');
        
header("Content-Type: application/json");
    }

    echo 
json_encode($response);

    if (!
defined('TESTSUITE'))
        exit;
}

/**
 * Display the form used to browse anywhere on the local server for a file to import
 *
 * @param string $max_upload_size maximum upload size
 *
 * @return nothing
 */
function PMA_browseUploadFile($max_upload_size)
{
    echo 
'<label for="radio_import_file">' __("Browse your computer:") . '</label>';
    echo 
'<div id="upload_form_status" style="display: none;"></div>';
    echo 
'<div id="upload_form_status_info" style="display: none;"></div>';
    echo 
'<input type="file" name="import_file" id="input_import_file" />';
    echo 
PMA_displayMaximumUploadSize($max_upload_size) . "\n";
    
// some browsers should respect this :)
    
echo PMA_generateHiddenMaxFileSize($max_upload_size) . "\n";
}

/**
 * Display the form used to select a file to import from the server upload directory
 *
 * @param array  $import_list array of import types
 * @param string $uploaddir   upload directory
 *
 * @return nothing
 */
function PMA_selectUploadFile($import_list$uploaddir)
{
    echo 
'<label for="radio_local_import_file">' sprintf(__("Select from the web server upload directory <b>%s</b>:"), htmlspecialchars(PMA_userDir($uploaddir))) . '</label>';
    
$extensions '';
    foreach (
$import_list as $key => $val) {
        if (!empty(
$extensions)) {
            
$extensions .= '|';
        }
        
$extensions .= $val['extension'];
    }
    
$matcher '@\.(' $extensions ')(\.('
        
PMA_supportedDecompressions() . '))?$@';

    
$active = (isset($timeout_passed) && $timeout_passed && isset($local_import_file))
        ? 
$local_import_file
        
'';
    
$files PMA_getFileSelectOptions(
        
PMA_userDir($uploaddir),
        
$matcher,
        
$active
    
);
    if (
$files === false) {
        
PMA_Message::error(
            
__('The directory you set for upload work cannot be reached')
        )->
display();
    } elseif (!empty(
$files)) {
        echo 
"\n";
        echo 
'    <select style="margin: 5px" size="1" name="local_import_file" id="select_local_import_file">' "\n";
        echo 
'        <option value="">&nbsp;</option>' "\n";
        echo 
$files;
        echo 
'    </select>' "\n";
    } elseif (empty (
$files)) {
        echo 
'<i>' __('There are no files to upload') . '</i>';
    }
}

/**
 * Build titles and icons for action links
 *
 * @return   array   the action titles
 */
function PMA_buildActionTitles()
{
    
$titles = array();

    
$titles['Browse']     = PMA_getIcon('b_browse.png'__('Browse'));
    
$titles['NoBrowse']   = PMA_getIcon('bd_browse.png'__('Browse'));
    
$titles['Search']     = PMA_getIcon('b_select.png'__('Search'));
    
$titles['NoSearch']   = PMA_getIcon('bd_select.png'__('Search'));
    
$titles['Insert']     = PMA_getIcon('b_insrow.png'__('Insert'));
    
$titles['NoInsert']   = PMA_getIcon('bd_insrow.png'__('Insert'));
    
$titles['Structure']  = PMA_getIcon('b_props.png'__('Structure'));
    
$titles['Drop']       = PMA_getIcon('b_drop.png'__('Drop'));
    
$titles['NoDrop']     = PMA_getIcon('bd_drop.png'__('Drop'));
    
$titles['Empty']      = PMA_getIcon('b_empty.png'__('Empty'));
    
$titles['NoEmpty']    = PMA_getIcon('bd_empty.png'__('Empty'));
    
$titles['Edit']       = PMA_getIcon('b_edit.png'__('Edit'));
    
$titles['NoEdit']     = PMA_getIcon('bd_edit.png'__('Edit'));
    
$titles['Export']     = PMA_getIcon('b_export.png'__('Export'));
    
$titles['NoExport']   = PMA_getIcon('bd_export.png'__('Export'));
    
$titles['Execute']    = PMA_getIcon('b_nextpage.png'__('Execute'));
    
$titles['NoExecute']  = PMA_getIcon('bd_nextpage.png'__('Execute'));
    return 
$titles;
}

/**
 * This function processes the datatypes supported by the DB, as specified in
 * $cfg['ColumnTypes'] and either returns an array (useful for quickly checking
 * if a datatype is supported) or an HTML snippet that creates a drop-down list.
 *
 * @param bool   $html     Whether to generate an html snippet or an array
 * @param string $selected The value to mark as selected in HTML mode
 *
 * @return  mixed   An HTML snippet or an array of datatypes.
 *
 */
function PMA_getSupportedDatatypes($html false$selected '')
{
    global 
$cfg;

    if (
$html) {
        
// NOTE: the SELECT tag in not included in this snippet.
        
$retval '';
        foreach (
$cfg['ColumnTypes'] as $key => $value) {
            if (
is_array($value)) {
                
$retval .= "<optgroup label='" htmlspecialchars($key) . "'>";
                foreach (
$value as $subvalue) {
                    if (
$subvalue == $selected) {
                        
$retval .= "<option selected='selected'>";
                        
$retval .= $subvalue;
                        
$retval .= "</option>";
                    } else if (
$subvalue === '-') {
                        
$retval .= "<option disabled='disabled'>";
                        
$retval .= $subvalue;
                        
$retval .= "</option>";
                    } else {
                        
$retval .= "<option>$subvalue</option>";
                    }
                }
                
$retval .= '</optgroup>';
            } else {
                if (
$selected == $value) {
                    
$retval .= "<option selected='selected'>$value</option>";
                } else {
                    
$retval .= "<option>$value</option>";
                }
            }
        }
    } else {
        
$retval = array();
        foreach (
$cfg['ColumnTypes'] as $value) {
            if (
is_array($value)) {
                foreach (
$value as $subvalue) {
                    if (
$subvalue !== '-') {
                        
$retval[] = $subvalue;
                    }
                }
            } else {
                if (
$value !== '-') {
                    
$retval[] = $value;
                }
            }
        }
    }

    return 
$retval;
// end PMA_getSupportedDatatypes()

/**
 * Returns a list of datatypes that are not (yet) handled by PMA.
 * Used by: tbl_change.php and libraries/db_routines.inc.php
 *
 * @return   array   list of datatypes
 */
function PMA_unsupportedDatatypes()
{
    
$no_support_types = array();
    return 
$no_support_types;
}

/**
 * Return GIS data types
 *
 * @param bool $upper_case whether to return values in upper case
 *
 * @return array GIS data types
 */
function PMA_getGISDatatypes($upper_case false)
{
    
$gis_data_types = array(
        
'geometry',
        
'point',
        
'linestring',
        
'polygon',
        
'multipoint',
        
'multilinestring',
        
'multipolygon',
        
'geometrycollection'
    
);
    if (
$upper_case) {
        for (
$i 0$i count($gis_data_types); $i++) {
            
$gis_data_types[$i] = strtoupper($gis_data_types[$i]);
        }
    }

    return 
$gis_data_types;
}

/**
 * Generates GIS data based on the string passed.
 *
 * @param string $gis_string GIS string
 *
 * @return GIS data enclosed in 'GeomFromText' function
 */
function PMA_createGISData($gis_string)
{
    
$gis_string =  trim($gis_string);
    
$geom_types '(POINT|MULTIPOINT|LINESTRING|MULTILINESTRING|'
        
'POLYGON|MULTIPOLYGON|GEOMETRYCOLLECTION)';
    if (
preg_match("/^'" $geom_types "\(.*\)',[0-9]*$/i"$gis_string)) {
        return 
'GeomFromText(' $gis_string ')';
    } elseif (
preg_match("/^" $geom_types "\(.*\)$/i"$gis_string)) {
        return 
"GeomFromText('" $gis_string "')";
    } else {
        return 
$gis_string;
    }
}

/**
 * Returns the names and details of the functions
 * that can be applied on geometry data typess.
 *
 * @param string $geom_type if provided the output is limited to the functions
 *                          that are applicable to the provided geometry type.
 * @param bool   $binary    if set to false functions that take two geometries
 *                          as arguments will not be included.
 * @param bool   $display   if set to true seperators will be added to the
 *                          output array.
 *
 * @return array names and details of the functions that can be applied on
 *               geometry data typess.
 */
function PMA_getGISFunctions($geom_type null$binary true$display false)
{
    
$funcs = array();
    if (
$display) {
        
$funcs[] = array('display' => ' ');
    }

    
// Unary functions common to all geomety types
    
$funcs['Dimension']    = array('params' => 1'type' => 'int');
    
$funcs['Envelope']     = array('params' => 1'type' => 'Polygon');
    
$funcs['GeometryType'] = array('params' => 1'type' => 'text');
    
$funcs['SRID']         = array('params' => 1'type' => 'int');
    
$funcs['IsEmpty']      = array('params' => 1'type' => 'int');
    
$funcs['IsSimple']     = array('params' => 1'type' => 'int');

    
$geom_type trim(strtolower($geom_type));
    if (
$display && $geom_type != 'geometry' && $geom_type != 'multipoint') {
        
$funcs[] = array('display' => '--------');
    }

    
// Unary functions that are specific to each geomety type
    
if ($geom_type == 'point') {
        
$funcs['X'] = array('params' => 1'type' => 'float');
        
$funcs['Y'] = array('params' => 1'type' => 'float');

    } elseif (
$geom_type == 'multipoint') {
        
// no fucntions here
    
} elseif ($geom_type == 'linestring') {
        
$funcs['EndPoint']   = array('params' => 1'type' => 'point');
        
$funcs['GLength']    = array('params' => 1'type' => 'float');
        
$funcs['NumPoints']  = array('params' => 1'type' => 'int');
        
$funcs['StartPoint'] = array('params' => 1'type' => 'point');
        
$funcs['IsRing']     = array('params' => 1'type' => 'int');

    } elseif (
$geom_type == 'multilinestring') {
        
$funcs['GLength']  = array('params' => 1'type' => 'float');
        
$funcs['IsClosed'] = array('params' => 1'type' => 'int');

    } elseif (
$geom_type == 'polygon') {
        
$funcs['Area']             = array('params' => 1'type' => 'float');
        
$funcs['ExteriorRing']     = array('params' => 1'type' => 'linestring');
        
$funcs['NumInteriorRings'] = array('params' => 1'type' => 'int');

    } elseif (
$geom_type == 'multipolygon') {
        
$funcs['Area']     = array('params' => 1'type' => 'float');
        
$funcs['Centroid'] = array('params' => 1'type' => 'point');
        
// Not yet implemented in MySQL
        //$funcs['PointOnSurface'] = array('params' => 1, 'type' => 'point');

    
} elseif ($geom_type == 'geometrycollection') {
        
$funcs['NumGeometries'] = array('params' => 1'type' => 'int');
    }

    
// If we are asked for binary functions as well
    
if ($binary) {
        
// section seperator
        
if ($display) {
            
$funcs[] = array('display' => '--------');
        }
        if (
PMA_MYSQL_INT_VERSION 50601) {
            
$funcs['Crosses']    = array('params' => 2'type' => 'int');
            
$funcs['Contains']   = array('params' => 2'type' => 'int');
            
$funcs['Disjoint']   = array('params' => 2'type' => 'int');
            
$funcs['Equals']     = array('params' => 2'type' => 'int');
            
$funcs['Intersects'] = array('params' => 2'type' => 'int');
            
$funcs['Overlaps']   = array('params' => 2'type' => 'int');
            
$funcs['Touches']    = array('params' => 2'type' => 'int');
            
$funcs['Within']     = array('params' => 2'type' => 'int');
        } else {
            
// If MySQl version is greaeter than or equal 5.6.1, use the ST_ prefix.
            
$funcs['ST_Crosses']    = array('params' => 2'type' => 'int');
            
$funcs['ST_Contains']   = array('params' => 2'type' => 'int');
            
$funcs['ST_Disjoint']   = array('params' => 2'type' => 'int');
            
$funcs['ST_Equals']     = array('params' => 2'type' => 'int');
            
$funcs['ST_Intersects'] = array('params' => 2'type' => 'int');
            
$funcs['ST_Overlaps']   = array('params' => 2'type' => 'int');
            
$funcs['ST_Touches']    = array('params' => 2'type' => 'int');
            
$funcs['ST_Within']     = array('params' => 2'type' => 'int');

        }

        if (
$display) {
            
$funcs[] = array('display' => '--------');
        }
        
// Minimum bounding rectangle functions
        
$funcs['MBRContains']   = array('params' => 2'type' => 'int');
        
$funcs['MBRDisjoint']   = array('params' => 2'type' => 'int');
        
$funcs['MBREquals']     = array('params' => 2'type' => 'int');
        
$funcs['MBRIntersects'] = array('params' => 2'type' => 'int');
        
$funcs['MBROverlaps']   = array('params' => 2'type' => 'int');
        
$funcs['MBRTouches']    = array('params' => 2'type' => 'int');
        
$funcs['MBRWithin']     = array('params' => 2'type' => 'int');
    }
    return 
$funcs;
}

/**
 * Creates a dropdown box with MySQL functions for a particular column.
 *
 * @param array $field       Data about the column for which
 *                           to generate the dropdown
 * @param bool  $insert_mode Whether the operation is 'insert'
 *
 * @global   array    $cfg            PMA configuration
 * @global   array    $analyzed_sql   Analyzed SQL query
 * @global   mixed    $data           (null/string) FIXME: what is this for?
 *
 * @return   string   An HTML snippet of a dropdown list with function
 *                    names appropriate for the requested column.
 */
function PMA_getFunctionsForField($field$insert_mode)
{
    global 
$cfg$analyzed_sql$data;

    
$selected '';
    
// Find the current type in the RestrictColumnTypes. Will result in 'FUNC_CHAR'
    // or something similar. Then directly look up the entry in the
    // RestrictFunctions array, which'll then reveal the available dropdown options
    
if (isset($cfg['RestrictColumnTypes'][strtoupper($field['True_Type'])])
        && isset(
$cfg['RestrictFunctions'][$cfg['RestrictColumnTypes'][strtoupper($field['True_Type'])]])
    ) {
        
$current_func_type  $cfg['RestrictColumnTypes'][strtoupper($field['True_Type'])];
        
$dropdown           $cfg['RestrictFunctions'][$current_func_type];
        
$default_function   $cfg['DefaultFunctions'][$current_func_type];
    } else {
        
$dropdown = array();
        
$default_function   '';
    }
    
$dropdown_built = array();
    
$op_spacing_needed false;
    
// what function defined as default?
    // for the first timestamp we don't set the default function
    // if there is a default value for the timestamp
    // (not including CURRENT_TIMESTAMP)
    // and the column does not have the
    // ON UPDATE DEFAULT TIMESTAMP attribute.
    
if ($field['True_Type'] == 'timestamp'
        
&& empty($field['Default'])
        && empty(
$data)
        && ! isset(
$analyzed_sql[0]['create_table_fields'][$field['Field']]['on_update_current_timestamp'])
        && 
$analyzed_sql[0]['create_table_fields'][$field['Field']]['default_value'] != 'NULL'
    
) {
        
$default_function $cfg['DefaultFunctions']['first_timestamp'];
    }
    
// For primary keys of type char(36) or varchar(36) UUID if the default function
    // Only applies to insert mode, as it would silently trash data on updates.
    
if ($insert_mode
        
&& $field['Key'] == 'PRI'
        
&& ($field['Type'] == 'char(36)' || $field['Type'] == 'varchar(36)')
    ) {
         
$default_function $cfg['DefaultFunctions']['FUNC_UUID'];
    }
    
// this is set only when appropriate and is always true
    
if (isset($field['display_binary_as_hex'])) {
        
$default_function 'UNHEX';
    }

    
// Create the output
    
$retval '                <option></option>' "\n";
    
// loop on the dropdown array and print all available options for that field.
    
foreach ($dropdown as $each_dropdown) {
        
$retval .= '                ';
        
$retval .= '<option';
        if (
$default_function === $each_dropdown) {
            
$retval .= ' selected="selected"';
        }
        
$retval .= '>' $each_dropdown '</option>' "\n";
        
$dropdown_built[$each_dropdown] = 'true';
        
$op_spacing_needed true;
    }
    
// For compatibility's sake, do not let out all other functions. Instead
    // print a separator (blank) and then show ALL functions which weren't shown
    // yet.
    
$cnt_functions count($cfg['Functions']);
    for (
$j 0$j $cnt_functions$j++) {
        if (! isset(
$dropdown_built[$cfg['Functions'][$j]])
            || 
$dropdown_built[$cfg['Functions'][$j]] != 'true'
        
) {
            
// Is current function defined as default?
            
$selected = ($field['first_timestamp'] && $cfg['Functions'][$j] == $cfg['DefaultFunctions']['first_timestamp'])
                        || (! 
$field['first_timestamp'] && $cfg['Functions'][$j] == $default_function)
                      ? 
' selected="selected"'
                      
'';
            if (
$op_spacing_needed == true) {
                
$retval .= '                ';
                
$retval .= '<option value="">--------</option>' "\n";
                
$op_spacing_needed false;
            }

            
$retval .= '                ';
            
$retval .= '<option' $selected '>' $cfg['Functions'][$j]
                . 
'</option>' "\n";
        }
    } 
// end for

    
return $retval;
// end PMA_getFunctionsForField()

/**
 * Checks if the current user has a specific privilege and returns true if the
 * user indeed has that privilege or false if (s)he doesn't. This function must
 * only be used for features that are available since MySQL 5, because it
 * relies on the INFORMATION_SCHEMA database to be present.
 *
 * Example:   PMA_currentUserHasPrivilege('CREATE ROUTINE', 'mydb');
 *            // Checks if the currently logged in user has the global
 *            // 'CREATE ROUTINE' privilege or, if not, checks if the
 *            // user has this privilege on database 'mydb'.
 *
 * @param string $priv The privilege to check
 * @param mixed  $db   null, to only check global privileges
 *                     string, db name where to also check for privileges
 * @param mixed  $tbl  null, to only check global/db privileges
 *                     string, table name where to also check for privileges
 *
 * @return bool
 */
function PMA_currentUserHasPrivilege($priv$db null$tbl null)
{
    
// Get the username for the current user in the format
    // required to use in the information schema database.
    
$user PMA_DBI_fetch_value("SELECT CURRENT_USER();");
    if (
$user === false) {
        return 
false;
    }
    
$user explode('@'$user);
    
$username  "''";
    
$username .= str_replace("'""''"$user[0]);
    
$username .= "''@''";
    
$username .= str_replace("'""''"$user[1]);
    
$username .= "''";
    
// Prepage the query
    
$query "SELECT `PRIVILEGE_TYPE` FROM `INFORMATION_SCHEMA`.`%s` "
           
"WHERE GRANTEE='%s' AND PRIVILEGE_TYPE='%s'";
    
// Check global privileges first.
    
if (PMA_DBI_fetch_value(
        
sprintf(
            
$query,
            
'USER_PRIVILEGES',
            
$username,
            
$priv
        
)
    )
    ) {
        return 
true;
    }
    
// If a database name was provided and user does not have the
    // required global privilege, try database-wise permissions.
    
if ($db !== null) {
        
// need to escape wildcards in db and table names, see bug #3518484
        
$db str_replace(array('%''_'), array('\%''\_'), $db);
        
$query .= " AND TABLE_SCHEMA='%s'";
        if (
PMA_DBI_fetch_value(
            
sprintf(
                
$query,
                
'SCHEMA_PRIVILEGES',
                
$username,
                
$priv,
                
PMA_sqlAddSlashes($db)
            )
        )
        ) {
            return 
true;
        }
    } else {
        
// There was no database name provided and the user
        // does not have the correct global privilege.
        
return false;
    }
    
// If a table name was also provided and we still didn't
    // find any valid privileges, try table-wise privileges.
    
if ($tbl !== null) {
        
// need to escape wildcards in db and table names, see bug #3518484
        
$tbl str_replace(array('%''_'), array('\%''\_'), $tbl);
        
$query .= " AND TABLE_NAME='%s'";
        if (
$retval PMA_DBI_fetch_value(
            
sprintf(
                
$query,
                
'TABLE_PRIVILEGES',
                
$username,
                
$priv,
                
PMA_sqlAddSlashes($db),
                
PMA_sqlAddSlashes($tbl)
            )
        )
        ) {
            return 
true;
        }
    }
    
// If we reached this point, the user does not
    // have even valid table-wise privileges.
    
return false;
}

/**
 * Returns server type for current connection
 *
 * Known types are: Drizzle, MariaDB and MySQL (default)
 *
 * @return string
 */
function PMA_getServerType()
{
    
$server_type 'MySQL';
    if (
PMA_DRIZZLE) {
        
$server_type 'Drizzle';
    } else if (
stripos(PMA_MYSQL_STR_VERSION'mariadb') !== false) {
        
$server_type 'MariaDB';
    } else if (
stripos(PMA_MYSQL_VERSION_COMMENT'percona') !== false) {
        
$server_type 'Percona Server';
    }
    return 
$server_type;
}

/**
 * Analyzes the limit clause and return the start and length attributes of it.
 *
 * @param string $limit_clause limit clause
 *
 * @return array Start and length attributes of the limit clause
 */
function PMA_analyzeLimitClause($limit_clause)
{
    
$start_and_length explode(','str_ireplace('LIMIT'''$limit_clause));
    return array(
        
'start'  => trim($start_and_length[0]),
        
'length' => trim($start_and_length[1])
    );
}

/**
 * Outputs HTML code for print button.
 *
 * @return nothing
 */
function PMA_printButton()
{
    echo 
'<p class="print_ignore">';
    echo 
'<input type="button" id="print" value="' __('Print') . '" />';
    echo 
'</p>';
}

/**
 * Parses ENUM/SET values
 *
 * @param string $definition The definition of the column
 *                           for which to parse the values
 * @param bool   $escapeHtml Whether to escape html entitites
 *
 * @return array
 */
function PMA_parseEnumSetValues($definition$escapeHtml true)
{
    
$values_string htmlentities($definition);
    
// There is a JS port of the below parser in functions.js
    // If you are fixing something here,
    // you need to also update the JS port.
    
$values = array();
    
$in_string false;
    
$buffer '';
    for (
$i=0$i<strlen($values_string); $i++) {
        
$curr $values_string[$i];
        
$next $i == strlen($values_string)-'' $values_string[$i+1];
        if (! 
$in_string && $curr == "'") {
            
$in_string true;
        } else if (
$in_string && $curr == "\\" && $next == "\\") {
            
$buffer .= "&#92;";
            
$i++;
        } else if (
$in_string && $next == "'" && ($curr == "'" || $curr == "\\")) {
            
$buffer .= "&#39;";
            
$i++;
        } else if (
$in_string && $curr == "'") {
            
$in_string false;
            
$values[] = $buffer;
            
$buffer '';
        } else if (
$in_string) {
             
$buffer .= $curr;
        }
    }
    if (
strlen($buffer) > 0) {
        
// The leftovers in the buffer are the last value (if any)
        
$values[] = $buffer;
    }
    if (! 
$escapeHtml) {
        foreach (
$values as $key => $value) {
            
$values[$key] = html_entity_decode($valueENT_QUOTES);
        }
    }
    return 
$values;
}

?>

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.0 [PHP 7 Update] [25.02.2019] maintained by HackingTool | HackingTool | Generation time: 0.0106 ]--