Merge pull request #19068 from MauricioFauth/console-settings
Refactor Console settings handling
This commit is contained in:
commit
913e7d4b17
@ -93,6 +93,10 @@ return [
|
||||
'class' => Console\Bookmark\RefreshController::class,
|
||||
'arguments' => ['$response' => '@response', '$template' => '@template', '$console' => '@console'],
|
||||
],
|
||||
Console\UpdateConfigController::class => [
|
||||
'class' => Console\UpdateConfigController::class,
|
||||
'arguments' => ['$response' => '@response', '$template' => '@template', '$config' => '@config'],
|
||||
],
|
||||
Database\CentralColumns\PopulateColumnsController::class => [
|
||||
'class' => Database\CentralColumns\PopulateColumnsController::class,
|
||||
'arguments' => [
|
||||
|
||||
@ -12449,6 +12449,12 @@
|
||||
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
|
||||
</DeprecatedMethod>
|
||||
</file>
|
||||
<file src="tests/unit/Controllers/Console/UpdateConfigControllerTest.php">
|
||||
<PossiblyUnusedMethod>
|
||||
<code><![CDATA[invalidParamsProvider]]></code>
|
||||
<code><![CDATA[validParamsProvider]]></code>
|
||||
</PossiblyUnusedMethod>
|
||||
</file>
|
||||
<file src="tests/unit/Controllers/Database/EventsControllerTest.php">
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[Config::getInstance()]]></code>
|
||||
@ -14482,6 +14488,7 @@
|
||||
<code><![CDATA[Config::getInstance()]]></code>
|
||||
</DeprecatedMethod>
|
||||
<MixedAssignment>
|
||||
<code><![CDATA[$json['error']]]></code>
|
||||
<code><![CDATA[$value]]></code>
|
||||
</MixedAssignment>
|
||||
<PossiblyUnusedMethod>
|
||||
|
||||
@ -939,7 +939,7 @@ const AJAX = {
|
||||
console.log('AJAX error: status=' + request.status + ', text=' + request.statusText);
|
||||
}
|
||||
|
||||
if (settings.url.includes('/git-revision')) {
|
||||
if (settings.url.includes('/git-revision') || settings.url.includes('/console/update-config')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -4,10 +4,11 @@ import { AJAX } from './ajax.ts';
|
||||
import { Functions } from './functions.ts';
|
||||
import { CommonParams } from './common.ts';
|
||||
import { Navigation } from './navigation.ts';
|
||||
import { Config } from './console/config.ts';
|
||||
import { getConfigValue } from './functions/config.ts';
|
||||
import Config from './console/config.ts';
|
||||
import { escapeHtml } from './functions/escape.ts';
|
||||
|
||||
let config: Config;
|
||||
|
||||
/**
|
||||
* Console object
|
||||
*/
|
||||
@ -58,18 +59,13 @@ var Console = {
|
||||
* Used for console initialize, reinit is ok, just some variable assignment
|
||||
*/
|
||||
initialize: function (): void {
|
||||
if ($('#pma_console').length === 0) {
|
||||
const consoleElement = document.getElementById('pma_console');
|
||||
if (consoleElement === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
getConfigValue('Console', false, (data) => {
|
||||
Config.init(data);
|
||||
Console.setupAfterInit();
|
||||
}, () => {
|
||||
Config.init({});// Avoid null pointers in setupAfterInit()
|
||||
// Fetching data failed, still perform the console init
|
||||
Console.setupAfterInit();
|
||||
});
|
||||
config = Config.createFromDataset(consoleElement.dataset);
|
||||
Console.setupAfterInit();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -101,28 +97,6 @@ var Console = {
|
||||
|
||||
// Event binds shouldn't run again
|
||||
if (Console.isInitialized === false) {
|
||||
// Load config first
|
||||
if (Config.AlwaysExpand) {
|
||||
(document.getElementById('consoleOptionsAlwaysExpandCheckbox') as HTMLInputElement).checked = true;
|
||||
}
|
||||
|
||||
if (Config.StartHistory) {
|
||||
(document.getElementById('consoleOptionsStartHistoryCheckbox') as HTMLInputElement).checked = true;
|
||||
}
|
||||
|
||||
if (Config.CurrentQuery) {
|
||||
(document.getElementById('consoleOptionsCurrentQueryCheckbox') as HTMLInputElement).checked = true;
|
||||
}
|
||||
|
||||
if (Config.EnterExecutes) {
|
||||
(document.getElementById('consoleOptionsEnterExecutesCheckbox') as HTMLInputElement).checked = true;
|
||||
}
|
||||
|
||||
if (Config.DarkTheme) {
|
||||
(document.getElementById('consoleOptionsDarkThemeCheckbox') as HTMLInputElement).checked = true;
|
||||
$('#pma_console').find('>.content').addClass('console_dark_theme');
|
||||
}
|
||||
|
||||
ConsoleResizer.initialize();
|
||||
ConsoleInput.initialize();
|
||||
ConsoleMessages.initialize();
|
||||
@ -174,21 +148,65 @@ var Console = {
|
||||
Console.hideCard($(this).closest('.card'));
|
||||
});
|
||||
|
||||
$('#pma_console_options').find('input[type=checkbox]').on('change', function () {
|
||||
Config.update();
|
||||
const consoleOptionsAlwaysExpandCheckbox = document.getElementById('consoleOptionsAlwaysExpandCheckbox') as HTMLInputElement;
|
||||
consoleOptionsAlwaysExpandCheckbox?.addEventListener('change', function (): void {
|
||||
config.setAlwaysExpand(consoleOptionsAlwaysExpandCheckbox.checked);
|
||||
});
|
||||
|
||||
$('#pma_console_options').find('.button.default').on('click', function () {
|
||||
(document.getElementById('consoleOptionsAlwaysExpandCheckbox') as HTMLInputElement).checked = false;
|
||||
(document.getElementById('consoleOptionsStartHistoryCheckbox') as HTMLInputElement).checked = false;
|
||||
(document.getElementById('consoleOptionsCurrentQueryCheckbox') as HTMLInputElement).checked = true;
|
||||
(document.getElementById('consoleOptionsEnterExecutesCheckbox') as HTMLInputElement).checked = false;
|
||||
(document.getElementById('consoleOptionsDarkThemeCheckbox') as HTMLInputElement).checked = false;
|
||||
Config.update();
|
||||
const consoleOptionsStartHistoryCheckbox = document.getElementById('consoleOptionsStartHistoryCheckbox') as HTMLInputElement;
|
||||
consoleOptionsStartHistoryCheckbox?.addEventListener('change', function (): void {
|
||||
config.setStartHistory(consoleOptionsStartHistoryCheckbox.checked);
|
||||
});
|
||||
|
||||
$('#consoleOptionsEnterExecutesCheckbox').on('change', function () {
|
||||
ConsoleMessages.showInstructions(Config.EnterExecutes);
|
||||
const consoleOptionsCurrentQueryCheckbox = document.getElementById('consoleOptionsCurrentQueryCheckbox') as HTMLInputElement;
|
||||
consoleOptionsCurrentQueryCheckbox?.addEventListener('change', function (): void {
|
||||
config.setCurrentQuery(consoleOptionsCurrentQueryCheckbox.checked);
|
||||
});
|
||||
|
||||
const consoleOptionsEnterExecutesCheckbox = document.getElementById('consoleOptionsEnterExecutesCheckbox') as HTMLInputElement;
|
||||
consoleOptionsEnterExecutesCheckbox?.addEventListener('change', function (): void {
|
||||
const isEnterExecutes = consoleOptionsEnterExecutesCheckbox.checked;
|
||||
config.setEnterExecutes(isEnterExecutes);
|
||||
ConsoleMessages.showInstructions(isEnterExecutes);
|
||||
});
|
||||
|
||||
const consoleOptionsDarkThemeCheckbox = document.getElementById('consoleOptionsDarkThemeCheckbox') as HTMLInputElement;
|
||||
consoleOptionsDarkThemeCheckbox?.addEventListener('change', function (): void {
|
||||
const isDarkTheme = consoleOptionsDarkThemeCheckbox.checked;
|
||||
config.setDarkTheme(isDarkTheme);
|
||||
const consoleContent = document.getElementById('pma_console').querySelector('.content');
|
||||
consoleContent.classList.toggle('console_dark_theme', isDarkTheme);
|
||||
});
|
||||
|
||||
const restoreConsoleOptionsButton = document.getElementById('pma_console_options').querySelector('.button.default');
|
||||
restoreConsoleOptionsButton?.addEventListener('click', function (): void {
|
||||
if (consoleOptionsAlwaysExpandCheckbox.checked) {
|
||||
consoleOptionsAlwaysExpandCheckbox.checked = false;
|
||||
config.setAlwaysExpand(false);
|
||||
}
|
||||
|
||||
if (consoleOptionsStartHistoryCheckbox.checked) {
|
||||
consoleOptionsStartHistoryCheckbox.checked = false;
|
||||
config.setStartHistory(false);
|
||||
}
|
||||
|
||||
if (! consoleOptionsCurrentQueryCheckbox.checked) {
|
||||
consoleOptionsCurrentQueryCheckbox.checked = true;
|
||||
config.setCurrentQuery(true);
|
||||
}
|
||||
|
||||
if (consoleOptionsEnterExecutesCheckbox.checked) {
|
||||
consoleOptionsEnterExecutesCheckbox.checked = false;
|
||||
config.setEnterExecutes(false);
|
||||
ConsoleMessages.showInstructions(false);
|
||||
}
|
||||
|
||||
if (consoleOptionsDarkThemeCheckbox.checked) {
|
||||
consoleOptionsDarkThemeCheckbox.checked = false;
|
||||
config.setDarkTheme(false);
|
||||
const consoleContent = document.getElementById('pma_console').querySelector('.content');
|
||||
consoleContent.classList.remove('console_dark_theme');
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('ajaxComplete', function (event, xhr, ajaxOptions) {
|
||||
@ -215,7 +233,7 @@ var Console = {
|
||||
}
|
||||
|
||||
// Change console mode from cookie
|
||||
switch (Config.Mode) {
|
||||
switch (config.mode) {
|
||||
case 'collapse':
|
||||
Console.collapse();
|
||||
break;
|
||||
@ -227,7 +245,7 @@ var Console = {
|
||||
Console.scrollBottom();
|
||||
break;
|
||||
default:
|
||||
Config.set('Mode', 'info');
|
||||
config.setMode('info');
|
||||
Console.info();
|
||||
}
|
||||
},
|
||||
@ -282,7 +300,7 @@ var Console = {
|
||||
if (data.reloadQuerywindow.sql_query.length > 0) {
|
||||
ConsoleMessages.appendQuery(data.reloadQuerywindow, 'successed')
|
||||
// @ts-ignore
|
||||
.$message.addClass(Config.CurrentQuery ? '' : 'hide');
|
||||
.$message.addClass(config.currentQuery ? '' : 'hide');
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -290,8 +308,8 @@ var Console = {
|
||||
* Change console to collapse mode
|
||||
*/
|
||||
collapse: function (): void {
|
||||
Config.set('Mode', 'collapse');
|
||||
var pmaConsoleHeight = Math.max(92, Config.Height);
|
||||
config.setMode('collapse');
|
||||
var pmaConsoleHeight = Math.max(92, config.height);
|
||||
|
||||
Console.$consoleToolbar.addClass('collapsed');
|
||||
Console.$consoleAllContents.height(pmaConsoleHeight);
|
||||
@ -305,11 +323,11 @@ var Console = {
|
||||
* @param {boolean} inputFocus If true, focus the input line after show()
|
||||
*/
|
||||
show: function (inputFocus = undefined): void {
|
||||
Config.set('Mode', 'show');
|
||||
config.setMode('show');
|
||||
|
||||
var pmaConsoleHeight = Math.max(92, Config.Height);
|
||||
var pmaConsoleHeight = Math.max(92, config.height);
|
||||
// eslint-disable-next-line compat/compat
|
||||
pmaConsoleHeight = Math.min(Config.Height, (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - 25);
|
||||
pmaConsoleHeight = Math.min(config.height, (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - 25);
|
||||
Console.$consoleContent.css({ display: 'block' });
|
||||
if (Console.$consoleToolbar.hasClass('collapsed')) {
|
||||
Console.$consoleToolbar.removeClass('collapsed');
|
||||
@ -335,7 +353,7 @@ var Console = {
|
||||
* Used for toggle buttons and shortcuts
|
||||
*/
|
||||
toggle: function (): void {
|
||||
if (Config.Mode === 'show') {
|
||||
if (config.mode === 'show') {
|
||||
Console.collapse();
|
||||
} else {
|
||||
Console.show(true);
|
||||
@ -413,7 +431,7 @@ var ConsoleResizer = {
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
mouseDown: function (event): void {
|
||||
if (Config.Mode !== 'show') {
|
||||
if (config.mode !== 'show') {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -456,7 +474,7 @@ var ConsoleResizer = {
|
||||
* Mouseup event handler for bind to resizer
|
||||
*/
|
||||
mouseUp: function (): void {
|
||||
Config.set('Height', Math.round(ConsoleResizer.resultHeight));
|
||||
config.setHeight(Math.round(ConsoleResizer.resultHeight));
|
||||
Console.show();
|
||||
$(document).off('mousemove');
|
||||
$(document).off('mouseup');
|
||||
@ -638,7 +656,7 @@ var ConsoleInput = {
|
||||
*/
|
||||
keyDown: function (event): void {
|
||||
// Execute command
|
||||
if (Config.EnterExecutes) {
|
||||
if (config.enterExecutes) {
|
||||
// Enter, but not in combination with Shift (which writes a new line).
|
||||
if (! event.shiftKey && event.keyCode === 13) {
|
||||
ConsoleInput.execute();
|
||||
@ -810,7 +828,7 @@ var ConsoleMessages = {
|
||||
var now = new Date();
|
||||
var $newMessage =
|
||||
$('<div class="message ' +
|
||||
(Config.AlwaysExpand ? 'expanded' : 'collapsed') +
|
||||
(config.alwaysExpand ? 'expanded' : 'collapsed') +
|
||||
'" msgid="' + msgId + '"><div class="action_content"></div></div>');
|
||||
switch (msgType) {
|
||||
case 'query':
|
||||
@ -1053,11 +1071,11 @@ var ConsoleMessages = {
|
||||
*/
|
||||
initialize: function (): void {
|
||||
ConsoleMessages.messageEventBinds($('#pma_console').find('.message:not(.binded)'));
|
||||
if (Config.StartHistory) {
|
||||
if (config.startHistory) {
|
||||
ConsoleMessages.showHistory();
|
||||
}
|
||||
|
||||
ConsoleMessages.showInstructions(Config.EnterExecutes);
|
||||
ConsoleMessages.showInstructions(config.enterExecutes);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1163,17 +1181,17 @@ var ConsoleDebug = {
|
||||
}
|
||||
});
|
||||
|
||||
if (Config.GroupQueries) {
|
||||
if (config.groupQueries) {
|
||||
$('#debug_console').addClass('grouped');
|
||||
} else {
|
||||
$('#debug_console').addClass('ungrouped');
|
||||
if (Config.OrderBy === 'count') {
|
||||
if (config.orderBy === 'count') {
|
||||
$('#debug_console').find('.button.order_by.sort_exec').addClass('active');
|
||||
}
|
||||
}
|
||||
|
||||
var orderBy = Config.OrderBy;
|
||||
var order = Config.Order;
|
||||
var orderBy = config.orderBy;
|
||||
var order = config.order;
|
||||
$('#debug_console').find('.button.order_by.sort_' + orderBy).addClass('active');
|
||||
$('#debug_console').find('.button.order.order_' + order).addClass('active');
|
||||
|
||||
@ -1181,9 +1199,9 @@ var ConsoleDebug = {
|
||||
$('#debug_console').find('.button.group_queries').on('click', function () {
|
||||
$('#debug_console').addClass('grouped');
|
||||
$('#debug_console').removeClass('ungrouped');
|
||||
Config.set('GroupQueries', true);
|
||||
config.setGroupQueries(true);
|
||||
ConsoleDebug.refresh();
|
||||
if (Config.OrderBy === 'count') {
|
||||
if (config.orderBy === 'count') {
|
||||
$('#debug_console').find('.button.order_by.sort_exec').removeClass('active');
|
||||
}
|
||||
});
|
||||
@ -1191,9 +1209,9 @@ var ConsoleDebug = {
|
||||
$('#debug_console').find('.button.ungroup_queries').on('click', function () {
|
||||
$('#debug_console').addClass('ungrouped');
|
||||
$('#debug_console').removeClass('grouped');
|
||||
Config.set('GroupQueries', false);
|
||||
config.setGroupQueries(false);
|
||||
ConsoleDebug.refresh();
|
||||
if (Config.OrderBy === 'count') {
|
||||
if (config.orderBy === 'count') {
|
||||
$('#debug_console').find('.button.order_by.sort_exec').addClass('active');
|
||||
}
|
||||
});
|
||||
@ -1203,11 +1221,11 @@ var ConsoleDebug = {
|
||||
$('#debug_console').find('.button.order_by').removeClass('active');
|
||||
$this.addClass('active');
|
||||
if ($this.hasClass('sort_time')) {
|
||||
Config.set('OrderBy', 'time');
|
||||
config.setOrderBy('time');
|
||||
} else if ($this.hasClass('sort_exec')) {
|
||||
Config.set('OrderBy', 'exec');
|
||||
config.setOrderBy('exec');
|
||||
} else if ($this.hasClass('sort_count')) {
|
||||
Config.set('OrderBy', 'count');
|
||||
config.setOrderBy('count');
|
||||
}
|
||||
|
||||
ConsoleDebug.refresh();
|
||||
@ -1218,9 +1236,9 @@ var ConsoleDebug = {
|
||||
$('#debug_console').find('.button.order').removeClass('active');
|
||||
$this.addClass('active');
|
||||
if ($this.hasClass('order_asc')) {
|
||||
Config.set('Order', 'asc');
|
||||
config.setOrder('asc');
|
||||
} else if ($this.hasClass('order_desc')) {
|
||||
Config.set('Order', 'desc');
|
||||
config.setOrder('desc');
|
||||
}
|
||||
|
||||
ConsoleDebug.refresh();
|
||||
@ -1507,7 +1525,7 @@ var ConsoleDebug = {
|
||||
|
||||
// For sorting queries
|
||||
function sortByTime (a, b) {
|
||||
var order = Config.Order === 'asc' ? 1 : -1;
|
||||
var order = config.order === 'asc' ? 1 : -1;
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
// It is grouped
|
||||
var timeA = 0;
|
||||
@ -1528,15 +1546,15 @@ var ConsoleDebug = {
|
||||
}
|
||||
|
||||
function sortByCount (a, b) {
|
||||
var order = Config.Order === 'asc' ? 1 : -1;
|
||||
var order = config.order === 'asc' ? 1 : -1;
|
||||
|
||||
return (a.length - b.length) * order;
|
||||
}
|
||||
|
||||
var orderBy = Config.OrderBy;
|
||||
var order = Config.Order;
|
||||
var orderBy = config.orderBy;
|
||||
var order = config.order;
|
||||
|
||||
if (Config.GroupQueries) {
|
||||
if (config.groupQueries) {
|
||||
// Sort queries
|
||||
if (orderBy === 'time') {
|
||||
uniqueQueries.sort(sortByTime);
|
||||
|
||||
@ -1,90 +1,139 @@
|
||||
import { setConfigValue } from '../functions/config.ts';
|
||||
import $ from 'jquery';
|
||||
import { ajaxShowMessage } from '../ajax-message.ts';
|
||||
import { CommonParams } from '../common.ts';
|
||||
import { escapeHtml } from '../functions/escape.ts';
|
||||
|
||||
/**
|
||||
* @link https://docs.phpmyadmin.net/en/latest/config.html#console-settings
|
||||
*/
|
||||
export const Config = {
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
StartHistory: false,
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
AlwaysExpand: false,
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
CurrentQuery: true,
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
EnterExecutes: false,
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
DarkTheme: false,
|
||||
/**
|
||||
* @type {'info'|'show'|'collapse'}
|
||||
*/
|
||||
Mode: 'info',
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
Height: 92,
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
GroupQueries: false,
|
||||
/**
|
||||
* @type {'exec'|'time'|'count'}
|
||||
*/
|
||||
OrderBy: 'exec',
|
||||
/**
|
||||
* @type {'asc'|'desc'}
|
||||
*/
|
||||
Order: 'asc',
|
||||
export default class Config {
|
||||
startHistory: boolean;
|
||||
|
||||
/**
|
||||
* @param {Object} data
|
||||
*/
|
||||
init: function (data): void {
|
||||
this.StartHistory = !! data.StartHistory;
|
||||
this.AlwaysExpand = !! data.AlwaysExpand;
|
||||
this.CurrentQuery = data.CurrentQuery !== undefined ? !! data.CurrentQuery : true;
|
||||
this.EnterExecutes = !! data.EnterExecutes;
|
||||
this.DarkTheme = !! data.DarkTheme;
|
||||
this.Mode = data.Mode === 'show' || data.Mode === 'collapse' ? data.Mode : 'info';
|
||||
this.Height = data.Height > 0 ? Number(data.Height) : 92;
|
||||
this.GroupQueries = !! data.GroupQueries;
|
||||
this.OrderBy = data.OrderBy === 'time' || data.OrderBy === 'count' ? data.OrderBy : 'exec';
|
||||
this.Order = data.Order === 'desc' ? 'desc' : 'asc';
|
||||
},
|
||||
alwaysExpand: boolean;
|
||||
|
||||
/**
|
||||
* @param {'StartHistory'|'AlwaysExpand'|'CurrentQuery'|'EnterExecutes'|'DarkTheme'|'Mode'|'Height'|'GroupQueries'|'OrderBy'|'Order'} key
|
||||
* @param {boolean|string|number} value
|
||||
*/
|
||||
set: function (key, value): void {
|
||||
this[key] = value;
|
||||
setConfigValue('Console/' + key, value);
|
||||
},
|
||||
currentQuery: boolean;
|
||||
|
||||
/**
|
||||
* Used for update console config
|
||||
*/
|
||||
update: function (): void {
|
||||
this.set('AlwaysExpand', !! (document.getElementById('consoleOptionsAlwaysExpandCheckbox') as HTMLInputElement).checked);
|
||||
this.set('StartHistory', !! (document.getElementById('consoleOptionsStartHistoryCheckbox') as HTMLInputElement).checked);
|
||||
this.set('CurrentQuery', !! (document.getElementById('consoleOptionsCurrentQueryCheckbox') as HTMLInputElement).checked);
|
||||
this.set('EnterExecutes', !! (document.getElementById('consoleOptionsEnterExecutesCheckbox') as HTMLInputElement).checked);
|
||||
this.set('DarkTheme', !! (document.getElementById('consoleOptionsDarkThemeCheckbox') as HTMLInputElement).checked);
|
||||
/* Setting the dark theme of the console*/
|
||||
const consoleContent = document.getElementById('pma_console').querySelector('.content');
|
||||
if (this.DarkTheme) {
|
||||
consoleContent.classList.add('console_dark_theme');
|
||||
} else {
|
||||
consoleContent.classList.remove('console_dark_theme');
|
||||
}
|
||||
enterExecutes: boolean;
|
||||
|
||||
darkTheme: boolean;
|
||||
|
||||
mode: 'info'|'show'|'collapse';
|
||||
|
||||
height: number;
|
||||
|
||||
groupQueries: boolean;
|
||||
|
||||
orderBy: 'exec'|'time'|'count';
|
||||
|
||||
order: 'asc'|'desc';
|
||||
|
||||
constructor (
|
||||
startHistory: boolean,
|
||||
alwaysExpand: boolean,
|
||||
currentQuery: boolean,
|
||||
enterExecutes: boolean,
|
||||
darkTheme: boolean,
|
||||
mode: 'info'|'show'|'collapse',
|
||||
height: number,
|
||||
groupQueries: boolean,
|
||||
orderBy: 'exec'|'time'|'count',
|
||||
order: 'asc'|'desc',
|
||||
) {
|
||||
this.startHistory = startHistory;
|
||||
this.alwaysExpand = alwaysExpand;
|
||||
this.currentQuery = currentQuery;
|
||||
this.enterExecutes = enterExecutes;
|
||||
this.darkTheme = darkTheme;
|
||||
this.mode = mode;
|
||||
this.height = height;
|
||||
this.groupQueries = groupQueries;
|
||||
this.orderBy = orderBy;
|
||||
this.order = order;
|
||||
}
|
||||
};
|
||||
|
||||
static createFromDataset (dataset: DOMStringMap): Config {
|
||||
const height = Number(dataset.height);
|
||||
|
||||
return new this(
|
||||
dataset.startHistory === 'true',
|
||||
dataset.alwaysExpand === 'true',
|
||||
dataset.currentQuery !== undefined ? dataset.currentQuery === 'true' : true,
|
||||
dataset.enterExecutes === 'true',
|
||||
dataset.darkTheme === 'true',
|
||||
dataset.mode === 'show' || dataset.mode === 'collapse' ? dataset.mode : 'info',
|
||||
height > 0 ? height : 92,
|
||||
dataset.groupQueries === 'true',
|
||||
dataset.orderBy === 'time' || dataset.orderBy === 'count' ? dataset.orderBy : 'exec',
|
||||
dataset.order === 'desc' ? 'desc' : 'asc',
|
||||
);
|
||||
}
|
||||
|
||||
setStartHistory (value: boolean): void {
|
||||
this.startHistory = value;
|
||||
setConfigValue('StartHistory', value);
|
||||
}
|
||||
|
||||
setAlwaysExpand (value: boolean): void {
|
||||
this.alwaysExpand = value;
|
||||
setConfigValue('AlwaysExpand', value);
|
||||
}
|
||||
|
||||
setCurrentQuery (value: boolean): void {
|
||||
this.currentQuery = value;
|
||||
setConfigValue('CurrentQuery', value);
|
||||
}
|
||||
|
||||
setEnterExecutes (value: boolean): void {
|
||||
this.enterExecutes = value;
|
||||
setConfigValue('EnterExecutes', value);
|
||||
}
|
||||
|
||||
setDarkTheme (value: boolean): void {
|
||||
this.darkTheme = value;
|
||||
setConfigValue('DarkTheme', value);
|
||||
}
|
||||
|
||||
setMode (value: 'info'|'show'|'collapse'): void {
|
||||
this.mode = value;
|
||||
setConfigValue('Mode', value);
|
||||
}
|
||||
|
||||
setHeight (value: number): void {
|
||||
this.height = value;
|
||||
setConfigValue('Height', value);
|
||||
}
|
||||
|
||||
setGroupQueries (value: boolean): void {
|
||||
this.groupQueries = value;
|
||||
setConfigValue('GroupQueries', value);
|
||||
}
|
||||
|
||||
setOrderBy (value: 'exec'|'time'|'count'): void {
|
||||
this.orderBy = value;
|
||||
setConfigValue('OrderBy', value);
|
||||
}
|
||||
|
||||
setOrder (value: 'asc'|'desc'): void {
|
||||
this.order = value;
|
||||
setConfigValue('Order', value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {'StartHistory'|'AlwaysExpand'|'CurrentQuery'|'EnterExecutes'|'DarkTheme'|'Mode'|'Height'|'GroupQueries'|'OrderBy'|'Order'} key
|
||||
* @param {boolean|string|number} value
|
||||
*/
|
||||
function setConfigValue (key: string, value: boolean|number|string): void {
|
||||
$.post(
|
||||
'index.php?route=/console/update-config',
|
||||
{
|
||||
'ajax_request': true,
|
||||
server: CommonParams.get('server'),
|
||||
key: key,
|
||||
value: value,
|
||||
},
|
||||
).fail(function (data) {
|
||||
const message = '<div class="alert alert-danger" role="alert">' + escapeHtml(data.responseJSON.error) + '</div>';
|
||||
ajaxShowMessage(message, false);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
<div id="pma_console_container" class="d-print-none">
|
||||
<div id="pma_console">
|
||||
<div id="pma_console"
|
||||
data-start-history="{{ settings.StartHistory ? 'true' : 'false' }}"
|
||||
data-always-expand="{{ settings.AlwaysExpand ? 'true' : 'false' }}"
|
||||
data-current-query="{{ settings.CurrentQuery ? 'true' : 'false' }}"
|
||||
data-enter-executes="{{ settings.EnterExecutes ? 'true' : 'false' }}"
|
||||
data-dark-theme="{{ settings.DarkTheme ? 'true' : 'false' }}"
|
||||
data-mode="{{ settings.Mode }}"
|
||||
data-height="{{ settings.Height }}"
|
||||
data-group-queries="{{ settings.GroupQueries ? 'true' : 'false' }}"
|
||||
data-order-by="{{ settings.OrderBy }}"
|
||||
data-order="{{ settings.Order }}">
|
||||
<div class="toolbar collapsed">
|
||||
<div class="switch_button console_switch">
|
||||
{{ get_image('console', 'SQL Query Console'|trans) }}
|
||||
@ -27,7 +37,7 @@
|
||||
</div>
|
||||
|
||||
{# Console messages #}
|
||||
<div class="content">
|
||||
<div class="content{{ settings.DarkTheme ? ' console_dark_theme' }}">
|
||||
<div class="console_message_container">
|
||||
<div class="message welcome">
|
||||
<span id="instructions-0">{% trans 'Press Ctrl+Enter to execute query' %}</span>
|
||||
@ -165,29 +175,29 @@
|
||||
<span>{{ 'Options'|trans }}</span>
|
||||
</div>
|
||||
<div class="button default">
|
||||
<span>{{ 'Set default'|trans }}</span>
|
||||
<span>{{ 'Restore default values'|trans }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsAlwaysExpandCheckbox" name="always_expand">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsAlwaysExpandCheckbox" name="always_expand"{{ settings.AlwaysExpand ? ' checked' }}>
|
||||
<label class="form-check-label" for="consoleOptionsAlwaysExpandCheckbox">{{ 'Always expand query messages'|trans }}</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsStartHistoryCheckbox" name="start_history">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsStartHistoryCheckbox" name="start_history"{{ settings.StartHistory ? ' checked' }}>
|
||||
<label class="form-check-label" for="consoleOptionsStartHistoryCheckbox">{{ 'Show query history at start'|trans }}</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsCurrentQueryCheckbox" name="current_query">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsCurrentQueryCheckbox" name="current_query"{{ settings.CurrentQuery ? ' checked' }}>
|
||||
<label class="form-check-label" for="consoleOptionsCurrentQueryCheckbox">{{ 'Show current browsing query'|trans }}</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsEnterExecutesCheckbox" name="enter_executes">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsEnterExecutesCheckbox" name="enter_executes"{{ settings.EnterExecutes ? ' checked' }}>
|
||||
<label class="form-check-label" for="consoleOptionsEnterExecutesCheckbox">{{ 'Execute queries on Enter and insert new line with Shift+Enter. To make this permanent, view settings.'|trans }}</label>
|
||||
</div>
|
||||
<div class="form-check form-switch">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsDarkThemeCheckbox" name="dark_theme">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="consoleOptionsDarkThemeCheckbox" name="dark_theme"{{ settings.DarkTheme ? ' checked' }}>
|
||||
<label class="form-check-label" for="consoleOptionsDarkThemeCheckbox">{{ 'Switch to dark theme'|trans }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -113,6 +113,7 @@ class Console
|
||||
$bookmarkContent = $this->getBookmarkContent();
|
||||
|
||||
return $this->template->render('console/display', [
|
||||
'settings' => $this->config->config->Console->asArray(),
|
||||
'has_bookmark_feature' => $bookmarkFeature !== null,
|
||||
'sql_history' => $sqlHistory,
|
||||
'bookmark_content' => $bookmarkContent,
|
||||
|
||||
112
src/Controllers/Console/UpdateConfigController.php
Normal file
112
src/Controllers/Console/UpdateConfigController.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Controllers\Console;
|
||||
|
||||
use Fig\Http\Message\StatusCodeInterface;
|
||||
use InvalidArgumentException;
|
||||
use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\Controllers\AbstractController;
|
||||
use PhpMyAdmin\Http\Response;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\ResponseRenderer;
|
||||
use PhpMyAdmin\Template;
|
||||
|
||||
use function __;
|
||||
use function in_array;
|
||||
use function is_numeric;
|
||||
|
||||
final class UpdateConfigController extends AbstractController
|
||||
{
|
||||
public function __construct(ResponseRenderer $response, Template $template, private Config $config)
|
||||
{
|
||||
parent::__construct($response, $template);
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequest $request): Response
|
||||
{
|
||||
try {
|
||||
$key = $this->parseKeyParam($request->getParsedBodyParam('key'));
|
||||
$value = $this->parseValueParam($key, $request->getParsedBodyParam('value'));
|
||||
} catch (InvalidArgumentException $exception) {
|
||||
$this->response->setStatusCode(StatusCodeInterface::STATUS_BAD_REQUEST);
|
||||
$this->response->setRequestStatus(false);
|
||||
$this->response->addJSON(['message' => $exception->getMessage()]);
|
||||
|
||||
return $this->response->response();
|
||||
}
|
||||
|
||||
$result = $this->config->setUserValue(null, 'Console/' . $key, $value);
|
||||
if ($result !== true) {
|
||||
$this->response->setStatusCode(StatusCodeInterface::STATUS_INTERNAL_SERVER_ERROR);
|
||||
$this->response->setRequestStatus(false);
|
||||
$this->response->addJSON(['message' => $result->getMessage()]);
|
||||
|
||||
return $this->response->response();
|
||||
}
|
||||
|
||||
$this->response->addJSON('message', __('Console settings has been updated successfully.'));
|
||||
|
||||
return $this->response->response();
|
||||
}
|
||||
|
||||
/** @psalm-return 'StartHistory'|'AlwaysExpand'|'CurrentQuery'|'EnterExecutes'|'DarkTheme'|'Mode'|'Height'|'GroupQueries'|'OrderBy'|'Order' */
|
||||
private function parseKeyParam(mixed $key): string
|
||||
{
|
||||
if (
|
||||
! in_array($key, [
|
||||
'StartHistory',
|
||||
'AlwaysExpand',
|
||||
'CurrentQuery',
|
||||
'EnterExecutes',
|
||||
'DarkTheme',
|
||||
'Mode',
|
||||
'Height',
|
||||
'GroupQueries',
|
||||
'OrderBy',
|
||||
'Order',
|
||||
], true)
|
||||
) {
|
||||
throw new InvalidArgumentException(__('Unexpected parameter value.'));
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/** @psalm-param 'StartHistory'|'AlwaysExpand'|'CurrentQuery'|'EnterExecutes'|'DarkTheme'|'Mode'|'Height'|'GroupQueries'|'OrderBy'|'Order' $key */
|
||||
private function parseValueParam(string $key, mixed $value): bool|int|string
|
||||
{
|
||||
if (
|
||||
in_array($key, [
|
||||
'StartHistory',
|
||||
'AlwaysExpand',
|
||||
'CurrentQuery',
|
||||
'EnterExecutes',
|
||||
'DarkTheme',
|
||||
'GroupQueries',
|
||||
], true)
|
||||
&& in_array($value, ['true', 'false'], true)
|
||||
) {
|
||||
return $value === 'true';
|
||||
}
|
||||
|
||||
if ($key === 'Mode' && in_array($value, ['show', 'collapse', 'info'], true)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($key === 'Height' && is_numeric($value) && $value > 0) {
|
||||
return (int) $value;
|
||||
}
|
||||
|
||||
if ($key === 'OrderBy' && in_array($value, ['exec', 'time', 'count'], true)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($key === 'Order' && in_array($value, ['asc', 'desc'], true)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(__('Unexpected parameter value.'));
|
||||
}
|
||||
}
|
||||
@ -12,6 +12,7 @@ use PhpMyAdmin\Controllers\CollationConnectionController;
|
||||
use PhpMyAdmin\Controllers\ColumnController;
|
||||
use PhpMyAdmin\Controllers\Config;
|
||||
use PhpMyAdmin\Controllers\Console\Bookmark;
|
||||
use PhpMyAdmin\Controllers\Console\UpdateConfigController;
|
||||
use PhpMyAdmin\Controllers\Database;
|
||||
use PhpMyAdmin\Controllers\DatabaseController;
|
||||
use PhpMyAdmin\Controllers\ErrorReportController;
|
||||
@ -57,9 +58,12 @@ final class Routes
|
||||
$routes->post('/get', Config\GetConfigController::class);
|
||||
$routes->post('/set', Config\SetConfigController::class);
|
||||
});
|
||||
$routes->addGroup('/console/bookmark', static function (RouteCollector $routes): void {
|
||||
$routes->post('/add', Bookmark\AddController::class);
|
||||
$routes->get('/refresh', Bookmark\RefreshController::class);
|
||||
$routes->addGroup('/console', static function (RouteCollector $routes): void {
|
||||
$routes->addGroup('/bookmark', static function (RouteCollector $routes): void {
|
||||
$routes->post('/add', Bookmark\AddController::class);
|
||||
$routes->get('/refresh', Bookmark\RefreshController::class);
|
||||
});
|
||||
$routes->post('/update-config', UpdateConfigController::class);
|
||||
});
|
||||
$routes->addGroup('/database', static function (RouteCollector $routes): void {
|
||||
$routes->addGroup('/central-columns', static function (RouteCollector $routes): void {
|
||||
|
||||
159
tests/unit/Controllers/Console/UpdateConfigControllerTest.php
Normal file
159
tests/unit/Controllers/Console/UpdateConfigControllerTest.php
Normal file
@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Tests\Controllers\Console;
|
||||
|
||||
use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\Controllers\Console\UpdateConfigController;
|
||||
use PhpMyAdmin\DatabaseInterface;
|
||||
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
|
||||
use PhpMyAdmin\Message;
|
||||
use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
use PhpMyAdmin\Tests\Stubs\ResponseRenderer;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
use function json_decode;
|
||||
|
||||
#[CoversClass(UpdateConfigController::class)]
|
||||
final class UpdateConfigControllerTest extends AbstractTestCase
|
||||
{
|
||||
#[DataProvider('validParamsProvider')]
|
||||
public function testValidParams(string $key, string $value, bool|int|string $expected): void
|
||||
{
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withParsedBody(['key' => $key, 'value' => $value]);
|
||||
|
||||
DatabaseInterface::$instance = $this->createDatabaseInterface();
|
||||
$config = new Config();
|
||||
$responseRenderer = new ResponseRenderer();
|
||||
$responseRenderer->setAjax(true);
|
||||
$controller = new UpdateConfigController($responseRenderer, new Template($config), $config);
|
||||
$response = $controller($request);
|
||||
|
||||
$responseBody = (string) $response->getBody();
|
||||
self::assertJson($responseBody);
|
||||
self::assertSame(
|
||||
['message' => 'Console settings has been updated successfully.', 'success' => true],
|
||||
json_decode($responseBody, true),
|
||||
);
|
||||
self::assertSame($expected, $config->settings['Console'][$key]);
|
||||
}
|
||||
|
||||
/** @return iterable<array{string, string, bool|int|string}> */
|
||||
public static function validParamsProvider(): iterable
|
||||
{
|
||||
yield ['StartHistory', 'true', true];
|
||||
yield ['StartHistory', 'false', false];
|
||||
yield ['AlwaysExpand', 'true', true];
|
||||
yield ['AlwaysExpand', 'false', false];
|
||||
yield ['CurrentQuery', 'true', true];
|
||||
yield ['CurrentQuery', 'false', false];
|
||||
yield ['EnterExecutes', 'true', true];
|
||||
yield ['EnterExecutes', 'false', false];
|
||||
yield ['DarkTheme', 'true', true];
|
||||
yield ['DarkTheme', 'false', false];
|
||||
yield ['Mode', 'show', 'show'];
|
||||
yield ['Mode', 'collapse', 'collapse'];
|
||||
yield ['Mode', 'info', 'info'];
|
||||
yield ['Height', '1', 1];
|
||||
yield ['Height', '92', 92];
|
||||
yield ['GroupQueries', 'true', true];
|
||||
yield ['GroupQueries', 'false', false];
|
||||
yield ['OrderBy', 'exec', 'exec'];
|
||||
yield ['OrderBy', 'time', 'time'];
|
||||
yield ['OrderBy', 'count', 'count'];
|
||||
yield ['Order', 'asc', 'asc'];
|
||||
yield ['Order', 'desc', 'desc'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $key
|
||||
* @param string|string[] $value
|
||||
*/
|
||||
#[DataProvider('invalidParamsProvider')]
|
||||
public function testInvalidParams(array|string $key, array|string $value): void
|
||||
{
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withParsedBody(['key' => $key, 'value' => $value]);
|
||||
|
||||
DatabaseInterface::$instance = $this->createDatabaseInterface();
|
||||
$config = new Config();
|
||||
$responseRenderer = new ResponseRenderer();
|
||||
$responseRenderer->setAjax(true);
|
||||
$controller = new UpdateConfigController($responseRenderer, new Template($config), $config);
|
||||
$response = $controller($request);
|
||||
|
||||
$responseBody = (string) $response->getBody();
|
||||
self::assertJson($responseBody);
|
||||
self::assertSame(
|
||||
['success' => false, 'error' => 'Unexpected parameter value.'],
|
||||
json_decode($responseBody, true),
|
||||
);
|
||||
}
|
||||
|
||||
/** @return iterable<array{string|string[], string|string[]}> */
|
||||
public static function invalidParamsProvider(): iterable
|
||||
{
|
||||
yield ['StartHistory', ''];
|
||||
yield ['StartHistory', 'invalid'];
|
||||
yield ['StartHistory', ['invalid']];
|
||||
yield ['AlwaysExpand', ''];
|
||||
yield ['AlwaysExpand', 'invalid'];
|
||||
yield ['AlwaysExpand', ['invalid']];
|
||||
yield ['CurrentQuery', ''];
|
||||
yield ['CurrentQuery', 'invalid'];
|
||||
yield ['CurrentQuery', ['invalid']];
|
||||
yield ['EnterExecutes', ''];
|
||||
yield ['EnterExecutes', 'invalid'];
|
||||
yield ['EnterExecutes', ['invalid']];
|
||||
yield ['DarkTheme', ''];
|
||||
yield ['DarkTheme', 'invalid'];
|
||||
yield ['DarkTheme', ['invalid']];
|
||||
yield ['Mode', ''];
|
||||
yield ['Mode', 'invalid'];
|
||||
yield ['Mode', ['invalid']];
|
||||
yield ['Height', ''];
|
||||
yield ['Height', 'invalid'];
|
||||
yield ['Height', ['invalid']];
|
||||
yield ['Height', '0'];
|
||||
yield ['Height', '-1'];
|
||||
yield ['GroupQueries', ''];
|
||||
yield ['GroupQueries', 'invalid'];
|
||||
yield ['GroupQueries', ['invalid']];
|
||||
yield ['OrderBy', ''];
|
||||
yield ['OrderBy', 'invalid'];
|
||||
yield ['OrderBy', ['invalid']];
|
||||
yield ['Order', ''];
|
||||
yield ['Order', 'invalid'];
|
||||
yield ['Order', ['invalid']];
|
||||
yield ['', 'invalid'];
|
||||
yield ['invalid', 'invalid'];
|
||||
yield [['invalid'], 'invalid'];
|
||||
}
|
||||
|
||||
public function testFailedConfigSaving(): void
|
||||
{
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withParsedBody(['key' => 'StartHistory', 'value' => 'true']);
|
||||
|
||||
$config = self::createStub(Config::class);
|
||||
$config->method('setUserValue')->willReturn(Message::error('Could not save configuration'));
|
||||
$responseRenderer = new ResponseRenderer();
|
||||
$responseRenderer->setAjax(true);
|
||||
$controller = new UpdateConfigController($responseRenderer, new Template($config), $config);
|
||||
$response = $controller($request);
|
||||
|
||||
$responseBody = (string) $response->getBody();
|
||||
self::assertJson($responseBody);
|
||||
self::assertSame(
|
||||
['success' => false, 'error' => 'Could not save configuration'],
|
||||
json_decode($responseBody, true),
|
||||
);
|
||||
|
||||
self::assertSame(['message' => 'Could not save configuration'], $responseRenderer->getJSONResult());
|
||||
self::assertFalse($responseRenderer->hasSuccessState(), 'Should be a failed response.');
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,7 @@ use PhpMyAdmin\Controllers\CollationConnectionController;
|
||||
use PhpMyAdmin\Controllers\ColumnController;
|
||||
use PhpMyAdmin\Controllers\Config;
|
||||
use PhpMyAdmin\Controllers\Console\Bookmark;
|
||||
use PhpMyAdmin\Controllers\Console\UpdateConfigController;
|
||||
use PhpMyAdmin\Controllers\Database;
|
||||
use PhpMyAdmin\Controllers\Database\Structure\CentralColumns;
|
||||
use PhpMyAdmin\Controllers\DatabaseController;
|
||||
@ -164,6 +165,7 @@ final class RoutesTest extends TestCase
|
||||
'/config/get' => Config\GetConfigController::class,
|
||||
'/config/set' => Config\SetConfigController::class,
|
||||
'/console/bookmark/add' => Bookmark\AddController::class,
|
||||
'/console/update-config' => UpdateConfigController::class,
|
||||
'/database/central-columns' => Database\CentralColumnsController::class,
|
||||
'/database/central-columns/populate' => Database\CentralColumns\PopulateColumnsController::class,
|
||||
'/database/designer' => Database\DesignerController::class,
|
||||
|
||||
@ -25,6 +25,7 @@ use PhpMyAdmin\Message;
|
||||
use PhpMyAdmin\Template;
|
||||
|
||||
use function is_array;
|
||||
use function json_encode;
|
||||
|
||||
class ResponseRenderer extends \PhpMyAdmin\ResponseRenderer
|
||||
{
|
||||
@ -186,4 +187,26 @@ class ResponseRenderer extends \PhpMyAdmin\ResponseRenderer
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
public function response(): Response
|
||||
{
|
||||
if ($this->isAjax()) {
|
||||
$json = $this->getJSONResult();
|
||||
if ($this->isSuccess) {
|
||||
$json['success'] = true;
|
||||
} else {
|
||||
$json['success'] = false;
|
||||
$json['error'] = $json['message'];
|
||||
unset($json['message']);
|
||||
}
|
||||
|
||||
$output = (string) json_encode($json);
|
||||
} else {
|
||||
$output = $this->getHTMLResult();
|
||||
}
|
||||
|
||||
$this->response->getBody()->write($output);
|
||||
|
||||
return $this->response;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user