PageRenderTime 61ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/pma/libraries/common.lib.php

https://bitbucket.org/StasPiv/playzone
PHP | 2690 lines | 1566 code | 234 blank | 890 comment | 382 complexity | 89c9f783e6f1689a9126f9e4a72794d5 MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, GPL-2.0, LGPL-2.1

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

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