PageRenderTime 6ms CodeModel.GetById 29ms app.highlight 66ms RepoModel.GetById 1ms app.codeStats 2ms

/phpmyadmin/libraries/common.lib.php

https://bitbucket.org/DenizYldrm/openemr
PHP | 2367 lines | 1394 code | 200 blank | 773 comment | 353 complexity | 1bc5e5f686ab67e428d7770cdec0e54a MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php
   2/* vim: set expandtab sw=4 ts=4 sts=4: */
   3/**
   4 * Misc functions used all over the scripts.
   5 *
   6 * @version $Id$
   7 */
   8
   9/**
  10 * Exponential expression / raise number into power
  11 *
  12 * @uses    function_exists()
  13 * @uses    bcpow()
  14 * @uses    gmp_pow()
  15 * @uses    gmp_strval()
  16 * @uses    pow()
  17 * @param   number  $base
  18 * @param   number  $exp
  19 * @param   string  pow function use, or false for auto-detect
  20 * @return  mixed  string or float
  21 */
  22function PMA_pow($base, $exp, $use_function = false)
  23{
  24    static $pow_function = null;
  25
  26    if ($exp < 0) {
  27        return false;
  28    }
  29
  30    if (null == $pow_function) {
  31        if (function_exists('bcpow')) {
  32            // BCMath Arbitrary Precision Mathematics Function
  33            $pow_function = 'bcpow';
  34        } elseif (function_exists('gmp_pow')) {
  35            // GMP Function
  36            $pow_function = 'gmp_pow';
  37        } else {
  38            // PHP function
  39            $pow_function = 'pow';
  40        }
  41    }
  42
  43    if (! $use_function) {
  44        $use_function = $pow_function;
  45    }
  46
  47    switch ($use_function) {
  48        case 'bcpow' :
  49            //bcscale(10);
  50            $pow = bcpow($base, $exp);
  51            break;
  52        case 'gmp_pow' :
  53             $pow = gmp_strval(gmp_pow($base, $exp));
  54            break;
  55        case 'pow' :
  56            $base = (float) $base;
  57            $exp = (int) $exp;
  58            $pow = pow($base, $exp);
  59            break;
  60        default:
  61            $pow = $use_function($base, $exp);
  62    }
  63
  64    return $pow;
  65}
  66
  67/**
  68 * string PMA_getIcon(string $icon)
  69 *
  70 * @uses    $GLOBALS['pmaThemeImage']
  71 * @param   $icon   name of icon
  72 * @return          html img tag
  73 */
  74function PMA_getIcon($icon, $alternate = '')
  75{
  76    if ($GLOBALS['cfg']['PropertiesIconic']) {
  77        return '<img src="' . $GLOBALS['pmaThemeImage'] . $icon . '"'
  78            . ' title="' . $alternate . '" alt="' . $alternate . '"'
  79            . ' class="icon" width="16" height="16" />';
  80    } else {
  81        return $alternate;
  82    }
  83}
  84
  85/**
  86 * Displays the maximum size for an upload
  87 *
  88 * @uses    $GLOBALS['strMaximumSize']
  89 * @uses    PMA_formatByteDown()
  90 * @uses    sprintf()
  91 * @param   integer  the size
  92 *
  93 * @return  string   the message
  94 *
  95 * @access  public
  96 */
  97function PMA_displayMaximumUploadSize($max_upload_size)
  98{
  99    list($max_size, $max_unit) = PMA_formatByteDown($max_upload_size);
 100    return '(' . sprintf($GLOBALS['strMaximumSize'], $max_size, $max_unit) . ')';
 101}
 102
 103/**
 104 * Generates a hidden field which should indicate to the browser
 105 * the maximum size for upload
 106 *
 107 * @param   integer  the size
 108 *
 109 * @return  string   the INPUT field
 110 *
 111 * @access  public
 112 */
 113 function PMA_generateHiddenMaxFileSize($max_size)
 114 {
 115     return '<input type="hidden" name="MAX_FILE_SIZE" value="' .$max_size . '" />';
 116 }
 117
 118/**
 119 * Add slashes before "'" and "\" characters so a value containing them can
 120 * be used in a sql comparison.
 121 *
 122 * @uses    str_replace()
 123 * @param   string   the string to slash
 124 * @param   boolean  whether the string will be used in a 'LIKE' clause
 125 *                   (it then requires two more escaped sequences) or not
 126 * @param   boolean  whether to treat cr/lfs as escape-worthy entities
 127 *                   (converts \n to \\n, \r to \\r)
 128 *
 129 * @param   boolean  whether this function is used as part of the
 130 *                   "Create PHP code" dialog
 131 *
 132 * @return  string   the slashed string
 133 *
 134 * @access  public
 135 */
 136function PMA_sqlAddslashes($a_string = '', $is_like = false, $crlf = false, $php_code = false)
 137{
 138    if ($is_like) {
 139        $a_string = str_replace('\\', '\\\\\\\\', $a_string);
 140    } else {
 141        $a_string = str_replace('\\', '\\\\', $a_string);
 142    }
 143
 144    if ($crlf) {
 145        $a_string = str_replace("\n", '\n', $a_string);
 146        $a_string = str_replace("\r", '\r', $a_string);
 147        $a_string = str_replace("\t", '\t', $a_string);
 148    }
 149
 150    if ($php_code) {
 151        $a_string = str_replace('\'', '\\\'', $a_string);
 152    } else {
 153        $a_string = str_replace('\'', '\'\'', $a_string);
 154    }
 155
 156    return $a_string;
 157} // end of the 'PMA_sqlAddslashes()' function
 158
 159
 160/**
 161 * Add slashes before "_" and "%" characters for using them in MySQL
 162 * database, table and field names.
 163 * Note: This function does not escape backslashes!
 164 *
 165 * @uses    str_replace()
 166 * @param   string   the string to escape
 167 *
 168 * @return  string   the escaped string
 169 *
 170 * @access  public
 171 */
 172function PMA_escape_mysql_wildcards($name)
 173{
 174    $name = str_replace('_', '\\_', $name);
 175    $name = str_replace('%', '\\%', $name);
 176
 177    return $name;
 178} // end of the 'PMA_escape_mysql_wildcards()' function
 179
 180/**
 181 * removes slashes before "_" and "%" characters
 182 * Note: This function does not unescape backslashes!
 183 *
 184 * @uses    str_replace()
 185 * @param   string   $name  the string to escape
 186 * @return  string   the escaped string
 187 * @access  public
 188 */
 189function PMA_unescape_mysql_wildcards($name)
 190{
 191    $name = str_replace('\\_', '_', $name);
 192    $name = str_replace('\\%', '%', $name);
 193
 194    return $name;
 195} // end of the 'PMA_unescape_mysql_wildcards()' function
 196
 197/**
 198 * removes quotes (',",`) from a quoted string
 199 *
 200 * checks if the sting is quoted and removes this quotes
 201 *
 202 * @uses    str_replace()
 203 * @uses    substr()
 204 * @param   string  $quoted_string  string to remove quotes from
 205 * @param   string  $quote          type of quote to remove
 206 * @return  string  unqoted string
 207 */
 208function PMA_unQuote($quoted_string, $quote = null)
 209{
 210    $quotes = array();
 211
 212    if (null === $quote) {
 213        $quotes[] = '`';
 214        $quotes[] = '"';
 215        $quotes[] = "'";
 216    } else {
 217        $quotes[] = $quote;
 218    }
 219
 220    foreach ($quotes as $quote) {
 221        if (substr($quoted_string, 0, 1) === $quote
 222         && substr($quoted_string, -1, 1) === $quote) {
 223             $unquoted_string = substr($quoted_string, 1, -1);
 224             // replace escaped quotes
 225             $unquoted_string = str_replace($quote . $quote, $quote, $unquoted_string);
 226             return $unquoted_string;
 227         }
 228    }
 229
 230    return $quoted_string;
 231}
 232
 233/**
 234 * format sql strings
 235 *
 236 * @todo    move into PMA_Sql
 237 * @uses    PMA_SQP_isError()
 238 * @uses    PMA_SQP_formatHtml()
 239 * @uses    PMA_SQP_formatNone()
 240 * @uses    is_array()
 241 * @param   mixed    pre-parsed SQL structure
 242 *
 243 * @return  string   the formatted sql
 244 *
 245 * @global  array    the configuration array
 246 * @global  boolean  whether the current statement is a multiple one or not
 247 *
 248 * @access  public
 249 *
 250 * @author  Robin Johnson <robbat2@users.sourceforge.net>
 251 */
 252function PMA_formatSql($parsed_sql, $unparsed_sql = '')
 253{
 254    global $cfg;
 255
 256    // Check that we actually have a valid set of parsed data
 257    // well, not quite
 258    // first check for the SQL parser having hit an error
 259    if (PMA_SQP_isError()) {
 260        return $parsed_sql;
 261    }
 262    // then check for an array
 263    if (!is_array($parsed_sql)) {
 264        // We don't so just return the input directly
 265        // This is intended to be used for when the SQL Parser is turned off
 266        $formatted_sql = '<pre>' . "\n"
 267                        . (($cfg['SQP']['fmtType'] == 'none' && $unparsed_sql != '') ? $unparsed_sql : $parsed_sql) . "\n"
 268                        . '</pre>';
 269        return $formatted_sql;
 270    }
 271
 272    $formatted_sql        = '';
 273
 274    switch ($cfg['SQP']['fmtType']) {
 275        case 'none':
 276            if ($unparsed_sql != '') {
 277                $formatted_sql = "<pre>\n" . PMA_SQP_formatNone(array('raw' => $unparsed_sql)) . "\n</pre>";
 278            } else {
 279                $formatted_sql = PMA_SQP_formatNone($parsed_sql);
 280            }
 281            break;
 282        case 'html':
 283            $formatted_sql = PMA_SQP_formatHtml($parsed_sql, 'color');
 284            break;
 285        case 'text':
 286            //$formatted_sql = PMA_SQP_formatText($parsed_sql);
 287            $formatted_sql = PMA_SQP_formatHtml($parsed_sql, 'text');
 288            break;
 289        default:
 290            break;
 291    } // end switch
 292
 293    return $formatted_sql;
 294} // end of the "PMA_formatSql()" function
 295
 296
 297/**
 298 * Displays a link to the official MySQL documentation
 299 *
 300 * @uses    $cfg['MySQLManualType']
 301 * @uses    $cfg['MySQLManualBase']
 302 * @uses    $cfg['ReplaceHelpImg']
 303 * @uses    $GLOBALS['mysql_4_1_doc_lang']
 304 * @uses    $GLOBALS['mysql_5_1_doc_lang']
 305 * @uses    $GLOBALS['mysql_5_0_doc_lang']
 306 * @uses    $GLOBALS['strDocu']
 307 * @uses    $GLOBALS['pmaThemeImage']
 308 * @uses    PMA_MYSQL_INT_VERSION
 309 * @uses    strtolower()
 310 * @uses    str_replace()
 311 * @param string  chapter of "HTML, one page per chapter" documentation
 312 * @param string  contains name of page/anchor that is being linked
 313 * @param bool    whether to use big icon (like in left frame)
 314 *
 315 * @return  string  the html link
 316 *
 317 * @access  public
 318 */
 319function PMA_showMySQLDocu($chapter, $link, $big_icon = false)
 320{
 321    global $cfg;
 322
 323    if ($cfg['MySQLManualType'] == 'none' || empty($cfg['MySQLManualBase'])) {
 324        return '';
 325    }
 326
 327    // Fixup for newly used names:
 328    $chapter = str_replace('_', '-', strtolower($chapter));
 329    $link = str_replace('_', '-', strtolower($link));
 330
 331    switch ($cfg['MySQLManualType']) {
 332        case 'chapters':
 333            if (empty($chapter)) {
 334                $chapter = 'index';
 335            }
 336            $url = $cfg['MySQLManualBase'] . '/' . $chapter . '.html#' . $link;
 337            break;
 338        case 'big':
 339            $url = $cfg['MySQLManualBase'] . '#' . $link;
 340            break;
 341        case 'searchable':
 342            if (empty($link)) {
 343                $link = 'index';
 344            }
 345            $url = $cfg['MySQLManualBase'] . '/' . $link . '.html';
 346            break;
 347        case 'viewable':
 348        default:
 349            if (empty($link)) {
 350                $link = 'index';
 351            }
 352            $mysql = '5.0';
 353            $lang = 'en';
 354            if (defined('PMA_MYSQL_INT_VERSION')) {
 355                if (PMA_MYSQL_INT_VERSION < 50000) {
 356                    $mysql = '4.1';
 357                    if (!empty($GLOBALS['mysql_4_1_doc_lang'])) {
 358                        $lang = $GLOBALS['mysql_4_1_doc_lang'];
 359                    }
 360                } elseif (PMA_MYSQL_INT_VERSION >= 50100) {
 361                    $mysql = '5.1';
 362                    if (!empty($GLOBALS['mysql_5_1_doc_lang'])) {
 363                        $lang = $GLOBALS['mysql_5_1_doc_lang'];
 364                    }
 365                } elseif (PMA_MYSQL_INT_VERSION >= 50000) {
 366                    $mysql = '5.0';
 367                    if (!empty($GLOBALS['mysql_5_0_doc_lang'])) {
 368                        $lang = $GLOBALS['mysql_5_0_doc_lang'];
 369                    }
 370                }
 371            }
 372            $url = $cfg['MySQLManualBase'] . '/' . $mysql . '/' . $lang . '/' . $link . '.html';
 373            break;
 374    }
 375
 376    if ($big_icon) {
 377        return '<a href="' . $url . '" target="mysql_doc"><img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 'b_sqlhelp.png" width="16" height="16" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" /></a>';
 378    } elseif ($GLOBALS['cfg']['ReplaceHelpImg']) {
 379        return '<a href="' . $url . '" target="mysql_doc"><img class="icon" src="' . $GLOBALS['pmaThemeImage'] . 'b_help.png" width="11" height="11" alt="' . $GLOBALS['strDocu'] . '" title="' . $GLOBALS['strDocu'] . '" /></a>';
 380    } else {
 381        return '[<a href="' . $url . '" target="mysql_doc">' . $GLOBALS['strDocu'] . '</a>]';
 382    }
 383} // end of the 'PMA_showMySQLDocu()' function
 384
 385/**
 386 * Displays a hint icon, on mouse over show the hint
 387 *
 388 * @uses    $GLOBALS['pmaThemeImage']
 389 * @uses    PMA_jsFormat()
 390 * @param   string   the error message
 391 *
 392 * @access  public
 393 */
 394function PMA_showHint($hint_message)
 395{
 396    //return '<img class="lightbulb" src="' . $GLOBALS['pmaThemeImage'] . 'b_tipp.png" width="16" height="16" border="0" alt="' . $hint_message . '" title="' . $hint_message . '" align="middle" onclick="alert(\'' . PMA_jsFormat($hint_message, false) . '\');" />';
 397    return '<img class="lightbulb" src="' . $GLOBALS['pmaThemeImage']
 398        . 'b_tipp.png" width="16" height="16" alt="Tip" title="Tip" onmouseover="pmaTooltip(\''
 399        .  PMA_jsFormat($hint_message, false) . '\'); return false;" onmouseout="swapTooltip(\'default\'); return false;" />';
 400}
 401
 402/**
 403 * Displays a MySQL error message in the right frame.
 404 *
 405 * @uses    footer.inc.php
 406 * @uses    header.inc.php
 407 * @uses    $GLOBALS['sql_query']
 408 * @uses    $GLOBALS['strError']
 409 * @uses    $GLOBALS['strSQLQuery']
 410 * @uses    $GLOBALS['pmaThemeImage']
 411 * @uses    $GLOBALS['strEdit']
 412 * @uses    $GLOBALS['strMySQLSaid']
 413 * @uses    $GLOBALS['cfg']['PropertiesIconic'] 
 414 * @uses    $GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] 
 415 * @uses    PMA_backquote()
 416 * @uses    PMA_DBI_getError()
 417 * @uses    PMA_formatSql()
 418 * @uses    PMA_generate_common_hidden_inputs()
 419 * @uses    PMA_generate_common_url()
 420 * @uses    PMA_showMySQLDocu()
 421 * @uses    PMA_sqlAddslashes()
 422 * @uses    PMA_SQP_isError()
 423 * @uses    PMA_SQP_parse()
 424 * @uses    PMA_SQP_getErrorString()
 425 * @uses    strtolower()
 426 * @uses    urlencode()
 427 * @uses    str_replace()
 428 * @uses    nl2br()
 429 * @uses    substr()
 430 * @uses    preg_replace()
 431 * @uses    preg_match()
 432 * @uses    explode()
 433 * @uses    implode()
 434 * @uses    is_array()
 435 * @uses    function_exists()
 436 * @uses    htmlspecialchars()
 437 * @uses    trim()
 438 * @uses    strstr()
 439 * @param   string   the error message
 440 * @param   string   the sql query that failed
 441 * @param   boolean  whether to show a "modify" link or not
 442 * @param   string   the "back" link url (full path is not required)
 443 * @param   boolean  EXIT the page?
 444 *
 445 * @global  string    the curent table
 446 * @global  string    the current db
 447 *
 448 * @access  public
 449 */
 450function PMA_mysqlDie($error_message = '', $the_query = '',
 451                        $is_modify_link = true, $back_url = '', $exit = true)
 452{
 453    global $table, $db;
 454
 455    /**
 456     * start http output, display html headers
 457     */
 458    require_once './libraries/header.inc.php';
 459
 460    if (!$error_message) {
 461        $error_message = PMA_DBI_getError();
 462    }
 463    if (!$the_query && !empty($GLOBALS['sql_query'])) {
 464        $the_query = $GLOBALS['sql_query'];
 465    }
 466
 467    // --- Added to solve bug #641765
 468    // Robbat2 - 12 January 2003, 9:46PM
 469    // Revised, Robbat2 - 13 January 2003, 2:59PM
 470    if (!function_exists('PMA_SQP_isError') || PMA_SQP_isError()) {
 471        $formatted_sql = htmlspecialchars($the_query);
 472    } elseif (empty($the_query) || trim($the_query) == '') {
 473        $formatted_sql = '';
 474    } else {
 475        if (strlen($the_query) > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) {
 476            $formatted_sql = substr($the_query, 0, $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) . '[...]';
 477        } else {
 478            $formatted_sql = PMA_formatSql(PMA_SQP_parse($the_query), $the_query);
 479        }
 480    }
 481    // ---
 482    echo "\n" . '<!-- PMA-SQL-ERROR -->' . "\n";
 483    echo '    <div class="error"><h1>' . $GLOBALS['strError'] . '</h1>' . "\n";
 484    // if the config password is wrong, or the MySQL server does not
 485    // respond, do not show the query that would reveal the
 486    // username/password
 487    if (!empty($the_query) && !strstr($the_query, 'connect')) {
 488        // --- Added to solve bug #641765
 489        // Robbat2 - 12 January 2003, 9:46PM
 490        // Revised, Robbat2 - 13 January 2003, 2:59PM
 491        if (function_exists('PMA_SQP_isError') && PMA_SQP_isError()) {
 492            echo PMA_SQP_getErrorString() . "\n";
 493            echo '<br />' . "\n";
 494        }
 495        // ---
 496        // modified to show me the help on sql errors (Michael Keck)
 497        echo '    <p><strong>' . $GLOBALS['strSQLQuery'] . ':</strong>' . "\n";
 498        if (strstr(strtolower($formatted_sql), 'select')) { // please show me help to the error on select
 499            echo PMA_showMySQLDocu('SQL-Syntax', 'SELECT');
 500        }
 501        if ($is_modify_link && strlen($db)) {
 502            if (strlen($table)) {
 503                $doedit_goto = '<a href="tbl_sql.php?' . PMA_generate_common_url($db, $table) . '&amp;sql_query=' . urlencode($the_query) . '&amp;show_query=1">';
 504            } else {
 505                $doedit_goto = '<a href="db_sql.php?' . PMA_generate_common_url($db) . '&amp;sql_query=' . urlencode($the_query) . '&amp;show_query=1">';
 506            }
 507            if ($GLOBALS['cfg']['PropertiesIconic']) {
 508                echo $doedit_goto
 509                   . '<img class="icon" src=" '. $GLOBALS['pmaThemeImage'] . 'b_edit.png" width="16" height="16" alt="' . $GLOBALS['strEdit'] .'" />'
 510                   . '</a>';
 511            } else {
 512                echo '    ['
 513                   . $doedit_goto . $GLOBALS['strEdit'] . '</a>'
 514                   . ']' . "\n";
 515            }
 516        } // end if
 517        echo '    </p>' . "\n"
 518            .'    <p>' . "\n"
 519            .'        ' . $formatted_sql . "\n"
 520            .'    </p>' . "\n";
 521    } // end if
 522
 523    $tmp_mysql_error = ''; // for saving the original $error_message
 524    if (!empty($error_message)) {
 525        $tmp_mysql_error = strtolower($error_message); // save the original $error_message
 526        $error_message = htmlspecialchars($error_message);
 527        $error_message = preg_replace("@((\015\012)|(\015)|(\012)){3,}@", "\n\n", $error_message);
 528    }
 529    // modified to show me the help on error-returns (Michael Keck)
 530    // (now error-messages-server)
 531    echo '<p>' . "\n"
 532            . '    <strong>' . $GLOBALS['strMySQLSaid'] . '</strong>'
 533            . PMA_showMySQLDocu('Error-messages-server', 'Error-messages-server')
 534            . "\n"
 535            . '</p>' . "\n";
 536
 537    // The error message will be displayed within a CODE segment.
 538    // To preserve original formatting, but allow wordwrapping, we do a couple of replacements
 539
 540    // Replace all non-single blanks with their HTML-counterpart
 541    $error_message = str_replace('  ', '&nbsp;&nbsp;', $error_message);
 542    // Replace TAB-characters with their HTML-counterpart
 543    $error_message = str_replace("\t", '&nbsp;&nbsp;&nbsp;&nbsp;', $error_message);
 544    // Replace linebreaks
 545    $error_message = nl2br($error_message);
 546
 547    echo '<code>' . "\n"
 548        . $error_message . "\n"
 549        . '</code><br />' . "\n";
 550    echo '</div>';
 551    echo '<fieldset class="tblFooters">';
 552
 553    if (!empty($back_url) && $exit) {
 554        $goto_back_url='<a href="' . (strstr($back_url, '?') ? $back_url . '&amp;no_history=true' : $back_url . '?no_history=true') . '">';
 555        echo '[ ' . $goto_back_url . $GLOBALS['strBack'] . '</a> ]';
 556    }
 557    echo '    </fieldset>' . "\n\n";
 558    if ($exit) {
 559        /**
 560         * display footer and exit
 561         */
 562        require_once './libraries/footer.inc.php';
 563    }
 564} // end of the 'PMA_mysqlDie()' function
 565
 566/**
 567 * Returns a string formatted with CONVERT ... USING
 568 * if MySQL supports it
 569 *
 570 * @uses    PMA_MYSQL_INT_VERSION
 571 * @uses    $GLOBALS['collation_connection']
 572 * @uses    explode()
 573 * @param   string  the string itself
 574 * @param   string  the mode: quoted or unquoted (this one by default)
 575 *
 576 * @return  the formatted string
 577 *
 578 * @access  private
 579 */
 580function PMA_convert_using($string, $mode='unquoted', $force_utf8 = false)
 581{
 582    if ($mode == 'quoted') {
 583        $possible_quote = "'";
 584    } else {
 585        $possible_quote = "";
 586    }
 587
 588    if (PMA_MYSQL_INT_VERSION >= 40100) {
 589        if ($force_utf8) {
 590            $charset = 'utf8';
 591            $collate = ' COLLATE utf8_bin';
 592        } else {
 593            list($charset) = explode('_', $GLOBALS['collation_connection']);
 594            $collate = '';
 595        }
 596        $converted_string = "CONVERT(" . $possible_quote . $string . $possible_quote . " USING " . $charset . ")" . $collate;
 597    } else {
 598        $converted_string = $possible_quote . $string . $possible_quote;
 599    }
 600    return $converted_string;
 601} // end function
 602
 603/**
 604 * Send HTTP header, taking IIS limits into account (600 seems ok)
 605 *
 606 * @uses    PMA_IS_IIS
 607 * @uses    PMA_COMING_FROM_COOKIE_LOGIN
 608 * @uses    PMA_get_arg_separator()
 609 * @uses    SID
 610 * @uses    strlen()
 611 * @uses    strpos()
 612 * @uses    header()
 613 * @uses    session_write_close()
 614 * @uses    headers_sent()
 615 * @uses    function_exists()
 616 * @uses    debug_print_backtrace()
 617 * @uses    trigger_error()
 618 * @uses    defined()
 619 * @param   string   $uri the header to send
 620 * @return  boolean  always true
 621 */
 622function PMA_sendHeaderLocation($uri)
 623{
 624    if (PMA_IS_IIS && strlen($uri) > 600) {
 625
 626        echo '<html><head><title>- - -</title>' . "\n";
 627        echo '<meta http-equiv="expires" content="0">' . "\n";
 628        echo '<meta http-equiv="Pragma" content="no-cache">' . "\n";
 629        echo '<meta http-equiv="Cache-Control" content="no-cache">' . "\n";
 630        echo '<meta http-equiv="Refresh" content="0;url=' .$uri . '">' . "\n";
 631        echo '<script type="text/javascript">' . "\n";
 632        echo '//<![CDATA[' . "\n";
 633        echo 'setTimeout("window.location = unescape(\'"' . $uri . '"\')", 2000);' . "\n";
 634        echo '//]]>' . "\n";
 635        echo '</script>' . "\n";
 636        echo '</head>' . "\n";
 637        echo '<body>' . "\n";
 638        echo '<script type="text/javascript">' . "\n";
 639        echo '//<![CDATA[' . "\n";
 640        echo 'document.write(\'<p><a href="' . $uri . '">' . $GLOBALS['strGo'] . '</a></p>\');' . "\n";
 641        echo '//]]>' . "\n";
 642        echo '</script></body></html>' . "\n";
 643
 644    } else {
 645        if (SID) {
 646            if (strpos($uri, '?') === false) {
 647                header('Location: ' . $uri . '?' . SID);
 648            } else {
 649                $separator = PMA_get_arg_separator();
 650                header('Location: ' . $uri . $separator . SID);
 651            }
 652        } else {
 653            session_write_close();
 654            if (headers_sent()) {
 655                if (function_exists('debug_print_backtrace')) {
 656                    echo '<pre>';
 657                    debug_print_backtrace();
 658                    echo '</pre>';
 659                }
 660                trigger_error('PMA_sendHeaderLocation called when headers are already sent!', E_USER_ERROR);
 661            }
 662            // bug #1523784: IE6 does not like 'Refresh: 0', it
 663            // results in a blank page
 664            // but we need it when coming from the cookie login panel)
 665            if (PMA_IS_IIS && defined('PMA_COMING_FROM_COOKIE_LOGIN')) {
 666                header('Refresh: 0; ' . $uri);
 667            } else {
 668                header('Location: ' . $uri);
 669            }
 670        }
 671    }
 672}
 673
 674/**
 675 * returns array with tables of given db with extended information and grouped
 676 *
 677 * @uses    $cfg['LeftFrameTableSeparator']
 678 * @uses    $cfg['LeftFrameTableLevel']
 679 * @uses    $cfg['ShowTooltipAliasTB']
 680 * @uses    $cfg['NaturalOrder']
 681 * @uses    PMA_backquote()
 682 * @uses    count()
 683 * @uses    array_merge
 684 * @uses    uksort()
 685 * @uses    strstr()
 686 * @uses    explode()
 687 * @param   string  $db     name of db
 688 * @param   string  $tables name of tables
 689 * return   array   (recursive) grouped table list
 690 */
 691function PMA_getTableList($db, $tables = null, $limit_offset = 0, $limit_count = false)
 692{
 693    $sep = $GLOBALS['cfg']['LeftFrameTableSeparator'];
 694
 695    if (null === $tables) {
 696        $tables = PMA_DBI_get_tables_full($db, false, false, null, $limit_offset, $limit_count);
 697        if ($GLOBALS['cfg']['NaturalOrder']) {
 698            uksort($tables, 'strnatcasecmp');
 699        }
 700    }
 701
 702    if (count($tables) < 1) {
 703        return $tables;
 704    }
 705
 706    $default = array(
 707        'Name'      => '',
 708        'Rows'      => 0,
 709        'Comment'   => '',
 710        'disp_name' => '',
 711    );
 712
 713    $table_groups = array();
 714
 715    foreach ($tables as $table_name => $table) {
 716
 717        // check for correct row count
 718        if (null === $table['Rows']) {
 719            // Do not check exact row count here,
 720            // if row count is invalid possibly the table is defect
 721            // and this would break left frame;
 722            // but we can check row count if this is a view,
 723            // since PMA_Table::countRecords() returns a limited row count
 724            // in this case.
 725
 726            // set this because PMA_Table::countRecords() can use it
 727            $tbl_is_view = PMA_Table::isView($db, $table['Name']);
 728
 729            if ($tbl_is_view) {
 730                $table['Rows'] = PMA_Table::countRecords($db, $table['Name'],
 731                    $return = true);
 732            }
 733        }
 734
 735        // in $group we save the reference to the place in $table_groups
 736        // where to store the table info
 737        if ($GLOBALS['cfg']['LeftFrameDBTree']
 738            && $sep && strstr($table_name, $sep))
 739        {
 740            $parts = explode($sep, $table_name);
 741
 742            $group =& $table_groups;
 743            $i = 0;
 744            $group_name_full = '';
 745            while ($i < count($parts) - 1
 746              && $i < $GLOBALS['cfg']['LeftFrameTableLevel']) {
 747                $group_name = $parts[$i] . $sep;
 748                $group_name_full .= $group_name;
 749
 750                if (!isset($group[$group_name])) {
 751                    $group[$group_name] = array();
 752                    $group[$group_name]['is' . $sep . 'group'] = true;
 753                    $group[$group_name]['tab' . $sep . 'count'] = 1;
 754                    $group[$group_name]['tab' . $sep . 'group'] = $group_name_full;
 755                } elseif (!isset($group[$group_name]['is' . $sep . 'group'])) {
 756                    $table = $group[$group_name];
 757                    $group[$group_name] = array();
 758                    $group[$group_name][$group_name] = $table;
 759                    unset($table);
 760                    $group[$group_name]['is' . $sep . 'group'] = true;
 761                    $group[$group_name]['tab' . $sep . 'count'] = 1;
 762                    $group[$group_name]['tab' . $sep . 'group'] = $group_name_full;
 763                } else {
 764                    $group[$group_name]['tab' . $sep . 'count']++;
 765                }
 766                $group =& $group[$group_name];
 767                $i++;
 768            }
 769        } else {
 770            if (!isset($table_groups[$table_name])) {
 771                $table_groups[$table_name] = array();
 772            }
 773            $group =& $table_groups;
 774        }
 775
 776
 777        if ($GLOBALS['cfg']['ShowTooltipAliasTB']
 778          && $GLOBALS['cfg']['ShowTooltipAliasTB'] !== 'nested') {
 779            // switch tooltip and name
 780            $table['Comment'] = $table['Name'];
 781            $table['disp_name'] = $table['Comment'];
 782        } else {
 783            $table['disp_name'] = $table['Name'];
 784        }
 785
 786        $group[$table_name] = array_merge($default, $table);
 787    }
 788
 789    return $table_groups;
 790}
 791
 792/* ----------------------- Set of misc functions ----------------------- */
 793
 794
 795/**
 796 * Adds backquotes on both sides of a database, table or field name.
 797 * and escapes backquotes inside the name with another backquote
 798 *
 799 * example:
 800 * <code>
 801 * echo PMA_backquote('owner`s db'); // `owner``s db`
 802 *
 803 * </code>
 804 *
 805 * @uses    PMA_backquote()
 806 * @uses    is_array()
 807 * @uses    strlen()
 808 * @uses    str_replace()
 809 * @param   mixed    $a_name    the database, table or field name to "backquote"
 810 *                              or array of it
 811 * @param   boolean  $do_it     a flag to bypass this function (used by dump
 812 *                              functions)
 813 * @return  mixed    the "backquoted" database, table or field name if the
 814 *                   current MySQL release is >= 3.23.6, the original one
 815 *                   else
 816 * @access  public
 817 */
 818function PMA_backquote($a_name, $do_it = true)
 819{
 820    if (! $do_it) {
 821        return $a_name;
 822    }
 823
 824    if (is_array($a_name)) {
 825         $result = array();
 826         foreach ($a_name as $key => $val) {
 827             $result[$key] = PMA_backquote($val);
 828         }
 829         return $result;
 830    }
 831
 832    // '0' is also empty for php :-(
 833    if (strlen($a_name) && $a_name !== '*') {
 834        return '`' . str_replace('`', '``', $a_name) . '`';
 835    } else {
 836        return $a_name;
 837    }
 838} // end of the 'PMA_backquote()' function
 839
 840
 841/**
 842 * Defines the <CR><LF> value depending on the user OS.
 843 *
 844 * @uses    PMA_USR_OS
 845 * @return  string   the <CR><LF> value to use
 846 *
 847 * @access  public
 848 */
 849function PMA_whichCrlf()
 850{
 851    $the_crlf = "\n";
 852
 853    // The 'PMA_USR_OS' constant is defined in "./libraries/Config.class.php"
 854    // Win case
 855    if (PMA_USR_OS == 'Win') {
 856        $the_crlf = "\r\n";
 857    }
 858    // Others
 859    else {
 860        $the_crlf = "\n";
 861    }
 862
 863    return $the_crlf;
 864} // end of the 'PMA_whichCrlf()' function
 865
 866/**
 867 * Reloads navigation if needed.
 868 *
 869 * @uses    $GLOBALS['reload']
 870 * @uses    $GLOBALS['db']
 871 * @uses    PMA_generate_common_url()
 872 * @global  array  configuration
 873 *
 874 * @access  public
 875 */
 876function PMA_reloadNavigation()
 877{
 878    global $cfg;
 879
 880    // Reloads the navigation frame via JavaScript if required
 881    if (isset($GLOBALS['reload']) && $GLOBALS['reload']) {
 882        // one of the reasons for a reload is when a table is dropped
 883        // in this case, get rid of the table limit offset, otherwise
 884        // we have a problem when dropping a table on the last page
 885        // and the offset becomes greater than the total number of tables
 886        unset($_SESSION['userconf']['table_limit_offset']);
 887        echo "\n";
 888        $reload_url = './navigation.php?' . PMA_generate_common_url($GLOBALS['db'], '', '&');
 889        ?>
 890<script type="text/javascript">
 891//<![CDATA[
 892if (typeof(window.parent) != 'undefined'
 893    && typeof(window.parent.frame_navigation) != 'undefined') {
 894    window.parent.goTo('<?php echo $reload_url; ?>');
 895}
 896//]]>
 897</script>
 898        <?php
 899        unset($GLOBALS['reload']);
 900    }
 901}
 902
 903/**
 904 * displays the message and the query
 905 * usually the message is the result of the query executed
 906 *
 907 * @param   string  $message    the message to display
 908 * @param   string  $sql_query  the query to display
 909 * @global  array   the configuration array
 910 * @uses    $cfg
 911 * @access  public
 912 */
 913function PMA_showMessage($message, $sql_query = null)
 914{
 915    global $cfg;
 916    $query_too_big = false;
 917
 918    if (null === $sql_query) {
 919        if (! empty($GLOBALS['display_query'])) {
 920            $sql_query = $GLOBALS['display_query'];
 921        } elseif ($cfg['SQP']['fmtType'] == 'none' && ! empty($GLOBALS['unparsed_sql'])) {
 922            $sql_query = $GLOBALS['unparsed_sql'];
 923        } elseif (! empty($GLOBALS['sql_query'])) {
 924            $sql_query = $GLOBALS['sql_query'];
 925        } else {
 926            $sql_query = '';
 927        }
 928    }
 929
 930    // Corrects the tooltip text via JS if required
 931    // @todo this is REALLY the wrong place to do this - very unexpected here
 932    if (strlen($GLOBALS['table']) && $cfg['ShowTooltip']) {
 933        $result = PMA_DBI_try_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], true) . '\'');
 934        if ($result) {
 935            $tbl_status = PMA_DBI_fetch_assoc($result);
 936            $tooltip    = (empty($tbl_status['Comment']))
 937                        ? ''
 938                        : $tbl_status['Comment'] . ' ';
 939            $tooltip .= '(' . PMA_formatNumber($tbl_status['Rows'], 0) . ' ' . $GLOBALS['strRows'] . ')';
 940            PMA_DBI_free_result($result);
 941            $uni_tbl = PMA_jsFormat($GLOBALS['db'] . '.' . $GLOBALS['table'], false);
 942            echo "\n";
 943            echo '<script type="text/javascript">' . "\n";
 944            echo '//<![CDATA[' . "\n";
 945            echo "window.parent.updateTableTitle('" . $uni_tbl . "', '" . PMA_jsFormat($tooltip, false) . "');" . "\n";
 946            echo '//]]>' . "\n";
 947            echo '</script>' . "\n";
 948        } // end if
 949    } // end if ... elseif
 950
 951    // Checks if the table needs to be repaired after a TRUNCATE query.
 952    // @todo what about $GLOBALS['display_query']???
 953    // @todo this is REALLY the wrong place to do this - very unexpected here
 954    if (strlen($GLOBALS['table'])
 955     && $GLOBALS['sql_query'] == 'TRUNCATE TABLE ' . PMA_backquote($GLOBALS['table'])) {
 956        if (!isset($tbl_status)) {
 957            $result = @PMA_DBI_try_query('SHOW TABLE STATUS FROM ' . PMA_backquote($GLOBALS['db']) . ' LIKE \'' . PMA_sqlAddslashes($GLOBALS['table'], true) . '\'');
 958            if ($result) {
 959                $tbl_status = PMA_DBI_fetch_assoc($result);
 960                PMA_DBI_free_result($result);
 961            }
 962        }
 963        if (isset($tbl_status) && (int) $tbl_status['Index_length'] > 1024) {
 964            PMA_DBI_try_query('REPAIR TABLE ' . PMA_backquote($GLOBALS['table']));
 965        }
 966    }
 967    unset($tbl_status);
 968    echo '<br />' . "\n";
 969
 970    echo '<div align="' . $GLOBALS['cell_align_left'] . '">' . "\n";
 971    if (!empty($GLOBALS['show_error_header'])) {
 972        echo '<div class="error">' . "\n";
 973        echo '<h1>' . $GLOBALS['strError'] . '</h1>' . "\n";
 974    }
 975
 976    echo '<div class="notice">';
 977    echo PMA_sanitize($message);
 978    if (isset($GLOBALS['special_message'])) {
 979        echo PMA_sanitize($GLOBALS['special_message']);
 980        unset($GLOBALS['special_message']);
 981    }
 982    echo '</div>';
 983
 984    if (!empty($GLOBALS['show_error_header'])) {
 985        echo '</div>';
 986    }
 987
 988    if ($cfg['ShowSQL'] == true && ! empty($sql_query)) {
 989        // Basic url query part
 990        $url_qpart = '?' . PMA_generate_common_url($GLOBALS['db'], $GLOBALS['table']);
 991
 992        // Html format the query to be displayed
 993        // The nl2br function isn't used because its result isn't a valid
 994        // xhtml1.0 statement before php4.0.5 ("<br>" and not "<br />")
 995        // If we want to show some sql code it is easiest to create it here
 996         /* SQL-Parser-Analyzer */
 997
 998        if (!empty($GLOBALS['show_as_php'])) {
 999            $new_line = '\'<br />' . "\n" . '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;. \' ';
1000        }
1001        if (isset($new_line)) {
1002             /* SQL-Parser-Analyzer */
1003            $query_base = PMA_sqlAddslashes(htmlspecialchars($sql_query), false, false, true);
1004             /* SQL-Parser-Analyzer */
1005            $query_base = preg_replace("@((\015\012)|(\015)|(\012))+@", $new_line, $query_base);
1006        } else {
1007            $query_base = $sql_query;
1008        }
1009
1010        if (strlen($query_base) > $cfg['MaxCharactersInDisplayedSQL']) {
1011            $query_too_big = true; 
1012            $query_base = nl2br(htmlspecialchars($sql_query));
1013            unset($GLOBALS['parsed_sql']);
1014        }
1015
1016        // Parse SQL if needed
1017        // (here, use "! empty" because when deleting a bookmark,
1018        // $GLOBALS['parsed_sql'] is set but empty
1019        if (! empty($GLOBALS['parsed_sql']) && $query_base == $GLOBALS['parsed_sql']['raw']) {
1020            $parsed_sql = $GLOBALS['parsed_sql'];
1021        } else {
1022            // when the query is large (for example an INSERT of binary
1023            // data), the parser chokes; so avoid parsing the query
1024            if (! $query_too_big) {
1025                $parsed_sql = PMA_SQP_parse($query_base);
1026            }
1027        }
1028
1029        // Analyze it
1030        if (isset($parsed_sql)) {
1031            $analyzed_display_query = PMA_SQP_analyze($parsed_sql);
1032        }
1033
1034        // Here we append the LIMIT added for navigation, to
1035        // enable its display. Adding it higher in the code
1036        // to $sql_query would create a problem when
1037        // using the Refresh or Edit links.
1038
1039        // Only append it on SELECTs.
1040
1041        /**
1042         * @todo what would be the best to do when someone hits Refresh:
1043         * use the current LIMITs ?
1044         */
1045
1046        if (isset($analyzed_display_query[0]['queryflags']['select_from'])
1047         && isset($GLOBALS['sql_limit_to_append'])) {
1048            $query_base  = $analyzed_display_query[0]['section_before_limit'] . "\n" . $GLOBALS['sql_limit_to_append'] . $analyzed_display_query[0]['section_after_limit'];
1049            // Need to reparse query
1050            $parsed_sql = PMA_SQP_parse($query_base);
1051        }
1052
1053        if (!empty($GLOBALS['show_as_php'])) {
1054            $query_base = '$sql  = \'' . $query_base;
1055        } elseif (!empty($GLOBALS['validatequery'])) {
1056            $query_base = PMA_validateSQL($query_base);
1057        } else {
1058            if (isset($parsed_sql)) {
1059                $query_base = PMA_formatSql($parsed_sql, $query_base);
1060            }
1061        }
1062
1063        // Prepares links that may be displayed to edit/explain the query
1064        // (don't go to default pages, we must go to the page
1065        // where the query box is available)
1066
1067        $edit_target = strlen($GLOBALS['db']) ? (strlen($GLOBALS['table']) ? 'tbl_sql.php' : 'db_sql.php') : 'server_sql.php';
1068
1069        if (isset($cfg['SQLQuery']['Edit'])
1070            && ($cfg['SQLQuery']['Edit'] == true)
1071            && (!empty($edit_target))
1072            && ! $query_too_big) {
1073
1074            if ($cfg['EditInWindow'] == true) {
1075                $onclick = 'window.parent.focus_querywindow(\'' . PMA_jsFormat($sql_query, false) . '\'); return false;';
1076            } else {
1077                $onclick = '';
1078            }
1079
1080            $edit_link = $edit_target
1081                       . $url_qpart
1082                       . '&amp;sql_query=' . urlencode($sql_query)
1083                       . '&amp;show_query=1#querybox';
1084            $edit_link = ' [' . PMA_linkOrButton($edit_link, $GLOBALS['strEdit'], array('onclick' => $onclick)) . ']';
1085        } else {
1086            $edit_link = '';
1087        }
1088
1089        // Want to have the query explained (Mike Beck 2002-05-22)
1090        // but only explain a SELECT (that has not been explained)
1091        /* SQL-Parser-Analyzer */
1092        if (isset($cfg['SQLQuery']['Explain'])
1093            && $cfg['SQLQuery']['Explain'] == true
1094            && ! $query_too_big) {
1095
1096            // Detect if we are validating as well
1097            // To preserve the validate uRL data
1098            if (!empty($GLOBALS['validatequery'])) {
1099                $explain_link_validate = '&amp;validatequery=1';
1100            } else {
1101                $explain_link_validate = '';
1102            }
1103
1104            $explain_link = 'import.php'
1105                          . $url_qpart
1106                          . $explain_link_validate
1107                          . '&amp;sql_query=';
1108
1109            if (preg_match('@^SELECT[[:space:]]+@i', $sql_query)) {
1110                $explain_link .= urlencode('EXPLAIN ' . $sql_query);
1111                $message = $GLOBALS['strExplain'];
1112            } elseif (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $sql_query)) {
1113                $explain_link .= urlencode(substr($sql_query, 8));
1114                $message = $GLOBALS['strNoExplain'];
1115            } else {
1116                $explain_link = '';
1117            }
1118            if (!empty($explain_link)) {
1119                $explain_link = ' [' . PMA_linkOrButton($explain_link, $message) . ']';
1120            }
1121        } else {
1122            $explain_link = '';
1123        } //show explain
1124
1125        // Also we would like to get the SQL formed in some nice
1126        // php-code (Mike Beck 2002-05-22)
1127        if (isset($cfg['SQLQuery']['ShowAsPHP'])
1128            && $cfg['SQLQuery']['ShowAsPHP'] == true
1129            && ! $query_too_big) {
1130            $php_link = 'import.php'
1131                      . $url_qpart
1132                      . '&amp;show_query=1'
1133                      . '&amp;sql_query=' . urlencode($sql_query)
1134                      . '&amp;show_as_php=';
1135
1136            if (!empty($GLOBALS['show_as_php'])) {
1137                $php_link .= '0';
1138                $message = $GLOBALS['strNoPhp'];
1139            } else {
1140                $php_link .= '1';
1141                $message = $GLOBALS['strPhp'];
1142            }
1143            $php_link = ' [' . PMA_linkOrButton($php_link, $message) . ']';
1144
1145            if (isset($GLOBALS['show_as_php'])) {
1146                $runquery_link
1147                     = 'import.php'
1148                     . $url_qpart
1149                     . '&amp;show_query=1'
1150                     . '&amp;sql_query=' . urlencode($sql_query);
1151                $php_link .= ' [' . PMA_linkOrButton($runquery_link, $GLOBALS['strRunQuery']) . ']';
1152            }
1153
1154        } else {
1155            $php_link = '';
1156        } //show as php
1157
1158        // Refresh query
1159        if (isset($cfg['SQLQuery']['Refresh'])
1160            && $cfg['SQLQuery']['Refresh']
1161            && preg_match('@^(SELECT|SHOW)[[:space:]]+@i', $sql_query)) {
1162
1163            $refresh_link = 'import.php'
1164                      . $url_qpart
1165                      . '&amp;show_query=1'
1166                      . '&amp;sql_query=' . urlencode($sql_query);
1167            $refresh_link = ' [' . PMA_linkOrButton($refresh_link, $GLOBALS['strRefresh']) . ']';
1168        } else {
1169            $refresh_link = '';
1170        } //show as php
1171
1172        if (isset($cfg['SQLValidator']['use'])
1173            && $cfg['SQLValidator']['use'] == true
1174            && isset($cfg['SQLQuery']['Validate'])
1175            && $cfg['SQLQuery']['Validate'] == true) {
1176            $validate_link = 'import.php'
1177                           . $url_qpart
1178                           . '&amp;show_query=1'
1179                           . '&amp;sql_query=' . urlencode($sql_query)
1180                           . '&amp;validatequery=';
1181            if (!empty($GLOBALS['validatequery'])) {
1182                $validate_link .= '0';
1183                $validate_message = $GLOBALS['strNoValidateSQL'] ;
1184            } else {
1185                $validate_link .= '1';
1186                $validate_message = $GLOBALS['strValidateSQL'] ;
1187            }
1188            $validate_link = ' [' . PMA_linkOrButton($validate_link, $validate_message) . ']';
1189        } else {
1190            $validate_link = '';
1191        } //validator
1192
1193        // why this?
1194        //unset($sql_query);
1195
1196        // Displays the message
1197        echo '<fieldset class="">' . "\n";
1198        echo '    <legend>' . $GLOBALS['strSQLQuery'] . ':</legend>';
1199        echo '    <div>';
1200        // when uploading a 700 Kio binary file into a LONGBLOB,
1201        // I get a white page, strlen($query_base) is 2 x 700 Kio
1202        // so put a hard limit here (let's say 1000)
1203        if ($query_too_big) {
1204            echo '    ' . substr($query_base, 0, $cfg['MaxCharactersInDisplayedSQL']) . '[...]';
1205        } else {
1206            echo '    ' . $query_base;
1207        }
1208
1209        //Clean up the end of the PHP
1210        if (!empty($GLOBALS['show_as_php'])) {
1211            echo '\';';
1212        }
1213        echo '    </div>';
1214        echo '</fieldset>' . "\n";
1215
1216        if (!empty($edit_target)) {
1217            echo '<fieldset class="tblFooters">';
1218            // avoid displaying a Profiling checkbox that could
1219            // be checked, which would reexecute an INSERT, for example
1220            if (! empty($refresh_link)) {
1221                PMA_profilingCheckbox($sql_query);
1222            }
1223            echo $edit_link . $explain_link . $php_link . $refresh_link . $validate_link;
1224            echo '</fieldset>';
1225        }
1226    }
1227    echo '</div><br />' . "\n";
1228} // end of the 'PMA_showMessage()' function
1229
1230
1231/**
1232 * Verifies if current MySQL server supports profiling 
1233 *
1234 * @access  public
1235 * @return  boolean whether profiling is supported 
1236 *
1237 * @author   Marc Delisle 
1238 */
1239function PMA_profilingSupported() {
1240    // 5.0.37 has profiling but for example, 5.1.20 does not
1241    // (avoid a trip to the server for MySQL before 5.0.37)
1242    // and do not set a constant as we might be switching servers
1243    if (defined('PMA_MYSQL_INT_VERSION') && PMA_MYSQL_INT_VERSION >= 50037 && PMA_DBI_fetch_value("SHOW VARIABLES LIKE 'profiling'")) {
1244        return true;
1245    } else {
1246        return false;
1247    }
1248}
1249
1250/**
1251 * Displays a form with the Profiling checkbox 
1252 *
1253 * @param   string  $sql_query
1254 * @access  public
1255 *
1256 * @author   Marc Delisle 
1257 */
1258function PMA_profilingCheckbox($sql_query) {
1259    if (PMA_profilingSupported()) {
1260        echo '<form action="sql.php" method="post">' . "\n";
1261        echo PMA_generate_common_hidden_inputs($GLOBALS['db'], $GLOBALS['table']);
1262        echo '<input type="hidden" name="sql_query" value="' . htmlspecialchars($sql_query) . '" />' . "\n";
1263        echo '<input type="hidden" name="profiling_form" value="1" />' . "\n";
1264        echo '<input type="checkbox" name="profiling" id="profiling"' . (isset($_SESSION['profiling']) ? ' checked="checked"' : '') . ' onclick="this.form.submit();" /><label for="profiling">' . $GLOBALS['strProfiling'] . '</label>' . "\n";
1265        echo '<noscript><input type="submit" value="' . $GLOBALS['strGo'] . '" /></noscript>' . "\n";
1266        echo '</form>' . "\n";
1267    }
1268}
1269
1270/**
1271 * Displays the results of SHOW PROFILE 
1272 *
1273 * @param    array   the results 
1274 * @access  public
1275 *
1276 * @author   Marc Delisle 
1277 */
1278function PMA_profilingResults($profiling_results) {
1279    echo '<fieldset><legend>' . $GLOBALS['strProfiling'] . '</legend>' . "\n";
1280    echo '<table>' . "\n";
1281    echo ' <tr>' .  "\n";
1282    echo '  <th>' . $GLOBALS['strStatus'] . '</th>' . "\n";
1283    echo '  <th>' . $GLOBALS['strTime'] . '</th>' . "\n";
1284    echo ' </tr>' .  "\n";
1285
1286    foreach($profiling_results as $one_result) {
1287        echo ' <tr>' .  "\n";
1288        echo '<td>' . $one_result['Status'] . '</td>' .  "\n";
1289        echo '<td>' . $one_result['Duration'] . '</td>' .  "\n";
1290    }
1291    echo '</table>' . "\n";
1292    echo '</fieldset>' . "\n";
1293}
1294
1295/**
1296 * Formats $value to byte view
1297 *
1298 * @param    double   the value to format
1299 * @param    integer  the sensitiveness
1300 * @param    integer  the number of decimals to retain
1301 *
1302 * @return   array    the formatted value and its unit
1303 *
1304 * @access  public
1305 *
1306 * @author   staybyte
1307 * @version  1.2 - 18 July 2002
1308 */
1309function PMA_formatByteDown($value, $limes = 6, $comma = 0)
1310{
1311    $dh           = PMA_pow(10, $comma);
1312    $li           = PMA_pow(10, $limes);
1313    $return_value = $value;
1314    $unit         = $GLOBALS['byteUnits'][0];
1315
1316    for ($d = 6, $ex = 15; $d >= 1; $d--, $ex-=3) {
1317        if (isset($GLOBALS['byteUnits'][$d]) && $value >= $li * PMA_pow(10, $ex)) {
1318            // use 1024.0 to avoid integer overflow on 64-bit machines
1319            $value = round($value / (PMA_pow(1024, $d) / $dh)) /$dh;
1320            $unit = $GLOBALS['byteUnits'][$d];
1321            break 1;
1322        } // end if
1323    } // end for
1324
1325    if ($unit != $GLOBALS['byteUnits'][0]) {
1326        // if the unit is not bytes (as represented in current language)
1327        // reformat with max length of 5
1328        // 4th parameter=true means do not reformat if value < 1
1329        $return_value = PMA_formatNumber($value, 5, $comma, true);
1330    } else {
1331        // do not reformat, just handle the locale
1332        $return_value = PMA_formatNumber($value, 0);
1333    }
1334
1335    return array($return_value, $unit);
1336} // end of the 'PMA_formatByteDown' function
1337
1338/**
1339 * Formats $value to the given length and appends SI prefixes
1340 * $comma is not substracted from the length
1341 * with a $length of 0 no truncation occurs, number is only formated
1342 * to the current locale
1343 *
1344 * examples:
1345 * <code>
1346 * echo PMA_formatNumber(123456789, 6);     // 123,457 k
1347 * echo PMA_formatNumber(-123456789, 4, 2); //    -123.46 M
1348 * echo PMA_formatNumber(-0.003, 6);        //      -3 m
1349 * echo PMA_formatNumber(0.003, 3, 3);      //       0.003
1350 * echo PMA_formatNumber(0.00003, 3, 2);    //       0.03 m
1351 * echo PMA_formatNumber(0, 6);             //       0
1352 *
1353 * </code>
1354 * @param   double   $value     the value to format
1355 * @param   integer  $length    the max length
1356 * @param   integer  $comma     the number of decimals to retain
1357 * @param   boolean  $only_down do not reformat numbers below 1
1358 *
1359 * @return  string   the formatted value and its unit
1360 *
1361 * @access  public
1362 *
1363 * @author  staybyte, sebastian mendel
1364 * @version 1.1.0 - 2005-10-27
1365 */
1366function PMA_formatNumber($value, $length = 3, $comma = 0, $only_down = false)
1367{
1368    //number_format is not multibyte safe, str_replace is safe
1369    if ($length === 0) {
1370        return str_replace(array(',', '.'),
1371                array($GLOBALS['number_thousands_separator'], $GLOBALS['number_decimal_separator']),
1372                number_format($value, $comma));
1373    }
1374
1375    // this units needs no translation, ISO
1376    $units = array(
1377        -8 => 'y',
1378        -7 => 'z',
1379        -6 => 'a',
1380        -5 => 'f',
1381        -4 => 'p',
1382        -3 => 'n',
1383        -2 => '&micro;',
1384        -1 => 'm',
1385        0 => ' ',
1386        1 => 'k',
1387        2 => 'M',
1388        3 => 'G',
1389        4 => 'T',
1390        5 => 'P',
1391        6 => 'E',
1392        7 => 'Z',
1393        8 => 'Y'
1394    );
1395
1396    // we need at least 3 digits to be displayed
1397    if (3 > $length + $comma) {
1398        $length = 3 - $comma;
1399    }
1400
1401    // check for negative value to retain sign
1402    if ($value < 0) {
1403        $sign = '-';
1404        $value = abs($value);
1405    } else {
1406        $sign = '';
1407    }
1408
1409    $dh = PMA_pow(10, $comma);
1410    $li = PMA_pow(10, $length);
1411    $unit = $units[0];
1412
1413    if ($value >= 1) {
1414        for ($d = 8; $d >= 0; $d--) {
1415            if (isset($units[$d]) && $value >= $li * PMA_pow(1000, $d-1)) {
1416                $value = round($value / (PMA_pow(1000, $d) / $dh)) /$dh;
1417                $unit = $units[$d];
1418                break 1;
1419            } // end if
1420        } // end for
1421    } elseif (!$only_down && (float) $value !== 0.0) {
1422        for ($d = -8; $d <= 8; $d++) {
1423            if (isset($units[$d]) && $value <= $li * PMA_pow(1000, $d-1)) {
1424                $value = round($value / (PMA_pow(1000, $d) / $dh)) /$dh;
1425                $unit = $units[$d];
1426                break 1;
1427            } // end if
1428        } // end for
1429    } // end if ($value >= 1) elseif (!$only_down && (float) $value !== 0.0)
1430
1431    //number_format is not multibyte safe, str_replace is safe
1432    $value = str_replace(array(',', '.'),
1433                         array($GLOBALS['number_thousands_separator'], $GLOBALS['number_decimal_separator']),
1434                         number_format($value, $comma));
1435
1436    return $sign . $value . ' ' . $unit;
1437} // end of the 'PMA_formatNumber' function
1438
1439/**
1440 * Extracts ENUM / SET options from a type definition string
1441 *
1442 * @param   string   The column type definition
1443 *
1444 * @return  array    The options or
1445 *          boolean  false in case of an error.
1446 *
1447 * @author  rabus
1448 */
1449function PMA_getEnumSetOptions($type_def)
1450{
1451    $open = strpos($type_def, '(');
1452    $close = strrpos($type_def, ')');
1453    if (!$open || !$close) {
1454        return false;
1455    }
1456    $options = substr($type_def, $open + 2, $close - $open - 3);
1457    $options = explode('\',\'', $options);
1458   

Large files files are truncated, but you can click here to view the full file