/** * Get HTML snippet for display user overview page * * @param string $pmaThemeImage a image source link * @param string $text_dir text directory * * @return string $html_output */ function PMA_getHtmlForUserOverview($pmaThemeImage, $text_dir) { $html_output = '<h2>' . "\n" . Util::getIcon('b_usrlist.png') . __('User accounts overview') . "\n" . '</h2>' . "\n"; $password_column = 'Password'; if (Util::getServerType() == 'MySQL' && PMA_MYSQL_INT_VERSION >= 50706) { $password_column = 'authentication_string'; } // $sql_query is for the initial-filtered, // $sql_query_all is for counting the total no. of users $sql_query = $sql_query_all = 'SELECT *,' . " IF(`" . $password_column . "` = _latin1 '', 'N', 'Y') AS 'Password'" . ' FROM `mysql`.`user`'; $sql_query .= isset($_REQUEST['initial']) ? PMA_rangeOfUsers($_REQUEST['initial']) : ''; $sql_query .= ' ORDER BY `User` ASC, `Host` ASC;'; $sql_query_all .= ' ;'; $res = $GLOBALS['dbi']->tryQuery($sql_query, null, PMA\libraries\DatabaseInterface::QUERY_STORE); $res_all = $GLOBALS['dbi']->tryQuery($sql_query_all, null, PMA\libraries\DatabaseInterface::QUERY_STORE); if (!$res) { // the query failed! This may have two reasons: // - the user does not have enough privileges // - the privilege tables use a structure of an earlier version. // so let's try a more simple query $GLOBALS['dbi']->freeResult($res); $GLOBALS['dbi']->freeResult($res_all); $sql_query = 'SELECT * FROM `mysql`.`user`'; $res = $GLOBALS['dbi']->tryQuery($sql_query, null, PMA\libraries\DatabaseInterface::QUERY_STORE); if (!$res) { $html_output .= PMA_getHtmlForViewUsersError(); $html_output .= PMA_getAddUserHtmlFieldset(); } else { // This message is hardcoded because I will replace it by // a automatic repair feature soon. $raw = 'Your privilege table structure seems to be older than' . ' this MySQL version!<br />' . 'Please run the <code>mysql_upgrade</code> command' . '(<code>mysql_fix_privilege_tables</code> on older systems)' . ' that should be included in your MySQL server distribution' . ' to solve this problem!'; $html_output .= Message::rawError($raw)->getDisplay(); } $GLOBALS['dbi']->freeResult($res); } else { $db_rights = PMA_getDbRightsForUserOverview(); // for all initials, even non A-Z $array_initials = array(); foreach ($db_rights as $right) { foreach ($right as $account) { if (empty($account['User']) && $account['Host'] == 'localhost') { $html_output .= Message::notice(__('A user account allowing any user from localhost to ' . 'connect is present. This will prevent other users ' . 'from connecting if the host part of their account ' . 'allows a connection from any (%) host.') . Util::showMySQLDocu('problems-connecting'))->getDisplay(); break 2; } } } /** * Displays the initials * Also not necessary if there is less than 20 privileges */ if ($GLOBALS['dbi']->numRows($res_all) > 20) { $html_output .= PMA_getHtmlForInitials($array_initials); } /** * Display the user overview * (if less than 50 users, display them immediately) */ if (isset($_REQUEST['initial']) || isset($_REQUEST['showall']) || $GLOBALS['dbi']->numRows($res) < 50) { $html_output .= PMA_getUsersOverview($res, $db_rights, $pmaThemeImage, $text_dir); } else { $html_output .= PMA_getAddUserHtmlFieldset(); } // end if (display overview) if (!$GLOBALS['is_ajax_request'] || !empty($_REQUEST['ajax_page_request'])) { if (isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv']) { $flushnote = new Message(__('Note: phpMyAdmin gets the users\' privileges directly ' . 'from MySQL\'s privilege tables. The content of these ' . 'tables may differ from the privileges the server uses, ' . 'if they have been changed manually. In this case, ' . 'you should %sreload the privileges%s before you continue.'), Message::NOTICE); $flushLink = '<a href="server_privileges.php' . PMA_URL_getCommon(array('flush_privileges' => 1)) . '" id="reload_privileges_anchor">'; $flushnote->addParam($flushLink, false); $flushnote->addParam('</a>', false); } else { $flushnote = new Message(__('Note: phpMyAdmin gets the users\' privileges directly ' . 'from MySQL\'s privilege tables. The content of these ' . 'tables may differ from the privileges the server uses, ' . 'if they have been changed manually. In this case, ' . 'the privileges have to be reloaded but currently, you ' . 'don\'t have the RELOAD privilege.') . Util::showMySQLDocu('privileges-provided', false, 'priv_reload'), Message::NOTICE); } $html_output .= $flushnote->getDisplay(); } } return $html_output; }
/** * Prepare the message and the query * usually the message is the result of the query executed * * @param Message|string $message the message to display * @param string $sql_query the query to display * @param string $type the type (level) of the message * * @return string * * @access public */ public static function getMessage( $message, $sql_query = null, $type = 'notice' ) { global $cfg; $retval = ''; if (null === $sql_query) { if (! empty($GLOBALS['display_query'])) { $sql_query = $GLOBALS['display_query']; } elseif (! empty($GLOBALS['unparsed_sql'])) { $sql_query = $GLOBALS['unparsed_sql']; } elseif (! empty($GLOBALS['sql_query'])) { $sql_query = $GLOBALS['sql_query']; } else { $sql_query = ''; } } $render_sql = $cfg['ShowSQL'] == true && ! empty($sql_query) && $sql_query !== ';'; if (isset($GLOBALS['using_bookmark_message'])) { $retval .= $GLOBALS['using_bookmark_message']->getDisplay(); unset($GLOBALS['using_bookmark_message']); } if ($render_sql) { $retval .= '<div class="result_query"' . ' style="text-align: ' . $GLOBALS['cell_align_left'] . '"' . '>' . "\n"; } if ($message instanceof Message) { if (isset($GLOBALS['special_message'])) { $message->addText($GLOBALS['special_message']); unset($GLOBALS['special_message']); } $retval .= $message->getDisplay(); } else { $retval .= '<div class="' . $type . '">'; $retval .= Sanitize::sanitize($message); if (isset($GLOBALS['special_message'])) { $retval .= Sanitize::sanitize($GLOBALS['special_message']); unset($GLOBALS['special_message']); } $retval .= '</div>'; } if ($render_sql) { $query_too_big = false; $queryLength = mb_strlen($sql_query); if ($queryLength > $cfg['MaxCharactersInDisplayedSQL']) { // when the query is large (for example an INSERT of binary // data), the parser chokes; so avoid parsing the query $query_too_big = true; $query_base = mb_substr( $sql_query, 0, $cfg['MaxCharactersInDisplayedSQL'] ) . '[...]'; } else { $query_base = $sql_query; } // Html format the query to be displayed // If we want to show some sql code it is easiest to create it here /* SQL-Parser-Analyzer */ if (! empty($GLOBALS['show_as_php'])) { $new_line = '\\n"<br />' . "\n" . ' . "'; $query_base = '$sql = \'' . $query_base; $query_base = '<code class="php"><pre>' . "\n" . htmlspecialchars(addslashes($query_base)); $query_base = preg_replace( '/((\015\012)|(\015)|(\012))/', $new_line, $query_base ); $query_base = '$sql = \'' . $query_base . '"'; } elseif ($query_too_big) { $query_base = htmlspecialchars($query_base); } else { $query_base = self::formatSql($query_base); } // Prepares links that may be displayed to edit/explain the query // (don't go to default pages, we must go to the page // where the query box is available) // Basic url query part $url_params = array(); if (! isset($GLOBALS['db'])) { $GLOBALS['db'] = ''; } if (strlen($GLOBALS['db']) > 0) { $url_params['db'] = $GLOBALS['db']; if (strlen($GLOBALS['table']) > 0) { $url_params['table'] = $GLOBALS['table']; $edit_link = 'tbl_sql.php'; } else { $edit_link = 'db_sql.php'; } } else { $edit_link = 'server_sql.php'; } // Want to have the query explained // but only explain a SELECT (that has not been explained) /* SQL-Parser-Analyzer */ $explain_link = ''; $is_select = preg_match('@^SELECT[[:space:]]+@i', $sql_query); if (! empty($cfg['SQLQuery']['Explain']) && ! $query_too_big) { $explain_params = $url_params; if ($is_select) { $explain_params['sql_query'] = 'EXPLAIN ' . $sql_query; $explain_link = ' [' . self::linkOrButton( 'import.php' . URL::getCommon($explain_params), __('Explain SQL') ) . ']'; } elseif (preg_match( '@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $sql_query )) { $explain_params['sql_query'] = mb_substr($sql_query, 8); $explain_link = ' [' . self::linkOrButton( 'import.php' . URL::getCommon($explain_params), __('Skip Explain SQL') ) . ']'; $url = 'https://mariadb.org/explain_analyzer/analyze/' . '?client=phpMyAdmin&raw_explain=' . urlencode(self::_generateRowQueryOutput($sql_query)); $explain_link .= ' [' . self::linkOrButton( htmlspecialchars('url.php?url=' . urlencode($url)), sprintf(__('Analyze Explain at %s'), 'mariadb.org'), array(), true, false, '_blank' ) . ']'; } } //show explain $url_params['sql_query'] = $sql_query; $url_params['show_query'] = 1; // even if the query is big and was truncated, offer the chance // to edit it (unless it's enormous, see linkOrButton() ) if (! empty($cfg['SQLQuery']['Edit']) && empty($GLOBALS['show_as_php']) ) { $edit_link .= URL::getCommon($url_params) . '#querybox'; $edit_link = ' [' . self::linkOrButton($edit_link, __('Edit')) . ']'; } else { $edit_link = ''; } // Also we would like to get the SQL formed in some nice // php-code if (! empty($cfg['SQLQuery']['ShowAsPHP']) && ! $query_too_big) { if (! empty($GLOBALS['show_as_php'])) { $php_link = ' [' . self::linkOrButton( 'import.php' . URL::getCommon($url_params), __('Without PHP code'), array(), true, false, '', true ) . ']'; $php_link .= ' [' . self::linkOrButton( 'import.php' . URL::getCommon($url_params), __('Submit query'), array(), true, false, '', true ) . ']'; } else { $php_params = $url_params; $php_params['show_as_php'] = 1; $_message = __('Create PHP code'); $php_link = ' [' . self::linkOrButton( 'import.php' . URL::getCommon($php_params), $_message ) . ']'; } } else { $php_link = ''; } //show as php // Refresh query if (! empty($cfg['SQLQuery']['Refresh']) && ! isset($GLOBALS['show_as_php']) // 'Submit query' does the same && preg_match('@^(SELECT|SHOW)[[:space:]]+@i', $sql_query) ) { $refresh_link = 'import.php' . URL::getCommon($url_params); $refresh_link = ' [' . self::linkOrButton($refresh_link, __('Refresh')) . ']'; } else { $refresh_link = ''; } //refresh $retval .= '<div class="sqlOuter">'; $retval .= $query_base; //Clean up the end of the PHP if (! empty($GLOBALS['show_as_php'])) { $retval .= '\';' . "\n" . '</pre></code>'; } $retval .= '</div>'; $retval .= '<div class="tools print_ignore">'; $retval .= '<form action="sql.php" method="post">'; $retval .= URL::getHiddenInputs($GLOBALS['db'], $GLOBALS['table']); $retval .= '<input type="hidden" name="sql_query" value="' . htmlspecialchars($sql_query) . '" />'; // avoid displaying a Profiling checkbox that could // be checked, which would reexecute an INSERT, for example if (! empty($refresh_link) && self::profilingSupported()) { $retval .= '<input type="hidden" name="profiling_form" value="1" />'; $retval .= Template::get('checkbox') ->render( array( 'html_field_name' => 'profiling', 'label' => __('Profiling'), 'checked' => isset($_SESSION['profiling']), 'onclick' => true, 'html_field_id' => '', ) ); } $retval .= '</form>'; /** * TODO: Should we have $cfg['SQLQuery']['InlineEdit']? */ if (! empty($cfg['SQLQuery']['Edit']) && ! $query_too_big && empty($GLOBALS['show_as_php']) ) { $inline_edit_link = ' [' . self::linkOrButton( '#', _pgettext('Inline edit query', 'Edit inline'), array('class' => 'inline_edit_sql') ) . ']'; } else { $inline_edit_link = ''; } $retval .= $inline_edit_link . $edit_link . $explain_link . $php_link . $refresh_link; $retval .= '</div>'; $retval .= '</div>'; } return $retval; } // end of the 'getMessage()' function
/** * Function to get html for the sql query results div * * @param string $previous_update_query_html html for the previously executed query * @param string $profiling_chart_html html for profiling * @param Message $missing_unique_column_msg message for the missing unique column * @param Message $bookmark_created_msg message for bookmark creation * @param string $table_html html for the table for displaying sql * results * @param string $indexes_problems_html html for displaying errors in indexes * @param string $bookmark_support_html html for displaying bookmark form * * @return string $html_output */ function PMA_getHtmlForSqlQueryResults($previous_update_query_html, $profiling_chart_html, $missing_unique_column_msg, $bookmark_created_msg, $table_html, $indexes_problems_html, $bookmark_support_html) { //begin the sqlqueryresults div here. container div $html_output = '<div class="sqlqueryresults ajax">'; $html_output .= isset($previous_update_query_html) ? $previous_update_query_html : ''; $html_output .= isset($profiling_chart_html) ? $profiling_chart_html : ''; $html_output .= isset($missing_unique_column_msg) ? $missing_unique_column_msg->getDisplay() : ''; $html_output .= isset($bookmark_created_msg) ? $bookmark_created_msg->getDisplay() : ''; $html_output .= $table_html; $html_output .= isset($indexes_problems_html) ? $indexes_problems_html : ''; $html_output .= isset($bookmark_support_html) ? $bookmark_support_html : ''; $html_output .= '</div>'; // end sqlqueryresults div return $html_output; }
/** * Stops the import on (mostly upload/file related) error * * @param PMA\libraries\Message $error_message The error message * * @return void * @access public * */ function PMA_stopImport(Message $error_message) { global $import_handle, $file_to_unlink; // Close open handles if ($import_handle !== false && $import_handle !== null) { fclose($import_handle); } // Delete temporary file if ($file_to_unlink != '') { unlink($file_to_unlink); } $msg = $error_message->getDisplay(); $_SESSION['Import_message']['message'] = $msg; $response = PMA\libraries\Response::getInstance(); $response->setRequestStatus(false); $response->addJSON('message', PMA\libraries\Message::error($msg)); exit; }