' . "\n";
}
if ($message instanceof Message) {
if (isset($GLOBALS['special_message'])) {
$message->addText($GLOBALS['special_message']);
unset($GLOBALS['special_message']);
}
$retval .= $message->getDisplay();
} else {
$context = 'primary';
if ($type === 'error') {
$context = 'danger';
} elseif ($type === 'success') {
$context = 'success';
}
$retval .= '
';
$retval .= Sanitize::sanitizeMessage($message);
if (isset($GLOBALS['special_message'])) {
$retval .= Sanitize::sanitizeMessage($GLOBALS['special_message']);
unset($GLOBALS['special_message']);
}
$retval .= '
';
}
if ($renderSql) {
$queryTooBig = false;
$queryLength = mb_strlen($sqlQuery);
if ($queryLength > $cfg['MaxCharactersInDisplayedSQL']) {
// when the query is large (for example an INSERT of binary
// data), the parser chokes; so avoid parsing the query
$queryTooBig = true;
$queryBase = mb_substr($sqlQuery, 0, $cfg['MaxCharactersInDisplayedSQL']) . '[...]';
} else {
$queryBase = $sqlQuery;
}
// 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'])) {
$newLine = '\\n"
' . "\n" . ' . "';
$queryBase = htmlspecialchars(addslashes($queryBase));
$queryBase = preg_replace('/((\015\012)|(\015)|(\012))/', $newLine, $queryBase);
$queryBase = '
' . "\n"
. '$sql = "' . $queryBase . '";' . "\n"
. '
';
} elseif ($queryTooBig) {
$queryBase = '
' . "\n" .
htmlspecialchars($queryBase, ENT_COMPAT) .
'
';
} else {
$queryBase = self::formatSql($queryBase);
}
// 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
$urlParams = [];
if (! isset($GLOBALS['db'])) {
$GLOBALS['db'] = '';
}
if (strlen($GLOBALS['db']) > 0) {
$urlParams['db'] = $GLOBALS['db'];
if (strlen($GLOBALS['table']) > 0) {
$urlParams['table'] = $GLOBALS['table'];
$editLinkRoute = '/table/sql';
} else {
$editLinkRoute = '/database/sql';
}
} else {
$editLinkRoute = '/server/sql';
}
// Want to have the query explained
// but only explain a SELECT (that has not been explained)
/* SQL-Parser-Analyzer */
$explainLink = '';
$isSelect = preg_match('@^SELECT[[:space:]]+@i', $sqlQuery);
if (! empty($cfg['SQLQuery']['Explain']) && ! $queryTooBig) {
$explainParams = $urlParams;
if ($isSelect) {
$explainParams['sql_query'] = 'EXPLAIN ' . $sqlQuery;
$explainLink = ' [ '
. self::linkOrButton(
Url::getFromRoute('/import', $explainParams),
null,
__('Explain SQL')
) . ' ]';
} elseif (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $sqlQuery)) {
$explainParams['sql_query'] = mb_substr($sqlQuery, 8);
$explainLink = ' [ '
. self::linkOrButton(
Url::getFromRoute('/import', $explainParams),
null,
__('Skip Explain SQL')
) . ']';
}
}
$urlParams['sql_query'] = $sqlQuery;
$urlParams['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'])) {
$editLink = ' [ '
. self::linkOrButton(Url::getFromRoute($editLinkRoute, $urlParams), null, __('Edit'))
. ' ]';
} else {
$editLink = '';
}
// Also we would like to get the SQL formed in some nice
// php-code
if (! empty($cfg['SQLQuery']['ShowAsPHP']) && ! $queryTooBig) {
if (! empty($GLOBALS['show_as_php'])) {
$phpLink = ' [ '
. self::linkOrButton(
Url::getFromRoute('/import', $urlParams),
null,
__('Without PHP code')
)
. ' ]';
$phpLink .= ' [ '
. self::linkOrButton(
Url::getFromRoute('/import', $urlParams),
null,
__('Submit query')
)
. ' ]';
} else {
$phpParams = $urlParams;
$phpParams['show_as_php'] = 1;
$phpLink = ' [ '
. self::linkOrButton(
Url::getFromRoute('/import', $phpParams),
null,
__('Create PHP code')
)
. ' ]';
}
} else {
$phpLink = '';
}
// Refresh query
if (
! empty($cfg['SQLQuery']['Refresh'])
&& ! isset($GLOBALS['show_as_php']) // 'Submit query' does the same
&& preg_match('@^(SELECT|SHOW)[[:space:]]+@i', $sqlQuery)
) {
$refreshLink = Url::getFromRoute('/sql', $urlParams);
$refreshLink = ' [ '
. self::linkOrButton($refreshLink, null, __('Refresh')) . ' ]';
} else {
$refreshLink = '';
}
$retval .= '
';
$retval .= $queryBase;
$retval .= '
';
$retval .= '
';
$retval .= '';
/**
* TODO: Should we have $cfg['SQLQuery']['InlineEdit']?
*/
if (! empty($cfg['SQLQuery']['Edit']) && ! $queryTooBig && empty($GLOBALS['show_as_php'])) {
$inlineEditLink = ' [ '
. self::linkOrButton(
'#',
null,
_pgettext('Inline edit query', 'Edit inline'),
['class' => 'inline_edit_sql']
)
. ' ]';
} else {
$inlineEditLink = '';
}
$retval .= $inlineEditLink . $editLink . $explainLink . $phpLink
. $refreshLink;
$retval .= '
';
$retval .= '
';
}
return $retval;
}
/**
* Displays a link to the PHP documentation
*
* @param string $target anchor in documentation
*
* @return string the html link
*/
public static function showPHPDocumentation($target): string
{
return self::showDocumentationLink(Core::getPHPDocLink($target));
}
/**
* Displays a link to the documentation as an icon
*
* @param string $link documentation link
* @param string $target optional link target
* @param bool $bbcode optional flag indicating whether to output bbcode
*
* @return string the html link
*/
public static function showDocumentationLink($link, $target = 'documentation', $bbcode = false): string
{
if ($bbcode) {
return '[a@' . $link . '@' . $target . '][dochelpicon][/a]';
}
return '' . __('Error') . '
';
// For security reasons, if the MySQL refuses the connection, the query
// is hidden so no details are revealed.
if (! empty($sqlQuery) && ! mb_strstr($sqlQuery, 'connect')) {
// Static analysis errors.
if (! empty($errors)) {
$errorMessage .= '
' . __('Static analysis:')
. '
';
$errorMessage .= '
' . sprintf(
__('%d errors were found during analysis.'),
count($errors)
) . '
';
$errorMessage .= '
';
$errorMessage .= implode(
ParserError::format(
$errors,
'- %2$s (near "%4$s" at position %5$d)
'
)
);
$errorMessage .= '
';
}
// Display the SQL query and link to MySQL documentation.
$errorMessage .= '
' . __('SQL query:') . '' . self::showCopyToClipboard(
$sqlQuery
) . "\n";
$formattedSqlToLower = mb_strtolower($formattedSql);
// TODO: Show documentation for all statement types.
if (mb_strstr($formattedSqlToLower, 'select')) {
// please show me help to the error on select
$errorMessage .= MySQLDocumentation::show('SELECT');
}
if ($isModifyLink) {
$urlParams = [
'sql_query' => $sqlQuery,
'show_query' => 1,
];
if (strlen($table) > 0) {
$urlParams['db'] = $db;
$urlParams['table'] = $table;
$doEditGoto = '';
} elseif (strlen($db) > 0) {
$urlParams['db'] = $db;
$doEditGoto = '';
} else {
$doEditGoto = '';
}
$errorMessage .= $doEditGoto
. self::getIcon('b_edit', __('Edit'))
. '';
}
$errorMessage .= '
' . "\n"
. '
' . "\n"
. $formattedSql . "\n"
. '
' . "\n";
}
// Display server's error.
if ($serverMessage !== '') {
$serverMessage = (string) preg_replace("@((\015\012)|(\015)|(\012)){3,}@", "\n\n", $serverMessage);
// Adds a link to MySQL documentation.
$errorMessage .= '
' . "\n"
. ' ' . __('MySQL said: ') . ''
. MySQLDocumentation::show('server-error-reference')
. "\n"
. '
' . "\n";
// The error message will be displayed within a CODE segment.
// To preserve original formatting, but allow word-wrapping,
// a couple of replacements are done.
// All non-single blanks and TAB-characters are replaced with their
// HTML-counterpart
$serverMessage = str_replace(
[
' ',
"\t",
],
[
' ',
' ',
],
$serverMessage
);
// Replace line breaks
$serverMessage = nl2br($serverMessage);
$errorMessage .= '
' . $serverMessage . '
';
}
$errorMessage .= '
';
$_SESSION['Import_message']['message'] = $errorMessage;
if (! $exit) {
return $errorMessage;
}
/**
* If this is an AJAX request, there is no "Back" link and
* `Response()` is used to send the response.
*/
$response = ResponseRenderer::getInstance();
if ($response->isAjax()) {
$response->setRequestStatus(false);
$response->addJSON('message', $errorMessage);
exit;
}
if (! empty($backUrl)) {
if (mb_strstr($backUrl, '?')) {
$backUrl .= '&no_history=true';
} else {
$backUrl .= '?no_history=true';
}
$_SESSION['Import_message']['go_back_url'] = $backUrl;
$errorMessage .= '' . "\n\n";
}
exit($errorMessage);
}
/**
* Returns an HTML IMG tag for a particular image from a theme
*
* The image name should match CSS class defined in icons.css.php
*
* @param string $image The name of the file to get
* @param string $alternate Used to set 'alt' and 'title' attributes
* of the image
* @param array $attributes An associative array of other attributes
*
* @return string an html IMG tag
*/
public static function getImage($image, $alternate = '', array $attributes = []): string
{
$alternate = htmlspecialchars($alternate);
if (isset($attributes['class'])) {
$attributes['class'] = 'icon ic_' . $image . ' ' . $attributes['class'];
} else {
$attributes['class'] = 'icon ic_' . $image;
}
// set all other attributes
$attributeString = '';
foreach ($attributes as $key => $value) {
if (in_array($key, ['alt', 'title'])) {
continue;
}
$attributeString .= ' ' . $key . '="' . $value . '"';
}
// override the alt attribute
$alt = $attributes['alt'] ?? $alternate;
// override the title attribute
$title = $attributes['title'] ?? $alternate;
// generate the IMG tag
$template = '