Update website

This commit is contained in:
Guilhem Lavaux 2024-11-19 09:35:33 +01:00
parent bb4b0f9be8
commit 011b183e28
4263 changed files with 3014 additions and 720369 deletions

View file

@ -1,19 +0,0 @@
const path = require('path');
module.exports = {
entry: './js/src/ol.mjs',
devtool: 'source-map',
mode: 'production',
performance: {
hints: false,
maxEntrypointSize: 512000,
maxAssetSize: 512000
},
output: {
path: path.resolve('./js/vendor/openlayers'),
filename: 'OpenLayers.js',
library: 'ol',
libraryTarget: 'umd',
libraryExport: 'default',
},
};

View file

@ -1,870 +0,0 @@
/**
* This object handles ajax requests for pages. It also
* handles the reloading of the main menu and scripts.
*
* @test-module AJAX
*/
var AJAX = {
/**
* @var {boolean} active Whether we are busy
*/
active: false,
/**
* @var {object} source The object whose event initialized the request
*/
source: null,
/**
* @var {object} xhr A reference to the ajax request that is currently running
*/
xhr: null,
/**
* @var {object} lockedTargets, list of locked targets
*/
lockedTargets: {},
// eslint-disable-next-line valid-jsdoc
/**
* @var {Function} callback Callback to execute after a successful request
* Used by CommonActions from common.js
*/
callback: function () {},
/**
* @var {boolean} debug Makes noise in your Firebug console
*/
debug: false,
/**
* @var {object} $msgbox A reference to a jQuery object that links to a message
* box that is generated by Functions.ajaxShowMessage()
*/
$msgbox: null,
/**
* Given the filename of a script, returns a hash to be
* used to refer to all the events registered for the file
*
* @param {string} key key The filename for which to get the event name
*
* @return {number}
*/
hash: function (key) {
var newKey = key;
/* https://burtleburtle.net/bob/hash/doobs.html#one */
newKey += '';
var len = newKey.length;
var hash = 0;
var i = 0;
for (; i < len; ++i) {
hash += newKey.charCodeAt(i);
hash += hash << 10;
hash ^= hash >> 6;
}
hash += hash << 3;
hash ^= hash >> 11;
hash += hash << 15;
return Math.abs(hash);
},
/**
* Registers an onload event for a file
*
* @param {string} file The filename for which to register the event
* @param {Function} func The function to execute when the page is ready
*
* @return {self} For chaining
*/
registerOnload: function (file, func) {
var eventName = 'onload_' + AJAX.hash(file);
$(document).on(eventName, func);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file);
}
return this;
},
/**
* Registers a teardown event for a file. This is useful to execute functions
* that unbind events for page elements that are about to be removed.
*
* @param {string} file The filename for which to register the event
* @param {Function} func The function to execute when
* the page is about to be torn down
*
* @return {self} For chaining
*/
registerTeardown: function (file, func) {
var eventName = 'teardown_' + AJAX.hash(file);
$(document).on(eventName, func);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file);
}
return this;
},
/**
* Called when a page has finished loading, once for every
* file that registered to the onload event of that file.
*
* @param {string} file The filename for which to fire the event
*
* @return {void}
*/
fireOnload: function (file) {
var eventName = 'onload_' + AJAX.hash(file);
$(document).trigger(eventName);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file);
}
},
/**
* Called just before a page is torn down, once for every
* file that registered to the teardown event of that file.
*
* @param {string} file The filename for which to fire the event
*
* @return {void}
*/
fireTeardown: function (file) {
var eventName = 'teardown_' + AJAX.hash(file);
$(document).triggerHandler(eventName);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file);
}
},
/**
* function to handle lock page mechanism
*
* @param event the event object
*
* @return {void}
*/
lockPageHandler: function (event) {
// don't consider checkbox event
if (typeof event.target !== 'undefined') {
if (event.target.type === 'checkbox') {
return;
}
}
var newHash = null;
var oldHash = null;
var lockId;
// CodeMirror lock
if (event.data.value === 3) {
newHash = event.data.content;
oldHash = true;
lockId = 'cm';
} else {
// Don't lock on enter.
if (0 === event.charCode) {
return;
}
lockId = $(this).data('lock-id');
if (typeof lockId === 'undefined') {
return;
}
/*
* @todo Fix Code mirror does not give correct full value (query)
* in textarea, it returns only the change in content.
*/
if (event.data.value === 1) {
newHash = AJAX.hash($(this).val());
} else {
newHash = AJAX.hash($(this).is(':checked'));
}
oldHash = $(this).data('val-hash');
}
// Set lock if old value !== new value
// otherwise release lock
if (oldHash !== newHash) {
AJAX.lockedTargets[lockId] = true;
} else {
delete AJAX.lockedTargets[lockId];
}
// Show lock icon if locked targets is not empty.
// otherwise remove lock icon
if (!jQuery.isEmptyObject(AJAX.lockedTargets)) {
$('#lock_page_icon').html(Functions.getImage('s_lock', Messages.strLockToolTip).toString());
} else {
$('#lock_page_icon').html('');
}
},
/**
* resets the lock
*
* @return {void}
*/
resetLock: function () {
AJAX.lockedTargets = {};
$('#lock_page_icon').html('');
},
handleMenu: {
replace: function (content) {
$('#floating_menubar').html(content)
// Remove duplicate wrapper
// TODO: don't send it in the response
.children().first().remove();
$('#topmenu').menuResizer(Functions.mainMenuResizerCallback);
}
},
/**
* Event handler for clicks on links and form submissions
*
* @param {KeyboardEvent} event Event data
*
* @return {boolean | void}
*/
requestHandler: function (event) {
// In some cases we don't want to handle the request here and either
// leave the browser deal with it natively (e.g: file download)
// or leave an existing ajax event handler present elsewhere deal with it
var href = $(this).attr('href');
if (typeof event !== 'undefined' && (event.shiftKey || event.ctrlKey || event.metaKey)) {
return true;
} else if ($(this).attr('target')) {
return true;
} else if ($(this).hasClass('ajax') || $(this).hasClass('disableAjax')) {
// reset the lockedTargets object, as specified AJAX operation has finished
AJAX.resetLock();
return true;
} else if (href && href.match(/^#/)) {
return true;
} else if (href && href.match(/^mailto/)) {
return true;
} else if ($(this).hasClass('ui-datepicker-next') || $(this).hasClass('ui-datepicker-prev')) {
return true;
}
if (typeof event !== 'undefined') {
event.preventDefault();
event.stopImmediatePropagation();
}
// triggers a confirm dialog if:
// the user has performed some operations on loaded page
// the user clicks on some link, (won't trigger for buttons)
// the click event is not triggered by script
if (typeof event !== 'undefined' && event.type === 'click' && event.isTrigger !== true && !jQuery.isEmptyObject(AJAX.lockedTargets) && confirm(Messages.strConfirmNavigation) === false) {
return false;
}
AJAX.resetLock();
var isLink = !!href || false;
var previousLinkAborted = false;
if (AJAX.active === true) {
// Cancel the old request if abortable, when the user requests
// something else. Otherwise silently bail out, as there is already
// a request well in progress.
if (AJAX.xhr) {
// In case of a link request, attempt aborting
AJAX.xhr.abort();
if (AJAX.xhr.status === 0 && AJAX.xhr.statusText === 'abort') {
// If aborted
AJAX.$msgbox = Functions.ajaxShowMessage(Messages.strAbortedRequest);
AJAX.active = false;
AJAX.xhr = null;
previousLinkAborted = true;
} else {
// If can't abort
return false;
}
} else {
// In case submitting a form, don't attempt aborting
return false;
}
}
AJAX.source = $(this);
$('html, body').animate({
scrollTop: 0
}, 'fast');
var url = isLink ? href : $(this).attr('action');
var argsep = CommonParams.get('arg_separator');
var params = 'ajax_request=true' + argsep + 'ajax_page_request=true';
var dataPost = AJAX.source.getPostData();
if (!isLink) {
params += argsep + $(this).serialize();
} else if (dataPost) {
params += argsep + dataPost;
isLink = false;
}
if (AJAX.debug) {
// eslint-disable-next-line no-console
console.log('Loading: ' + url); // no need to translate
}
if (isLink) {
AJAX.active = true;
AJAX.$msgbox = Functions.ajaxShowMessage();
// Save reference for the new link request
AJAX.xhr = $.get(url, params, AJAX.responseHandler);
var state = {
url: href
};
if (previousLinkAborted) {
// hack: there is already an aborted entry on stack
// so just modify the aborted one
history.replaceState(state, null, href);
} else {
history.pushState(state, null, href);
}
} else {
/**
* Manually fire the onsubmit event for the form, if any.
* The event was saved in the jQuery data object by an onload
* handler defined below. Workaround for bug #3583316
*/
var onsubmit = $(this).data('onsubmit');
// Submit the request if there is no onsubmit handler
// or if it returns a value that evaluates to true
if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) {
AJAX.active = true;
AJAX.$msgbox = Functions.ajaxShowMessage();
if ($(this).attr('id') === 'login_form') {
$.post(url, params, AJAX.loginResponseHandler);
} else {
$.post(url, params, AJAX.responseHandler);
}
}
}
},
/**
* Response handler to handle login request from login modal after session expiration
*
* To refer to self use 'AJAX', instead of 'this' as this function
* is called in the jQuery context.
*
* @param {object} data Event data
*
* @return {void}
*/
loginResponseHandler: function (data) {
if (typeof data === 'undefined' || data === null) {
return;
}
Functions.ajaxRemoveMessage(AJAX.$msgbox);
CommonParams.set('token', data.new_token);
AJAX.scriptHandler.load([]);
if (data.displayMessage) {
$('#page_content').prepend(data.displayMessage);
Functions.highlightSql($('#page_content'));
}
$('#pma_errors').remove();
var msg = '';
if (data.errSubmitMsg) {
msg = data.errSubmitMsg;
}
if (data.errors) {
$('<div></div>', {
id: 'pma_errors',
class: 'clearfloat d-print-none'
}).insertAfter('#selflink').append(data.errors);
// bind for php error reporting forms (bottom)
$('#pma_ignore_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors(false);
});
// In case of 'sendErrorReport'='always'
// submit the hidden error reporting form.
if (data.sendErrorAlways === '1' && data.stopErrorReportLoop !== '1') {
$('#pma_report_errors_form').trigger('submit');
Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false);
$('html, body').animate({
scrollTop: $(document).height()
}, 'slow');
} else if (data.promptPhpErrors) {
// otherwise just prompt user if it is set so.
msg = msg + Messages.phpErrorsFound;
// scroll to bottom where all the errors are displayed.
$('html, body').animate({
scrollTop: $(document).height()
}, 'slow');
}
}
Functions.ajaxShowMessage(msg, false);
// bind for php error reporting forms (popup)
$('#pma_ignore_errors_popup').on('click', function () {
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_popup').on('click', function () {
Functions.ignorePhpErrors(false);
});
if (typeof data.success !== 'undefined' && data.success) {
// reload page if user trying to login has changed
if (CommonParams.get('user') !== data.params.user) {
window.location = 'index.php';
Functions.ajaxShowMessage(Messages.strLoading, false);
AJAX.active = false;
AJAX.xhr = null;
return;
}
// remove the login modal if the login is successful otherwise show error.
if (typeof data.logged_in !== 'undefined' && data.logged_in === 1) {
if ($('#modalOverlay').length) {
$('#modalOverlay').remove();
}
$('fieldset.disabled_for_expiration').removeAttr('disabled').removeClass('disabled_for_expiration');
AJAX.fireTeardown('functions.js');
AJAX.fireOnload('functions.js');
}
if (typeof data.new_token !== 'undefined') {
$('input[name=token]').val(data.new_token);
}
} else if (typeof data.logged_in !== 'undefined' && data.logged_in === 0) {
$('#modalOverlay').replaceWith(data.error);
} else {
Functions.ajaxShowMessage(data.error, false);
AJAX.active = false;
AJAX.xhr = null;
Functions.handleRedirectAndReload(data);
if (data.fieldWithError) {
$(':input.error').removeClass('error');
$('#' + data.fieldWithError).addClass('error');
}
}
},
/**
* Called after the request that was initiated by this.requestHandler()
* has completed successfully or with a caught error. For completely
* failed requests or requests with uncaught errors, see the .ajaxError
* handler at the bottom of this file.
*
* To refer to self use 'AJAX', instead of 'this' as this function
* is called in the jQuery context.
*
* @param {object} data Event data
*
* @return {void}
*/
responseHandler: function (data) {
if (typeof data === 'undefined' || data === null) {
return;
}
// Can be a string when an error occurred and only HTML was returned.
if (typeof data === 'string') {
Functions.ajaxRemoveMessage(AJAX.$msgbox);
Functions.ajaxShowMessage($(data).text(), false, 'error');
AJAX.active = false;
AJAX.xhr = null;
return;
}
if (typeof data.success !== 'undefined' && data.success) {
$('html, body').animate({
scrollTop: 0
}, 'fast');
Functions.ajaxRemoveMessage(AJAX.$msgbox);
if (data.redirect) {
Functions.ajaxShowMessage(data.redirect, false);
AJAX.active = false;
AJAX.xhr = null;
return;
}
AJAX.scriptHandler.reset(function () {
if (data.reloadNavigation) {
Navigation.reload();
}
if (data.title) {
$('title').replaceWith(data.title);
}
if (data.menu) {
var state = {
url: data.selflink,
menu: data.menu
};
history.replaceState(state, null);
AJAX.handleMenu.replace(data.menu);
}
if (data.disableNaviSettings) {
Navigation.disableSettings();
} else {
Navigation.ensureSettings(data.selflink);
}
// Remove all containers that may have
// been added outside of #page_content
$('body').children().not('div.modal').not('#pma_navigation').not('#floating_menubar').not('#page_nav_icons').not('#page_content').not('#selflink').not('#pma_header').not('#pma_footer').not('#pma_demo').not('#pma_console_container').not('#prefs_autoload').remove();
// Replace #page_content with new content
if (data.message && data.message.length > 0) {
$('#page_content').replaceWith('<div id=\'page_content\'>' + data.message + '</div>');
Functions.highlightSql($('#page_content'));
Functions.checkNumberOfFields();
}
if (data.selflink) {
var source = data.selflink.split('?')[0];
// Check for faulty links
var $selflinkReplace = {
'index.php?route=/import': 'index.php?route=/table/sql',
'index.php?route=/table/chart': 'index.php?route=/sql',
'index.php?route=/table/gis-visualization': 'index.php?route=/sql'
};
if ($selflinkReplace[source]) {
var replacement = $selflinkReplace[source];
data.selflink = data.selflink.replace(source, replacement);
}
$('#selflink').find('> a').attr('href', data.selflink);
}
if (data.params) {
CommonParams.setAll(data.params);
}
if (data.scripts) {
AJAX.scriptHandler.load(data.scripts);
}
if (data.displayMessage) {
$('#page_content').prepend(data.displayMessage);
Functions.highlightSql($('#page_content'));
}
$('#pma_errors').remove();
var msg = '';
if (data.errSubmitMsg) {
msg = data.errSubmitMsg;
}
if (data.errors) {
$('<div></div>', {
id: 'pma_errors',
class: 'clearfloat d-print-none'
}).insertAfter('#selflink').append(data.errors);
// bind for php error reporting forms (bottom)
$('#pma_ignore_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors(false);
});
// In case of 'sendErrorReport'='always'
// submit the hidden error reporting form.
if (data.sendErrorAlways === '1' && data.stopErrorReportLoop !== '1') {
$('#pma_report_errors_form').trigger('submit');
Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false);
$('html, body').animate({
scrollTop: $(document).height()
}, 'slow');
} else if (data.promptPhpErrors) {
// otherwise just prompt user if it is set so.
msg = msg + Messages.phpErrorsFound;
// scroll to bottom where all the errors are displayed.
$('html, body').animate({
scrollTop: $(document).height()
}, 'slow');
}
}
Functions.ajaxShowMessage(msg, false);
// bind for php error reporting forms (popup)
$('#pma_ignore_errors_popup').on('click', function () {
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_popup').on('click', function () {
Functions.ignorePhpErrors(false);
});
if (typeof AJAX.callback === 'function') {
AJAX.callback.call();
}
AJAX.callback = function () {};
});
} else {
Functions.ajaxShowMessage(data.error, false);
Functions.ajaxRemoveMessage(AJAX.$msgbox);
var $ajaxError = $('<div></div>');
$ajaxError.attr({
'id': 'ajaxError'
});
$('#page_content').append($ajaxError);
$ajaxError.html(data.error);
$('html, body').animate({
scrollTop: $(document).height()
}, 200);
AJAX.active = false;
AJAX.xhr = null;
Functions.handleRedirectAndReload(data);
if (data.fieldWithError) {
$(':input.error').removeClass('error');
$('#' + data.fieldWithError).addClass('error');
}
}
},
/**
* This object is in charge of downloading scripts,
* keeping track of what's downloaded and firing
* the onload event for them when the page is ready.
*/
scriptHandler: {
/**
* @var {string[]} scripts The list of files already downloaded
*/
scripts: [],
/**
* @var {string} scriptsVersion version of phpMyAdmin from which the
* scripts have been loaded
*/
scriptsVersion: null,
/**
* @var {string[]} scriptsToBeLoaded The list of files that
* need to be downloaded
*/
scriptsToBeLoaded: [],
/**
* @var {string[]} scriptsToBeFired The list of files for which
* to fire the onload and unload events
*/
scriptsToBeFired: [],
scriptsCompleted: false,
/**
* Records that a file has been downloaded
*
* @param {string} file The filename
* @param {string} fire Whether this file will be registering
* onload/teardown events
*
* @return {self} For chaining
*/
add: function (file, fire) {
this.scripts.push(file);
if (fire) {
// Record whether to fire any events for the file
// This is necessary to correctly tear down the initial page
this.scriptsToBeFired.push(file);
}
return this;
},
/**
* Download a list of js files in one request
*
* @param {string[]} files An array of filenames and flags
* @param {Function} callback
*
* @return {void}
*/
load: function (files, callback) {
var self = this;
var i;
// Clear loaded scripts if they are from another version of phpMyAdmin.
// Depends on common params being set before loading scripts in responseHandler
if (self.scriptsVersion === null) {
self.scriptsVersion = CommonParams.get('version');
} else if (self.scriptsVersion !== CommonParams.get('version')) {
self.scripts = [];
self.scriptsVersion = CommonParams.get('version');
}
self.scriptsCompleted = false;
self.scriptsToBeFired = [];
// We need to first complete list of files to load
// as next loop will directly fire requests to load them
// and that triggers removal of them from
// self.scriptsToBeLoaded
for (i in files) {
self.scriptsToBeLoaded.push(files[i].name);
if (files[i].fire) {
self.scriptsToBeFired.push(files[i].name);
}
}
for (i in files) {
var script = files[i].name;
// Only for scripts that we don't already have
if ($.inArray(script, self.scripts) === -1) {
this.add(script);
this.appendScript(script, callback);
} else {
self.done(script, callback);
}
}
// Trigger callback if there is nothing else to load
self.done(null, callback);
},
/**
* Called whenever all files are loaded
*
* @param {string} script
* @param {Function?} callback
*
* @return {void}
*/
done: function (script, callback) {
if ($.inArray(script, this.scriptsToBeFired)) {
AJAX.fireOnload(script);
}
if ($.inArray(script, this.scriptsToBeLoaded)) {
this.scriptsToBeLoaded.splice($.inArray(script, this.scriptsToBeLoaded), 1);
}
if (script === null) {
this.scriptsCompleted = true;
}
/* We need to wait for last signal (with null) or last script load */
AJAX.active = this.scriptsToBeLoaded.length > 0 || !this.scriptsCompleted;
/* Run callback on last script */
if (!AJAX.active && typeof callback === 'function') {
callback();
}
},
/**
* Appends a script element to the head to load the scripts
*
* @param {string} name
* @param {Function} callback
*
* @return {void}
*/
appendScript: function (name, callback) {
var head = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement('script');
var self = this;
script.type = 'text/javascript';
var file = name.indexOf('vendor/') !== -1 ? name : 'dist/' + name;
script.src = 'js/' + file + '?' + 'v=' + encodeURIComponent(CommonParams.get('version'));
script.async = false;
script.onload = function () {
self.done(name, callback);
};
head.appendChild(script);
},
/**
* Fires all the teardown event handlers for the current page
* and rebinds all forms and links to the request handler
*
* @param {Function} callback The callback to call after resetting
*
* @return {void}
*/
reset: function (callback) {
for (var i in this.scriptsToBeFired) {
AJAX.fireTeardown(this.scriptsToBeFired[i]);
}
this.scriptsToBeFired = [];
/**
* Re-attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).off('click', 'a').on('click', 'a', AJAX.requestHandler);
$(document).off('submit', 'form').on('submit', 'form', AJAX.requestHandler);
callback();
}
}
};
/**
* Here we register a function that will remove the onsubmit event from all
* forms that will be handled by the generic page loader. We then save this
* event handler in the "jQuery data", so that we can fire it up later in
* AJAX.requestHandler().
*
* See bug #3583316
*/
AJAX.registerOnload('functions.js', function () {
// Registering the onload event for functions.js
// ensures that it will be fired for all pages
$('form').not('.ajax').not('.disableAjax').each(function () {
if ($(this).attr('onsubmit')) {
$(this).data('onsubmit', this.onsubmit).attr('onsubmit', '');
}
});
var $pageContent = $('#page_content');
/**
* Workaround for passing submit button name,value on ajax form submit
* by appending hidden element with submit button name and value.
*/
$pageContent.on('click', 'form input[type=submit]', function () {
var buttonName = $(this).attr('name');
if (typeof buttonName === 'undefined') {
return;
}
$(this).closest('form').append($('<input>', {
'type': 'hidden',
'name': buttonName,
'value': $(this).val()
}));
});
/**
* Attach event listener to events when user modify visible
* Input,Textarea and select fields to make changes in forms
*/
$pageContent.on('keyup change', 'form.lock-page textarea, ' + 'form.lock-page input[type="text"], ' + 'form.lock-page input[type="number"], ' + 'form.lock-page select', {
value: 1
}, AJAX.lockPageHandler);
$pageContent.on('change', 'form.lock-page input[type="checkbox"], ' + 'form.lock-page input[type="radio"]', {
value: 2
}, AJAX.lockPageHandler);
/**
* Reset lock when lock-page form reset event is fired
* Note: reset does not bubble in all browser so attach to
* form directly.
*/
$('form.lock-page').on('reset', function () {
AJAX.resetLock();
});
});
/**
* Page load event handler
*/
$(function () {
var menuContent = $('<div></div>').append($('#server-breadcrumb').clone()).append($('#topmenucontainer').clone()).html();
// set initial state reload
var initState = 'state' in window.history && window.history.state !== null;
var initURL = $('#selflink').find('> a').attr('href') || location.href;
var state = {
url: initURL,
menu: menuContent
};
history.replaceState(state, null);
$(window).on('popstate', function (event) {
var initPop = !initState && location.href === initURL;
initState = true;
// check if popstate fired on first page itself
if (initPop) {
return;
}
var state = event.originalEvent.state;
if (state && state.menu) {
AJAX.$msgbox = Functions.ajaxShowMessage();
var params = 'ajax_request=true' + CommonParams.get('arg_separator') + 'ajax_page_request=true';
var url = state.url || location.href;
$.get(url, params, AJAX.responseHandler);
// TODO: Check if sometimes menu is not retrieved from server,
// Not sure but it seems menu was missing only for printview which
// been removed lately, so if it's right some dead menu checks/fallbacks
// may need to be removed from this file and Header.php
// AJAX.handleMenu.replace(event.originalEvent.state.menu);
}
});
});
/**
* Attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).on('click', 'a', AJAX.requestHandler);
$(document).on('submit', 'form', AJAX.requestHandler);
/**
* Gracefully handle fatal server errors
* (e.g: 500 - Internal server error)
*/
$(document).on('ajaxError', function (event, request) {
if (AJAX.debug) {
// eslint-disable-next-line no-console
console.log('AJAX error: status=' + request.status + ', text=' + request.statusText);
}
// Don't handle aborted requests
if (request.status !== 0 || request.statusText !== 'abort') {
var details = '';
var state = request.state();
if (request.status !== 0) {
details += '<div>' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorCode, request.status)) + '</div>';
}
details += '<div>' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorText, request.statusText + ' (' + state + ')')) + '</div>';
if (state === 'rejected' || state === 'timeout') {
details += '<div>' + Functions.escapeHtml(Messages.strErrorConnection) + '</div>';
}
Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert">' + Messages.strErrorProcessingRequest + details + '</div>', false);
AJAX.active = false;
AJAX.xhr = null;
}
});

View file

@ -1,656 +0,0 @@
/**
* Chart type enumerations
*/
var ChartType = {
LINE: 'line',
SPLINE: 'spline',
AREA: 'area',
BAR: 'bar',
COLUMN: 'column',
PIE: 'pie',
TIMELINE: 'timeline',
SCATTER: 'scatter'
};
/**
* Column type enumeration
*/
var ColumnType = {
STRING: 'string',
NUMBER: 'number',
BOOLEAN: 'boolean',
DATE: 'date'
};
/**
* Abstract chart factory which defines the contract for chart factories
*/
var ChartFactory = function () {};
ChartFactory.prototype = {
createChart: function () {
throw new Error('createChart must be implemented by a subclass');
}
};
/**
* Abstract chart which defines the contract for charts
*
* @param elementId
* id of the div element the chart is drawn in
*/
var Chart = function (elementId) {
this.elementId = elementId;
};
Chart.prototype = {
draw: function () {
throw new Error('draw must be implemented by a subclass');
},
redraw: function () {
throw new Error('redraw must be implemented by a subclass');
},
destroy: function () {
throw new Error('destroy must be implemented by a subclass');
},
toImageString: function () {
throw new Error('toImageString must be implemented by a subclass');
}
};
/**
* Abstract representation of charts that operates on DataTable where,<br>
* <ul>
* <li>First column provides index to the data.</li>
* <li>Each subsequent columns are of type
* <code>ColumnType.NUMBER<code> and represents a data series.</li>
* </ul>
* Line chart, area chart, bar chart, column chart are typical examples.
*
* @param elementId
* id of the div element the chart is drawn in
*/
var BaseChart = function (elementId) {
Chart.call(this, elementId);
};
BaseChart.prototype = new Chart();
BaseChart.prototype.constructor = BaseChart;
BaseChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length < 2) {
throw new Error('Minimum of two columns are required for this chart');
}
for (var i = 1; i < columns.length; i++) {
if (columns[i].type !== ColumnType.NUMBER) {
throw new Error('Column ' + (i + 1) + ' should be of type \'Number\'');
}
}
return true;
};
/**
* Abstract pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var PieChart = function (elementId) {
BaseChart.call(this, elementId);
};
PieChart.prototype = new BaseChart();
PieChart.prototype.constructor = PieChart;
PieChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length > 2) {
throw new Error('Pie charts can draw only one series');
}
return BaseChart.prototype.validateColumns.call(this, dataTable);
};
/**
* Abstract timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var TimelineChart = function (elementId) {
BaseChart.call(this, elementId);
};
TimelineChart.prototype = new BaseChart();
TimelineChart.prototype.constructor = TimelineChart;
TimelineChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.DATE) {
throw new Error('First column of timeline chart need to be a date column');
}
}
return result;
};
/**
* Abstract scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var ScatterChart = function (elementId) {
BaseChart.call(this, elementId);
};
ScatterChart.prototype = new BaseChart();
ScatterChart.prototype.constructor = ScatterChart;
ScatterChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.NUMBER) {
throw new Error('First column of scatter chart need to be a numeric column');
}
}
return result;
};
/**
* The data table contains column information and data for the chart.
*/
// eslint-disable-next-line no-unused-vars
var DataTable = function () {
var columns = [];
var data = null;
this.addColumn = function (type, name) {
columns.push({
'type': type,
'name': name
});
};
this.getColumns = function () {
return columns;
};
this.setData = function (rows) {
data = rows;
fillMissingValues();
};
this.getData = function () {
return data;
};
var fillMissingValues = function () {
if (columns.length === 0) {
throw new Error('Set columns first');
}
var row;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row.length > columns.length) {
row.splice(columns.length - 1, row.length - columns.length);
} else if (row.length < columns.length) {
for (var j = row.length; j < columns.length; j++) {
row.push(null);
}
}
}
};
};
/** *****************************************************************************
* JQPlot specific code
******************************************************************************/
/**
* Abstract JQplot chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotChart = function (elementId) {
Chart.call(this, elementId);
this.plot = null;
this.validator = null;
};
JQPlotChart.prototype = new Chart();
JQPlotChart.prototype.constructor = JQPlotChart;
JQPlotChart.prototype.draw = function (data, options) {
if (this.validator.validateColumns(data)) {
this.plot = $.jqplot(this.elementId, this.prepareData(data), this.populateOptions(data, options));
}
};
JQPlotChart.prototype.destroy = function () {
if (this.plot !== null) {
this.plot.destroy();
}
};
JQPlotChart.prototype.redraw = function (options) {
if (this.plot !== null) {
this.plot.replot(options);
}
};
JQPlotChart.prototype.toImageString = function () {
if (this.plot !== null) {
return $('#' + this.elementId).jqplotToImageStr({});
}
};
JQPlotChart.prototype.populateOptions = function () {
throw new Error('populateOptions must be implemented by a subclass');
};
JQPlotChart.prototype.prepareData = function () {
throw new Error('prepareData must be implemented by a subclass');
};
/**
* JQPlot line chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotLineChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = BaseChart.prototype;
};
JQPlotLineChart.prototype = new JQPlotChart();
JQPlotLineChart.prototype.constructor = JQPlotLineChart;
JQPlotLineChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes: {
xaxis: {
label: columns[0].name,
renderer: $.jqplot.CategoryAxisRenderer,
ticks: []
},
yaxis: {
label: columns.length === 2 ? columns[1].name : 'Values',
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'y',
formatString: '%d'
},
series: []
};
$.extend(true, optional, options);
if (optional.series.length === 0) {
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label: columns[i].name.toString()
});
}
}
if (optional.axes.xaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var j = 0; j < data.length; j++) {
optional.axes.xaxis.ticks.push(data[j][0].toString());
}
}
return optional;
};
JQPlotLineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push(row[j]);
}
}
return retData;
};
/**
* JQPlot spline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotSplineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotSplineChart.prototype = new JQPlotLineChart();
JQPlotSplineChart.prototype.constructor = JQPlotSplineChart;
JQPlotSplineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
var compulsory = {
seriesDefaults: {
rendererOptions: {
smooth: true
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotScatterChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = ScatterChart.prototype;
};
JQPlotScatterChart.prototype = new JQPlotChart();
JQPlotScatterChart.prototype.constructor = JQPlotScatterChart;
JQPlotScatterChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes: {
xaxis: {
label: columns[0].name
},
yaxis: {
label: columns.length === 2 ? columns[1].name : 'Values',
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString: '%d, %d'
},
series: []
};
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label: columns[i].name.toString()
});
}
var compulsory = {
seriesDefaults: {
showLine: false,
markerOptions: {
size: 7,
style: 'x'
}
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotScatterChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row[0]) {
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push([row[0], row[j]]);
}
}
}
return retData;
};
/**
* JQPlot timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotTimelineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
this.validator = TimelineChart.prototype;
};
JQPlotTimelineChart.prototype = new JQPlotLineChart();
JQPlotTimelineChart.prototype.constructor = JQPlotTimelineChart;
JQPlotTimelineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
axes: {
xaxis: {
tickOptions: {
formatString: '%b %#d, %y'
}
}
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
var compulsory = {
axes: {
xaxis: {
renderer: $.jqplot.DateAxisRenderer
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
JQPlotTimelineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var d;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
d = row[0];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
// See https://github.com/phpmyadmin/phpmyadmin/issues/14395 for the block
if (d !== null && typeof d === 'object') {
retRow.push([d.getTime(), row[j]]);
} else if (typeof d === 'string') {
d = new Date(d);
retRow.push([d.getTime(), row[j]]);
}
}
}
return retData;
};
/**
* JQPlot area chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotAreaChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotAreaChart.prototype = new JQPlotLineChart();
JQPlotAreaChart.prototype.constructor = JQPlotAreaChart;
JQPlotAreaChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults: {
fillToZero: true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
var compulsory = {
seriesDefaults: {
fill: true
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot column chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotColumnChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotColumnChart.prototype = new JQPlotLineChart();
JQPlotColumnChart.prototype.constructor = JQPlotColumnChart;
JQPlotColumnChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults: {
fillToZero: true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
var compulsory = {
seriesDefaults: {
renderer: $.jqplot.BarRenderer
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot bar chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotBarChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotBarChart.prototype = new JQPlotLineChart();
JQPlotBarChart.prototype.constructor = JQPlotBarChart;
JQPlotBarChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes: {
yaxis: {
label: columns[0].name,
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
renderer: $.jqplot.CategoryAxisRenderer,
ticks: []
},
xaxis: {
label: columns.length === 2 ? columns[1].name : 'Values',
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'x',
formatString: '%d'
},
series: [],
seriesDefaults: {
fillToZero: true
}
};
var compulsory = {
seriesDefaults: {
renderer: $.jqplot.BarRenderer,
rendererOptions: {
barDirection: 'horizontal'
}
}
};
$.extend(true, optional, options, compulsory);
if (optional.axes.yaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var i = 0; i < data.length; i++) {
optional.axes.yaxis.ticks.push(data[i][0].toString());
}
}
if (optional.series.length === 0) {
for (var j = 1; j < columns.length; j++) {
optional.series.push({
label: columns[j].name.toString()
});
}
}
return optional;
};
/**
* JQPlot pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotPieChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = PieChart.prototype;
};
JQPlotPieChart.prototype = new JQPlotChart();
JQPlotPieChart.prototype.constructor = JQPlotPieChart;
JQPlotPieChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString: '%s, %d',
useAxesFormatters: false
},
legend: {
renderer: $.jqplot.EnhancedPieLegendRenderer
}
};
var compulsory = {
seriesDefaults: {
shadow: false,
renderer: $.jqplot.PieRenderer,
rendererOptions: {
sliceMargin: 1,
showDataLabels: true
}
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotPieChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
for (var i = 0; i < data.length; i++) {
row = data[i];
retData.push([row[0], row[1]]);
}
return [retData];
};
/**
* Chart factory that returns JQPlotCharts
*/
var JQPlotChartFactory = function () {};
JQPlotChartFactory.prototype = new ChartFactory();
JQPlotChartFactory.prototype.createChart = function (type, elementId) {
var chart = null;
switch (type) {
case ChartType.LINE:
chart = new JQPlotLineChart(elementId);
break;
case ChartType.SPLINE:
chart = new JQPlotSplineChart(elementId);
break;
case ChartType.TIMELINE:
chart = new JQPlotTimelineChart(elementId);
break;
case ChartType.AREA:
chart = new JQPlotAreaChart(elementId);
break;
case ChartType.BAR:
chart = new JQPlotBarChart(elementId);
break;
case ChartType.COLUMN:
chart = new JQPlotColumnChart(elementId);
break;
case ChartType.PIE:
chart = new JQPlotPieChart(elementId);
break;
case ChartType.SCATTER:
chart = new JQPlotScatterChart(elementId);
break;
}
return chart;
};

View file

@ -1,33 +0,0 @@
CodeMirror.sqlLint = function (text, updateLinting, options, cm) {
// Skipping check if text box is empty.
if (text.trim() === '') {
updateLinting(cm, []);
return;
}
function handleResponse(response) {
var found = [];
for (var idx in response) {
found.push({
// eslint-disable-next-line new-cap
from: CodeMirror.Pos(response[idx].fromLine, response[idx].fromColumn),
// eslint-disable-next-line new-cap
to: CodeMirror.Pos(response[idx].toLine, response[idx].toColumn),
messageHTML: response[idx].message,
severity: response[idx].severity
});
}
updateLinting(cm, found);
}
$.ajax({
method: 'POST',
url: 'index.php?route=/lint',
dataType: 'json',
data: {
'sql_query': text,
'server': CommonParams.get('server'),
'options': options.lintOptions,
'no_history': true
},
success: handleResponse
});
};

View file

@ -1,157 +0,0 @@
$(function () {
Functions.checkNumberOfFields();
});
/**
* Holds common parameters such as server, db, table, etc
*
* The content for this is normally loaded from Header.php or
* Response.php and executed by ajax.js
*
* @test-module CommonParams
*/
var CommonParams = function () {
/**
* @var {Object} params An associative array of key value pairs
* @access private
*/
var params = {};
// The returned object is the public part of the module
return {
/**
* Saves all the key value pair that
* are provided in the input array
*
* @param obj hash The input array
*
* @return {void}
*/
setAll: function (obj) {
var updateNavigation = false;
for (var i in obj) {
if (params[i] !== undefined && params[i] !== obj[i]) {
if (i === 'db' || i === 'table') {
updateNavigation = true;
}
}
params[i] = obj[i];
}
if (updateNavigation && $('#pma_navigation_tree').hasClass('synced')) {
Navigation.showCurrent();
}
},
/**
* Retrieves a value given its key
* Returns empty string for undefined values
*
* @param {string} name The key
*
* @return {string}
*/
get: function (name) {
return params[name];
},
/**
* Saves a single key value pair
*
* @param {string} name The key
* @param {string} value The value
*
* @return {CommonParams} For chainability
*/
set: function (name, value) {
var updateNavigation = false;
if (name === 'db' || name === 'table' && params[name] !== value) {
updateNavigation = true;
}
params[name] = value;
if (updateNavigation && $('#pma_navigation_tree').hasClass('synced')) {
Navigation.showCurrent();
}
return this;
},
/**
* Returns the url query string using the saved parameters
*
* @param {string} separator New separator
*
* @return {string}
*/
getUrlQuery: function (separator) {
var sep = typeof separator !== 'undefined' ? separator : '?';
var common = this.get('common_query');
var argsep = CommonParams.get('arg_separator');
if (typeof common === 'string' && common.length > 0) {
// If the last char is the separator, do not add it
// Else add it
common = common.substr(common.length - 1, common.length) === argsep ? common : common + argsep;
}
return Functions.sprintf('%s%sserver=%s' + argsep + 'db=%s' + argsep + 'table=%s', sep, common, encodeURIComponent(this.get('server')), encodeURIComponent(this.get('db')), encodeURIComponent(this.get('table')));
}
};
}();
/**
* Holds common parameters such as server, db, table, etc
*
* The content for this is normally loaded from Header.php or
* Response.php and executed by ajax.js
*/
// eslint-disable-next-line no-unused-vars
var CommonActions = {
/**
* Saves the database name when it's changed
* and reloads the query window, if necessary
*
* @param {string} newDb new_db The name of the new database
*
* @return {void}
*/
setDb: function (newDb) {
if (newDb !== CommonParams.get('db')) {
CommonParams.setAll({
'db': newDb,
'table': ''
});
}
},
/**
* Opens a database in the main part of the page
*
* @param {string} newDb The name of the new database
*
* @return {void}
*/
openDb: function (newDb) {
CommonParams.set('db', newDb).set('table', '');
this.refreshMain(CommonParams.get('opendb_url'));
},
/**
* Refreshes the main frame
*
* @param {any} url Undefined to refresh to the same page
* String to go to a different page, e.g: 'index.php'
* @param {function | undefined} callback
*
* @return {void}
*/
refreshMain: function (url) {
let callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
var newUrl = url;
if (!newUrl) {
newUrl = $('#selflink').find('a').attr('href') || window.location.pathname;
newUrl = newUrl.substring(0, newUrl.indexOf('?'));
}
if (newUrl.indexOf('?') !== -1) {
newUrl += CommonParams.getUrlQuery(CommonParams.get('arg_separator'));
} else {
newUrl += CommonParams.getUrlQuery('?');
}
$('<a></a>', {
href: newUrl
}).appendTo('body').trigger('click').remove();
if (typeof callback !== 'undefined') {
AJAX.callback = callback;
}
}
};

View file

@ -1,835 +0,0 @@
/**
* Functions used in configuration forms and on user preferences pages
*/
/* exported PASSIVE_EVENT_LISTENERS */
var configInlineParams;
var configScriptLoaded;
/**
* checks whether browser supports web storage
*
* @param {'localStorage' | 'sessionStorage'} type the type of storage i.e. localStorage or sessionStorage
* @param {boolean} warn Wether to show a warning on error
*
* @return {boolean}
*/
function isStorageSupported(type) {
let warn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
try {
window[type].setItem('PMATest', 'test');
// Check whether key-value pair was set successfully
if (window[type].getItem('PMATest') === 'test') {
// Supported, remove test variable from storage
window[type].removeItem('PMATest');
return true;
}
} catch (error) {
// Not supported
if (warn) {
Functions.ajaxShowMessage(Messages.strNoLocalStorage, false);
}
}
return false;
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('config.js', function () {
$('.optbox input[id], .optbox select[id], .optbox textarea[id]').off('change').off('keyup');
$('.optbox input[type=button][name=submit_reset]').off('click');
$('div.tab-content').off();
$('#import_local_storage, #export_local_storage').off('click');
$('form.prefs-form').off('change').off('submit');
$(document).off('click', 'div.click-hide-message');
$('#prefs_autoload').find('a').off('click');
});
AJAX.registerOnload('config.js', function () {
var $topmenuUpt = $('#user_prefs_tabs');
$topmenuUpt.find('a.active').attr('rel', 'samepage');
$topmenuUpt.find('a:not(.active)').attr('rel', 'newpage');
});
// default values for fields
var defaultValues = {};
/**
* Returns field type
*
* @param {Element} field
*
* @return {string}
*/
function getFieldType(field) {
var $field = $(field);
var tagName = $field.prop('tagName');
if (tagName === 'INPUT') {
return $field.attr('type');
} else if (tagName === 'SELECT') {
return 'select';
} else if (tagName === 'TEXTAREA') {
return 'text';
}
return '';
}
/**
* Enables or disables the "restore default value" button
*
* @param {Element} field
* @param {boolean} display
*
* @return {void}
*/
function setRestoreDefaultBtn(field, display) {
var $el = $(field).closest('td').find('.restore-default img');
$el[display ? 'show' : 'hide']();
}
/**
* Marks field depending on its value (system default or custom)
*
* @param {Element | JQuery<Element>} field
*
* @return {void}
*/
function markField(field) {
var $field = $(field);
var type = getFieldType($field);
var isDefault = checkFieldDefault($field, type);
// checkboxes uses parent <span> for marking
var $fieldMarker = type === 'checkbox' ? $field.parent() : $field;
setRestoreDefaultBtn($field, !isDefault);
$fieldMarker[isDefault ? 'removeClass' : 'addClass']('custom');
}
/**
* Sets field value
*
* value must be of type:
* o undefined (omitted) - restore default value (form default, not PMA default)
* o String - if field_type is 'text'
* o boolean - if field_type is 'checkbox'
* o Array of values - if field_type is 'select'
*
* @param {Element} field
* @param {string} fieldType see {@link #getFieldType}
* @param {string | boolean} value
*/
function setFieldValue(field, fieldType, value) {
var $field = $(field);
switch (fieldType) {
case 'text':
case 'number':
$field.val(value);
break;
case 'checkbox':
$field.prop('checked', value);
break;
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
for (i = 0; i < imax; i++) {
options[i].selected = value.indexOf(options[i].value) !== -1;
}
break;
}
markField($field);
}
/**
* Gets field value
*
* Will return one of:
* o String - if type is 'text'
* o boolean - if type is 'checkbox'
* o Array of values - if type is 'select'
*
* @param {Element} field
* @param {string} fieldType returned by {@link #getFieldType}
*
* @return {boolean | string | string[] | null}
*/
function getFieldValue(field, fieldType) {
var $field = $(field);
switch (fieldType) {
case 'text':
case 'number':
return $field.prop('value');
case 'checkbox':
return $field.prop('checked');
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
var items = [];
for (i = 0; i < imax; i++) {
if (options[i].selected) {
items.push(options[i].value);
}
}
return items;
}
return null;
}
/**
* Returns values for all fields in fieldsets
*
* @return {object}
*/
// eslint-disable-next-line no-unused-vars
function getAllValues() {
var $elements = $('fieldset input, fieldset select, fieldset textarea');
var values = {};
var type;
var value;
for (var i = 0; i < $elements.length; i++) {
type = getFieldType($elements[i]);
value = getFieldValue($elements[i], type);
if (typeof value !== 'undefined') {
// we only have single selects, fatten array
if (type === 'select') {
value = value[0];
}
values[$elements[i].name] = value;
}
}
return values;
}
/**
* Checks whether field has its default value
*
* @param {Element} field
* @param {string} type
*
* @return {boolean}
*/
function checkFieldDefault(field, type) {
var $field = $(field);
var fieldId = $field.attr('id');
if (typeof defaultValues[fieldId] === 'undefined') {
return true;
}
var isDefault = true;
var currentValue = getFieldValue($field, type);
if (type !== 'select') {
isDefault = currentValue === defaultValues[fieldId];
} else {
// compare arrays, will work for our representation of select values
if (currentValue.length !== defaultValues[fieldId].length) {
isDefault = false;
} else {
for (var i = 0; i < currentValue.length; i++) {
if (currentValue[i] !== defaultValues[fieldId][i]) {
isDefault = false;
break;
}
}
}
}
return isDefault;
}
/**
* Returns element's id prefix
* @param {Element} element
*
* @return {string}
*/
// eslint-disable-next-line no-unused-vars
function getIdPrefix(element) {
return $(element).attr('id').replace(/[^-]+$/, '');
}
// ------------------------------------------------------------------
// Form validation and field operations
//
// form validator assignments
var validate = {};
// form validator list
var validators = {
// regexp: numeric value
regExpNumeric: /^[0-9]+$/,
// regexp: extract parts from PCRE expression
regExpPcreExtract: /(.)(.*)\1(.*)?/,
/**
* Validates positive number
*
* @param {boolean} isKeyUp
*
* @return {boolean}
*/
validatePositiveNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = this.value !== '0' && validators.regExpNumeric.test(this.value);
return result ? true : Messages.error_nan_p;
},
/**
* Validates non-negative number
*
* @param {boolean} isKeyUp
*
* @return {boolean}
*/
validateNonNegativeNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = validators.regExpNumeric.test(this.value);
return result ? true : Messages.error_nan_nneg;
},
/**
* Validates port number
*
* @return {true|string}
*/
validatePortNumber: function () {
if (this.value === '') {
return true;
}
var result = validators.regExpNumeric.test(this.value) && this.value !== '0';
return result && this.value <= 65535 ? true : Messages.error_incorrect_port;
},
/**
* Validates value according to given regular expression
*
* @param {boolean} isKeyUp
* @param {string} regexp
*
* @return {true|string}
*/
validateByRegex: function (isKeyUp, regexp) {
if (isKeyUp && this.value === '') {
return true;
}
// convert PCRE regexp
var parts = regexp.match(validators.regExpPcreExtract);
var valid = this.value.match(new RegExp(parts[2], parts[3])) !== null;
return valid ? true : Messages.error_invalid_value;
},
/**
* Validates upper bound for numeric inputs
*
* @param {boolean} isKeyUp
* @param {number} maxValue
*
* @return {true|string}
*/
validateUpperBound: function (isKeyUp, maxValue) {
var val = parseInt(this.value, 10);
if (isNaN(val)) {
return true;
}
return val <= maxValue ? true : Functions.sprintf(Messages.error_value_lte, maxValue);
},
// field validators
field: {},
// fieldset validators
fieldset: {}
};
/**
* Registers validator for given field
*
* @param {string} id field id
* @param {string} type validator (key in validators object)
* @param {boolean} onKeyUp whether fire on key up
* @param {Array} params validation function parameters
*/
// eslint-disable-next-line no-unused-vars
function registerFieldValidator(id, type, onKeyUp, params) {
if (typeof validators[type] === 'undefined') {
return;
}
if (typeof validate[id] === 'undefined') {
validate[id] = [];
}
if (validate[id].length === 0) {
validate[id].push([type, params, onKeyUp]);
}
}
/**
* Returns validation functions associated with form field
*
* @param {String} fieldId form field id
* @param {boolean} onKeyUpOnly see registerFieldValidator
*
* @return {any[]} of [function, parameters to be passed to function]
*/
function getFieldValidators(fieldId, onKeyUpOnly) {
// look for field bound validator
var name = fieldId && fieldId.match(/[^-]+$/)[0];
if (typeof validators.field[name] !== 'undefined') {
return [[validators.field[name], null]];
}
// look for registered validators
var functions = [];
if (typeof validate[fieldId] !== 'undefined') {
// validate[field_id]: array of [type, params, onKeyUp]
for (var i = 0, imax = validate[fieldId].length; i < imax; i++) {
if (onKeyUpOnly && !validate[fieldId][i][2]) {
continue;
}
functions.push([validators[validate[fieldId][i][0]], validate[fieldId][i][1]]);
}
}
return functions;
}
/**
* Displays errors for given form fields
*
* WARNING: created DOM elements must be identical with the ones made by
* PhpMyAdmin\Config\FormDisplayTemplate::displayInput()!
*
* @param {object} errorList list of errors in the form {field id: error array}
*/
function displayErrors(errorList) {
var tempIsEmpty = function (item) {
return item !== '';
};
for (var fieldId in errorList) {
var errors = errorList[fieldId];
var $field = $('#' + fieldId);
var isFieldset = $field.attr('tagName') === 'FIELDSET';
var $errorCnt;
if (isFieldset) {
$errorCnt = $field.find('dl.errors');
} else {
$errorCnt = $field.siblings('.inline_errors');
}
// remove empty errors (used to clear error list)
errors = $.grep(errors, tempIsEmpty);
// CSS error class
if (!isFieldset) {
// checkboxes uses parent <span> for marking
var $fieldMarker = $field.attr('type') === 'checkbox' ? $field.parent() : $field;
$fieldMarker[errors.length ? 'addClass' : 'removeClass']('field-error');
}
if (errors.length) {
// if error container doesn't exist, create it
if ($errorCnt.length === 0) {
if (isFieldset) {
$errorCnt = $('<dl class="errors"></dl>');
$field.find('table').before($errorCnt);
} else {
$errorCnt = $('<dl class="inline_errors"></dl>');
$field.closest('td').append($errorCnt);
}
}
var html = '';
for (var i = 0, imax = errors.length; i < imax; i++) {
html += '<dd>' + errors[i] + '</dd>';
}
$errorCnt.html(html);
} else if ($errorCnt !== null) {
// remove useless error container
$errorCnt.remove();
}
}
}
/**
* Validates fields and fieldsets and call displayError function as required
*/
function setDisplayError() {
var elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]');
// run all field validators
var errors = {};
for (var i = 0; i < elements.length; i++) {
validateField(elements[i], false, errors);
}
// run all fieldset validators
$('fieldset.optbox').each(function () {
validateFieldset(this, false, errors);
});
displayErrors(errors);
}
/**
* Validates fieldset and puts errors in 'errors' object
*
* @param {Element} fieldset
* @param {boolean} isKeyUp
* @param {object} errors
*/
function validateFieldset(fieldset, isKeyUp, errors) {
var $fieldset = $(fieldset);
if ($fieldset.length && typeof validators.fieldset[$fieldset.attr('id')] !== 'undefined') {
var fieldsetErrors = validators.fieldset[$fieldset.attr('id')].apply($fieldset[0], [isKeyUp]);
for (var fieldId in fieldsetErrors) {
if (typeof errors[fieldId] === 'undefined') {
errors[fieldId] = [];
}
if (typeof fieldsetErrors[fieldId] === 'string') {
fieldsetErrors[fieldId] = [fieldsetErrors[fieldId]];
}
$.merge(errors[fieldId], fieldsetErrors[fieldId]);
}
}
}
/**
* Validates form field and puts errors in 'errors' object
*
* @param {Element} field
* @param {boolean} isKeyUp
* @param {object} errors
*/
function validateField(field, isKeyUp, errors) {
var args;
var result;
var $field = $(field);
var fieldId = $field.attr('id');
errors[fieldId] = [];
var functions = getFieldValidators(fieldId, isKeyUp);
for (var i = 0; i < functions.length; i++) {
if (typeof functions[i][1] !== 'undefined' && functions[i][1] !== null) {
args = functions[i][1].slice(0);
} else {
args = [];
}
args.unshift(isKeyUp);
result = functions[i][0].apply($field[0], args);
if (result !== true) {
if (typeof result === 'string') {
result = [result];
}
$.merge(errors[fieldId], result);
}
}
}
/**
* Validates form field and parent fieldset
*
* @param {Element} field
* @param {boolean} isKeyUp
*/
function validateFieldAndFieldset(field, isKeyUp) {
var $field = $(field);
var errors = {};
validateField($field, isKeyUp, errors);
validateFieldset($field.closest('fieldset.optbox'), isKeyUp, errors);
displayErrors(errors);
}
function loadInlineConfig() {
if (!Array.isArray(configInlineParams)) {
return;
}
for (var i = 0; i < configInlineParams.length; ++i) {
if (typeof configInlineParams[i] === 'function') {
configInlineParams[i]();
}
}
}
function setupValidation() {
validate = {};
configScriptLoaded = true;
if (configScriptLoaded && typeof configInlineParams !== 'undefined') {
loadInlineConfig();
}
// register validators and mark custom values
var $elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]');
$elements.each(function () {
markField(this);
var $el = $(this);
$el.on('change', function () {
validateFieldAndFieldset(this, false);
markField(this);
});
var tagName = $el.attr('tagName');
// text fields can be validated after each change
if (tagName === 'INPUT' && $el.attr('type') === 'text') {
$el.on('keyup', function () {
validateFieldAndFieldset($el, true);
markField($el);
});
}
// disable textarea spellcheck
if (tagName === 'TEXTAREA') {
$el.attr('spellcheck', false);
}
});
// check whether we've refreshed a page and browser remembered modified
// form values
var $checkPageRefresh = $('#check_page_refresh');
if ($checkPageRefresh.length === 0 || $checkPageRefresh.val() === '1') {
// run all field validators
var errors = {};
for (var i = 0; i < $elements.length; i++) {
validateField($elements[i], false, errors);
}
// run all fieldset validators
$('fieldset.optbox').each(function () {
validateFieldset(this, false, errors);
});
displayErrors(errors);
} else if ($checkPageRefresh) {
$checkPageRefresh.val('1');
}
}
AJAX.registerOnload('config.js', function () {
setupValidation();
});
//
// END: Form validation and field operations
// ------------------------------------------------------------------
function adjustPrefsNotification() {
var $prefsAutoLoad = $('#prefs_autoload');
var $tableNameControl = $('#table_name_col_no');
var $prefsAutoShowing = $prefsAutoLoad.css('display') !== 'none';
if ($prefsAutoShowing && $tableNameControl.length) {
$tableNameControl.css('top', '55px');
}
}
AJAX.registerOnload('config.js', function () {
adjustPrefsNotification();
});
// ------------------------------------------------------------------
// Form reset buttons
//
AJAX.registerOnload('config.js', function () {
$('.optbox input[type=button][name=submit_reset]').on('click', function () {
var fields = $(this).closest('fieldset').find('input, select, textarea');
for (var i = 0, imax = fields.length; i < imax; i++) {
setFieldValue(fields[i], getFieldType(fields[i]), defaultValues[fields[i].id]);
}
setDisplayError();
});
});
//
// END: Form reset buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// "Restore default" and "set value" buttons
//
/**
* Restores field's default value
*
* @param {string} fieldId
*
* @return {void}
*/
function restoreField(fieldId) {
var $field = $('#' + fieldId);
if ($field.length === 0 || defaultValues[fieldId] === undefined) {
return;
}
setFieldValue($field, getFieldType($field), defaultValues[fieldId]);
}
function setupRestoreField() {
$('div.tab-content').on('mouseenter', '.restore-default, .set-value', function () {
$(this).css('opacity', 1);
}).on('mouseleave', '.restore-default, .set-value', function () {
$(this).css('opacity', 0.25);
}).on('click', '.restore-default, .set-value', function (e) {
e.preventDefault();
var href = $(this).attr('href');
var fieldSel;
if ($(this).hasClass('restore-default')) {
fieldSel = href;
restoreField(fieldSel.substr(1));
} else {
fieldSel = href.match(/^[^=]+/)[0];
var value = href.match(/=(.+)$/)[1];
setFieldValue($(fieldSel), 'text', value);
}
$(fieldSel).trigger('change');
}).find('.restore-default, .set-value')
// inline-block for IE so opacity inheritance works
.css({
display: 'inline-block',
opacity: 0.25
});
}
AJAX.registerOnload('config.js', function () {
setupRestoreField();
});
//
// END: "Restore default" and "set value" buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// User preferences import/export
//
AJAX.registerOnload('config.js', function () {
offerPrefsAutoimport();
var $radios = $('#import_local_storage, #export_local_storage');
if (!$radios.length) {
return;
}
// enable JavaScript dependent fields
$radios.prop('disabled', false).add('#export_text_file, #import_text_file').on('click', function () {
var enableId = $(this).attr('id');
var disableId;
if (enableId.match(/local_storage$/)) {
disableId = enableId.replace(/local_storage$/, 'text_file');
} else {
disableId = enableId.replace(/text_file$/, 'local_storage');
}
$('#opts_' + disableId).addClass('disabled').find('input').prop('disabled', true);
$('#opts_' + enableId).removeClass('disabled').find('input').prop('disabled', false);
});
// detect localStorage state
var lsSupported = isStorageSupported('localStorage', true);
var lsExists = lsSupported ? window.localStorage.config || false : false;
$('div.localStorage-' + (lsSupported ? 'un' : '') + 'supported').hide();
$('div.localStorage-' + (lsExists ? 'empty' : 'exists')).hide();
if (lsExists) {
updatePrefsDate();
}
$('form.prefs-form').on('change', function () {
var $form = $(this);
var disabled = false;
if (!lsSupported) {
disabled = $form.find('input[type=radio][value$=local_storage]').prop('checked');
} else if (!lsExists && $form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked) {
disabled = true;
}
$form.find('input[type=submit]').prop('disabled', disabled);
}).on('submit', function (e) {
var $form = $(this);
if ($form.attr('name') === 'prefs_export' && $('#export_local_storage')[0].checked) {
e.preventDefault();
// use AJAX to read JSON settings and save them
savePrefsToLocalStorage($form);
} else if ($form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked) {
// set 'json' input and submit form
$form.find('input[name=json]').val(window.localStorage.config);
}
});
$(document).on('click', 'div.click-hide-message', function () {
$(this).hide();
$(this).parent('.card-body').css('height', '');
$(this).parent('.card-body').find('.prefs-form').show();
});
});
/**
* Saves user preferences to localStorage
*
* @param {Element} form
*/
function savePrefsToLocalStorage(form) {
var $form = $(form);
var submit = $form.find('input[type=submit]');
submit.prop('disabled', true);
$.ajax({
url: 'index.php?route=/preferences/manage',
cache: false,
type: 'POST',
data: {
'ajax_request': true,
'server': CommonParams.get('server'),
'submit_get_json': true
},
success: function (data) {
if (typeof data !== 'undefined' && data.success === true) {
window.localStorage.config = data.prefs;
window.localStorage.configMtime = data.mtime;
window.localStorage.configMtimeLocal = new Date().toUTCString();
updatePrefsDate();
$('div.localStorage-empty').hide();
$('div.localStorage-exists').show();
var group = $form.parent('.card-body');
group.css('height', group.height() + 'px');
$form.hide('fast');
$form.prev('.click-hide-message').show('fast');
} else {
Functions.ajaxShowMessage(data.error);
}
},
complete: function () {
submit.prop('disabled', false);
}
});
}
/**
* Updates preferences timestamp in Import form
*/
function updatePrefsDate() {
var d = new Date(window.localStorage.configMtimeLocal);
var msg = Messages.strSavedOn.replace('@DATE@', Functions.formatDateTime(d));
$('#opts_import_local_storage').find('div.localStorage-exists').html(msg);
}
/**
* Prepares message which informs that localStorage preferences are available and can be imported or deleted
*/
function offerPrefsAutoimport() {
var hasConfig = isStorageSupported('localStorage') && (window.localStorage.config || false);
var $cnt = $('#prefs_autoload');
if (!$cnt.length || !hasConfig) {
return;
}
$cnt.find('a').on('click', function (e) {
e.preventDefault();
var $a = $(this);
if ($a.attr('href') === '#no') {
$cnt.remove();
$.post('index.php', {
'server': CommonParams.get('server'),
'prefs_autoload': 'hide'
}, null, 'html');
return;
} else if ($a.attr('href') === '#delete') {
$cnt.remove();
localStorage.clear();
$.post('index.php', {
'server': CommonParams.get('server'),
'prefs_autoload': 'hide'
}, null, 'html');
return;
}
$cnt.find('input[name=json]').val(window.localStorage.config);
$cnt.find('form').trigger('submit');
});
$cnt.show();
}
/**
* @type {boolean} Support for passive event listener option
*/
var PASSIVE_EVENT_LISTENERS = function () {
var passive = false;
try {
var options = Object.defineProperty({}, 'passive', {
get: function () {
return passive = true;
}
});
window.addEventListener('_', null, options);
window.removeEventListener('_', null, options);
} catch (error) {
// passive not supported
}
return passive;
}();

File diff suppressed because it is too large Load diff

View file

@ -1,13 +0,0 @@
/**
* Conditionally included if framing is not allowed
*/
if (self === top) {
var styleElement = document.getElementById('cfs-style');
// check if styleElement has already been removed
// to avoid frequently reported js error
if (typeof styleElement !== 'undefined' && styleElement !== null) {
styleElement.parentNode.removeChild(styleElement);
}
} else {
top.location = self.location;
}

View file

@ -1,231 +0,0 @@
/**
* @fileoverview events handling from central columns page
* @name Central columns
*
* @requires jQuery
*/
/**
* AJAX scripts for /database/central-columns
*
* Actions ajaxified here:
* Inline Edit and save of a result row
* Delete a row
* Multiple edit and delete option
*
*/
AJAX.registerTeardown('database/central_columns.js', function () {
$('.edit').off('click');
$('.edit_save_form').off('click');
$('.edit_cancel_form').off('click');
$('.del_row').off('click');
$(document).off('keyup', '.filter_rows');
$('.edit_cancel_form').off('click');
$('#table-select').off('change');
$('#column-select').off('change');
$('#add_col_div').find('>a').off('click');
$('#add_new').off('submit');
$('#multi_edit_central_columns').off('submit');
$('select.default_type').off('change');
$('button[name=\'delete_central_columns\']').off('click');
$('button[name=\'edit_central_columns\']').off('click');
});
AJAX.registerOnload('database/central_columns.js', function () {
$('#tableslistcontainer input,#tableslistcontainer select,#tableslistcontainer .default_value,#tableslistcontainer .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
$('#tableslistcontainer').find('.checkall_box').show();
if ($('#table_columns').find('tbody tr').length > 0) {
$('#table_columns').tablesorter({
headers: {
0: {
sorter: false
},
1: {
sorter: false
},
// hidden column
4: {
sorter: 'integer'
}
}
});
}
$('#tableslistcontainer').find('button[name="delete_central_columns"]').on('click', function (event) {
event.preventDefault();
var multiDeleteColumns = $('.checkall:checkbox:checked').serialize();
if (multiDeleteColumns === '') {
Functions.ajaxShowMessage(Messages.strRadioUnchecked);
return false;
}
Functions.ajaxShowMessage();
$('#del_col_name').val(multiDeleteColumns);
$('#del_form').trigger('submit');
});
$('#tableslistcontainer').find('button[name="edit_central_columns"]').on('click', function (event) {
event.preventDefault();
var editColumnList = $('.checkall:checkbox:checked').serialize();
if (editColumnList === '') {
Functions.ajaxShowMessage(Messages.strRadioUnchecked);
return false;
}
var argsep = CommonParams.get('arg_separator');
var editColumnData = editColumnList + '' + argsep + 'edit_central_columns_page=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(CommonParams.get('db')) + argsep + 'server=' + CommonParams.get('server');
Functions.ajaxShowMessage();
AJAX.source = $(this);
$.post('index.php?route=/database/central-columns', editColumnData, AJAX.responseHandler);
});
$('#multi_edit_central_columns').on('submit', function (event) {
event.preventDefault();
event.stopPropagation();
var argsep = CommonParams.get('arg_separator');
var multiColumnEditData = $('#multi_edit_central_columns').serialize() + argsep + 'multi_edit_central_column_save=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(CommonParams.get('db')) + argsep + 'server=' + CommonParams.get('server');
Functions.ajaxShowMessage();
AJAX.source = $(this);
$.post('index.php?route=/database/central-columns', multiColumnEditData, AJAX.responseHandler);
});
$('#add_new').find('td').each(function () {
if ($(this).attr('name') !== 'undefined') {
$(this).find('input,select').first().attr('name', $(this).attr('name'));
}
});
$('#field_0_0').attr('required', 'required');
$('#add_new input[type="text"], #add_new input[type="number"], #add_new select').css({
'width': '10em',
'box-sizing': 'border-box'
});
window.scrollTo(0, 0);
$(document).on('keyup', '.filter_rows', function () {
// get the column names
var cols = $('th.column_heading').map(function () {
return $(this).text().trim();
}).get();
$.uiTableFilter($('#table_columns'), $(this).val(), cols, null, 'td span');
});
$('.edit').on('click', function () {
var rownum = $(this).parent().data('rownum');
$('#save_' + rownum).show();
$(this).hide();
$('#f_' + rownum + ' td span').hide();
$('#f_' + rownum + ' input, #f_' + rownum + ' select, #f_' + rownum + ' .open_enum_editor').show();
var attributeVal = $('#f_' + rownum + ' td[name=col_attribute] span').html();
$('#f_' + rownum + ' select[name=field_attribute\\[' + rownum + '\\] ] option[value="' + attributeVal + '"]').attr('selected', 'selected');
if ($('#f_' + rownum + ' .default_type').val() === 'USER_DEFINED') {
$('#f_' + rownum + ' .default_type').siblings('.default_value').show();
} else {
$('#f_' + rownum + ' .default_type').siblings('.default_value').hide();
}
});
$('.del_row').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var $td = $(this);
var question = Messages.strDeleteCentralColumnWarning;
$td.confirm(question, null, function () {
var rownum = $td.data('rownum');
$('#del_col_name').val('selected_fld%5B%5D=' + $('#checkbox_row_' + rownum).val());
$('#del_form').trigger('submit');
});
});
$('.edit_cancel_form').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var rownum = $(this).data('rownum');
$('#save_' + rownum).hide();
$('#edit_' + rownum).show();
$('#f_' + rownum + ' td span').show();
$('#f_' + rownum + ' input, #f_' + rownum + ' select,#f_' + rownum + ' .default_value, #f_' + rownum + ' .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
});
$('.edit_save_form').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var rownum = $(this).data('rownum');
$('#f_' + rownum + ' td').each(function () {
if ($(this).attr('name') !== 'undefined') {
$(this).find(':input[type!="hidden"],select').first().attr('name', $(this).attr('name'));
}
});
if ($('#f_' + rownum + ' .default_type').val() === 'USER_DEFINED') {
$('#f_' + rownum + ' .default_type').attr('name', 'col_default_sel');
} else {
$('#f_' + rownum + ' .default_value').attr('name', 'col_default_val');
}
var datastring = $('#f_' + rownum + ' :input').serialize();
$.ajax({
type: 'POST',
url: 'index.php?route=/database/central-columns',
data: datastring + CommonParams.get('arg_separator') + 'ajax_request=true',
dataType: 'json',
success: function (data) {
if (data.message !== '1') {
Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert">' + data.message + '</div>', false);
} else {
$('#f_' + rownum + ' td input[id=checkbox_row_' + rownum + ']').val($('#f_' + rownum + ' input[name=col_name]').val()).html();
$('#f_' + rownum + ' td[name=col_name] span').text($('#f_' + rownum + ' input[name=col_name]').val()).html();
$('#f_' + rownum + ' td[name=col_type] span').text($('#f_' + rownum + ' select[name=col_type]').val()).html();
$('#f_' + rownum + ' td[name=col_length] span').text($('#f_' + rownum + ' input[name=col_length]').val()).html();
$('#f_' + rownum + ' td[name=collation] span').text($('#f_' + rownum + ' select[name=collation]').val()).html();
$('#f_' + rownum + ' td[name=col_attribute] span').text($('#f_' + rownum + ' select[name=col_attribute]').val()).html();
$('#f_' + rownum + ' td[name=col_isNull] span').text($('#f_' + rownum + ' input[name=col_isNull]').is(':checked') ? 'Yes' : 'No').html();
$('#f_' + rownum + ' td[name=col_extra] span').text($('#f_' + rownum + ' input[name=col_extra]').is(':checked') ? 'auto_increment' : '').html();
$('#f_' + rownum + ' td[name=col_default] span').text($('#f_' + rownum + ' :input[name=col_default]').val()).html();
}
$('#save_' + rownum).hide();
$('#edit_' + rownum).show();
$('#f_' + rownum + ' td span').show();
$('#f_' + rownum + ' input, #f_' + rownum + ' select,#f_' + rownum + ' .default_value, #f_' + rownum + ' .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
},
error: function () {
Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert">' + Messages.strErrorProcessingRequest + '</div>', false);
}
});
});
$('#table-select').on('change', function () {
var selectValue = $(this).val();
var defaultColumnSelect = $('#column-select').find('option').first();
var href = 'index.php?route=/database/central-columns/populate';
var params = {
'ajax_request': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'selectedTable': selectValue
};
$('#column-select').html('<option value="">' + Messages.strLoading + '</option>');
if (selectValue !== '') {
$.post(href, params, function (data) {
$('#column-select').empty().append(defaultColumnSelect);
$('#column-select').append(data.message);
});
}
});
$('#add_column').on('submit', function (e) {
var selectvalue = $('#column-select').val();
if (selectvalue === '') {
e.preventDefault();
e.stopPropagation();
}
});
$('#add_col_div').find('>a').on('click', function () {
$('#add_new').slideToggle('slow');
var $addColDivLinkSpan = $('#add_col_div').find('>a span');
if ($addColDivLinkSpan.html() === '+') {
$addColDivLinkSpan.html('-');
} else {
$addColDivLinkSpan.html('+');
}
});
$('#add_new').on('submit', function () {
$('#add_new').toggle();
});
$('#tableslistcontainer').find('select.default_type').on('change', function () {
if ($(this).val() === 'USER_DEFINED') {
$(this).siblings('.default_value').attr('name', 'col_default');
$(this).attr('name', 'col_default_sel');
} else {
$(this).attr('name', 'col_default');
$(this).siblings('.default_value').attr('name', 'col_default_val');
}
});
});

View file

@ -1,570 +0,0 @@
AJAX.registerTeardown('database/events.js', function () {
$(document).off('click', 'a.ajax.add_anchor, a.ajax.edit_anchor');
$(document).off('click', 'a.ajax.export_anchor');
$(document).off('click', '#bulkActionExportButton');
$(document).off('click', 'a.ajax.drop_anchor');
$(document).off('click', '#bulkActionDropButton');
$(document).off('change', 'select[name=item_type]');
});
const DatabaseEvents = {
/**
* @var $ajaxDialog Query object containing the reference to the
* dialog that contains the editor
*/
$ajaxDialog: null,
/**
* @var syntaxHiglighter Reference to the codemirror editor
*/
syntaxHiglighter: null,
/**
* Validate editor form fields.
*
* @return {bool}
*/
validate: function () {
/**
* @var $elm a jQuery object containing the reference
* to an element that is being validated
*/
var $elm = null;
// Common validation. At the very least the name
// and the definition must be provided for an item
$elm = $('table.rte_table').last().find('input[name=item_name]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
$elm = $('table.rte_table').find('textarea[name=item_definition]');
if ($elm.val() === '') {
if (this.syntaxHiglighter !== null) {
this.syntaxHiglighter.focus();
} else {
$('textarea[name=item_definition]').last().trigger('focus');
}
alert(Messages.strFormEmpty);
return false;
}
// The validation has so far passed, so now
// we can validate item-specific fields.
return this.validateCustom();
},
exportDialog: function ($this) {
var $msg = Functions.ajaxShowMessage();
if ($this.attr('id') === 'bulkActionExportButton') {
var combined = {
success: true,
title: Messages.strExport,
message: '',
error: ''
};
// export anchors of all selected rows
var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor');
var count = exportAnchors.length;
var returnCount = 0;
var p = $.when();
exportAnchors.each(function () {
var h = $(this).attr('href');
p = p.then(function () {
return $.get(h, {
'ajax_request': true
}, function (data) {
returnCount++;
if (data.success === true) {
combined.message += '\n' + data.message + '\n';
if (returnCount === count) {
showExport(combined);
}
} else {
// complain even if one export is failing
combined.success = false;
combined.error += '\n' + data.error + '\n';
if (returnCount === count) {
showExport(combined);
}
}
});
});
});
} else {
$.get($this.attr('href'), {
'ajax_request': true
}, showExport);
}
Functions.ajaxRemoveMessage($msg);
function showExport(data) {
if (data.success === true) {
Functions.ajaxRemoveMessage($msg);
/**
* @var buttonOptions Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-primary',
click: function () {
$(this).dialog('close').remove();
}
}
};
/**
* Display the dialog to the user
*/
data.message = '<textarea cols="40" rows="15" class="w-100">' + data.message + '</textarea>';
var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 500,
buttons: buttonOptions,
title: data.title
});
// Attach syntax highlighted editor to export dialog
/**
* @var $elm jQuery object containing the reference
* to the Export textarea.
*/
var $elm = $ajaxDialog.find('textarea');
Functions.getSqlEditor($elm);
} else {
Functions.ajaxShowMessage(data.error, false);
}
} // end showExport()
},
// end exportDialog()
editorDialog: function (isNew, $this) {
var that = this;
/**
* @var $edit_row jQuery object containing the reference to
* the row of the the item being edited
* from the list of items
*/
var $editRow = null;
if ($this.hasClass('edit_anchor')) {
// Remember the row of the item being edited for later,
// so that if the edit is successful, we can replace the
// row with info about the modified item.
$editRow = $this.parents('tr');
}
/**
* @var $msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage();
$.get($this.attr('href'), {
'ajax_request': true
}, function (data) {
if (data.success === true) {
// We have successfully fetched the editor form
Functions.ajaxRemoveMessage($msg);
/**
* @var buttonOptions Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary'
},
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-secondary'
}
};
// Now define the function that is called when
// the user presses the "Go" button
buttonOptions[Messages.strGo].click = function () {
// Move the data from the codemirror editor back to the
// textarea, where it can be used in the form submission.
if (typeof CodeMirror !== 'undefined') {
that.syntaxHiglighter.save();
}
// Validate editor and submit request, if passed.
if (that.validate()) {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $('form.rte_form').last().serialize();
$msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var url = $('form.rte_form').last().attr('action');
$.post(url, data, function (data) {
if (data.success === true) {
// Item created successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
that.$ajaxDialog.dialog('close');
// If we are in 'edit' mode, we must
// remove the reference to the old row.
if (mode === 'edit' && $editRow !== null) {
$editRow.remove();
}
// Sometimes, like when moving a trigger from
// a table to another one, the new row should
// not be inserted into the list. In this case
// "data.insert" will be set to false.
if (data.insert) {
// Insert the new row at the correct
// location in the list of items
/**
* @var text Contains the name of an item from
* the list that is used in comparisons
* to find the correct location where
* to insert a new row.
*/
var text = '';
/**
* @var inserted Whether a new item has been
* inserted in the list or not
*/
var inserted = false;
$('table.data').find('tr').each(function () {
text = $(this).children('td').eq(0).find('strong').text().toUpperCase().trim();
if (text !== '' && text > data.name) {
$(this).before(data.new_row);
inserted = true;
return false;
}
});
if (!inserted) {
// If we didn't manage to insert the row yet,
// it must belong at the end of the list,
// so we insert it there.
$('table.data').append(data.new_row);
}
// Fade-in the new row
$('tr.ajaxInsert').show('slow').removeClass('ajaxInsert');
} else if ($('table.data').find('tr').has('td').length === 0) {
// If we are not supposed to insert the new row,
// we will now check if the table is empty and
// needs to be hidden. This will be the case if
// we were editing the only item in the list,
// which we removed and will not be inserting
// something else in its place.
$('table.data').hide('slow', function () {
$('#nothing2display').show('slow');
});
}
// Now we have inserted the row at the correct
// position, but surely at least some row classes
// are wrong now. So we will iterate through
// all rows and assign correct classes to them
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$('table.data').find('tr').has('td').each(function () {
rowclass = ct % 2 === 0 ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
// If this is the first item being added, remove
// the "No items" message and show the list.
if ($('table.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible')) {
$('#nothing2display').hide('slow', function () {
$('table.data').show('slow');
});
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
} // end "if (that.validate())"
}; // end of function that handles the submission of the Editor
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close');
};
/**
* Display the dialog to the user
*/
that.$ajaxDialog = $('<div id="rteDialog">' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 700,
minWidth: 500,
buttons: buttonOptions,
// Issue #15810 - use button titles for modals (eg: new procedure)
// Respect the order: title on href tag, href content, title sent in response
title: $this.attr('title') || $this.text() || $(data.title).text(),
modal: true,
open: function () {
$('#rteDialog').dialog('option', 'max-height', $(window).height());
if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) {
$('#rteDialog').dialog('option', 'height', $(window).height());
}
$(this).find('input[name=item_name]').trigger('focus');
$(this).find('input.datefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'date');
});
$(this).find('input.datetimefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'datetime');
});
$.datepicker.initialized = false;
},
close: function () {
$(this).remove();
}
});
/**
* @var mode Used to remember whether the editor is in
* "Edit" or "Add" mode
*/
var mode = 'add';
if ($('input[name=editor_process_edit]').length > 0) {
mode = 'edit';
}
// Attach syntax highlighted editor to the definition
/**
* @var elm jQuery object containing the reference to
* the Definition textarea.
*/
var $elm = $('textarea[name=item_definition]').last();
var linterOptions = {};
linterOptions.eventEditor = true;
that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.get()
},
dropDialog: function ($this) {
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $this.parents('tr');
/**
* @var question String containing the question to be asked for confirmation
*/
var question = $('<div></div>').text($currRow.children('td').children('.drop_sql').html());
// We ask for confirmation first here, before submitting the ajax request
$this.confirm(question, $this.attr('href'), function (url) {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $this.getPostData());
$.post(url, params, function (data) {
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('slow', function () {
$(this).remove();
// Now we have removed the row from the list, but maybe
// some row classes are wrong now. So we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = ct % 2 === 1 ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
});
}
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
// Show the query that we just executed
Functions.slidingMessage(data.sql_query);
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
},
dropMultipleDialog: function ($this) {
// We ask for confirmation here
$this.confirm(Messages.strDropRTEitems, '', function () {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
// drop anchors of all selected rows
var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor');
var success = true;
var count = dropAnchors.length;
var returnCount = 0;
dropAnchors.each(function () {
var $anchor = $(this);
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $anchor.parents('tr');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
$.post($anchor.attr('href'), params, function (data) {
returnCount++;
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('fast', function () {
// we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = ct % 2 === 1 ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
});
$currRow.remove();
}
if (returnCount === count) {
if (success) {
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
$('#rteListForm_checkall').prop({
checked: false,
indeterminate: false
});
}
Navigation.reload();
}
} else {
Functions.ajaxShowMessage(data.error, false);
success = false;
if (returnCount === count) {
Navigation.reload();
}
}
}); // end $.post()
}); // end drop_anchors.each()
});
},
/**
* Validate custom editor form fields.
*
* @return {bool}
*/
validateCustom: function () {
/**
* @var elm a jQuery object containing the reference
* to an element that is being validated
*/
var $elm = null;
if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'RECURRING') {
// The interval field must not be empty for recurring events
$elm = this.$ajaxDialog.find('input[name=item_interval_value]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
} else {
// The execute_at field must not be empty for "once off" events
$elm = this.$ajaxDialog.find('input[name=item_execute_at]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
}
return true;
}
};
AJAX.registerOnload('database/events.js', function () {
/**
* Attach Ajax event handlers for the Add/Edit functionality.
*/
$(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) {
event.preventDefault();
if ($(this).hasClass('add_anchor')) {
$.datepicker.initialized = false;
}
DatabaseEvents.editorDialog($(this).hasClass('add_anchor'), $(this));
});
/**
* Attach Ajax event handlers for Export
*/
$(document).on('click', 'a.ajax.export_anchor', function (event) {
event.preventDefault();
DatabaseEvents.exportDialog($(this));
}); // end $(document).on()
$(document).on('click', '#bulkActionExportButton', function (event) {
event.preventDefault();
DatabaseEvents.exportDialog($(this));
}); // end $(document).on()
/**
* Attach Ajax event handlers for Drop functionality
*/
$(document).on('click', 'a.ajax.drop_anchor', function (event) {
event.preventDefault();
DatabaseEvents.dropDialog($(this));
}); // end $(document).on()
$(document).on('click', '#bulkActionDropButton', function (event) {
event.preventDefault();
DatabaseEvents.dropMultipleDialog($(this));
}); // end $(document).on()
/**
* Attach Ajax event handlers for the "Change event type" functionality, so that the correct
* rows are shown in the editor when changing the event type
*/
$(document).on('change', 'select[name=item_type]', function () {
$(this).closest('table').find('tr.recurring_event_row, tr.onetime_event_row').toggle();
});
});

View file

@ -1,207 +0,0 @@
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
* @requires js/database/query_generator.js
*
*/
/* global generateFromBlock, generateWhereBlock */ // js/database/query_generator.js
/**
* js file for handling AJAX and other events in /database/multi-table-query
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/multi_table_query.js', function () {
$('.tableNameSelect').each(function () {
$(this).off('change');
});
$('#update_query_button').off('click');
$('#add_column_button').off('click');
});
AJAX.registerOnload('database/multi_table_query.js', function () {
var editor = Functions.getSqlEditor($('#MultiSqlquery'), {}, 'both');
$('.CodeMirror-line').css('text-align', 'left');
editor.setSize(-1, 50);
var columnCount = 3;
addNewColumnCallbacks();
$('#update_query_button').on('click', function () {
var columns = [];
var tableAliases = {};
$('.tableNameSelect').each(function () {
var $show = $(this).siblings('.show_col').first();
if ($(this).val() !== '' && $show.prop('checked')) {
var tableAlias = $(this).siblings('.table_alias').first().val();
var columnAlias = $(this).siblings('.col_alias').first().val();
if (tableAlias !== '') {
columns.push([tableAlias, $(this).siblings('.columnNameSelect').first().val()]);
} else {
columns.push([$(this).val(), $(this).siblings('.columnNameSelect').first().val()]);
}
columns[columns.length - 1].push(columnAlias);
if ($(this).val() in tableAliases) {
if (!tableAliases[$(this).val()].includes(tableAlias)) {
tableAliases[$(this).val()].push(tableAlias);
}
} else {
tableAliases[$(this).val()] = [tableAlias];
}
}
});
if (Object.keys(tableAliases).length === 0) {
Functions.ajaxShowMessage('Nothing selected', false, 'error');
return;
}
var foreignKeys;
$.ajax({
type: 'GET',
async: false,
url: 'index.php?route=/database/multi-table-query/tables',
data: {
'server': sessionStorage.server,
'db': $('#db_name').val(),
'tables': Object.keys(tableAliases),
'ajax_request': '1',
'token': CommonParams.get('token')
},
success: function (response) {
foreignKeys = response.foreignKeyConstrains;
}
});
var query = 'SELECT ' + '`' + Functions.escapeBacktick(columns[0][0]) + '`.';
if (columns[0][1] === '*') {
query += '*';
} else {
query += '`' + Functions.escapeBacktick(columns[0][1]) + '`';
}
if (columns[0][2] !== '') {
query += ' AS `' + Functions.escapeBacktick(columns[0][2]) + '`';
}
for (var i = 1; i < columns.length; i++) {
query += ', `' + Functions.escapeBacktick(columns[i][0]) + '`.';
if (columns[i][1] === '*') {
query += '*';
} else {
query += '`' + Functions.escapeBacktick(columns[i][1]) + '`';
}
if (columns[i][2] !== '') {
query += ' AS `' + Functions.escapeBacktick(columns[i][2]) + '`';
}
}
query += '\nFROM ';
query += generateFromBlock(tableAliases, foreignKeys);
var $criteriaColCount = $('.criteria_col:checked').length;
if ($criteriaColCount > 0) {
query += '\nWHERE ';
query += generateWhereBlock();
}
query += ';';
editor.getDoc().setValue(query);
});
$('#submit_query').on('click', function () {
var query = editor.getDoc().getValue();
// Verifying that the query is not empty
if (query === '') {
Functions.ajaxShowMessage(Messages.strEmptyQuery, false, 'error');
return;
}
var data = {
'db': $('#db_name').val(),
'sql_query': query,
'ajax_request': '1',
'server': CommonParams.get('server'),
'token': CommonParams.get('token')
};
$.ajax({
type: 'POST',
url: 'index.php?route=/database/multi-table-query/query',
data: data,
success: function (data) {
var $resultsDom = $(data.message);
$resultsDom.find('.ajax:not(.pageselector)').each(function () {
$(this).on('click', function (event) {
event.preventDefault();
});
});
$resultsDom.find('.autosubmit, .pageselector, .showAllRows, .filter_rows').each(function () {
$(this).on('change click select focus', function (event) {
event.preventDefault();
});
});
$('#sql_results').html($resultsDom);
$('#slide-handle').trigger('click'); // Collapse search criteria area
}
});
});
$('#add_column_button').on('click', function () {
columnCount++;
var $newColumnDom = $($('#new_column_layout').html()).clone();
$newColumnDom.find('.jsCriteriaButton').first().attr('data-bs-target', '#criteriaOptionsExtra' + columnCount.toString());
$newColumnDom.find('.jsCriteriaButton').first().attr('aria-controls', 'criteriaOptionsExtra' + columnCount.toString());
$newColumnDom.find('.jsCriteriaOptions').first().attr('id', 'criteriaOptionsExtra' + columnCount.toString());
$('#add_column_button').parent().before($newColumnDom);
addNewColumnCallbacks();
});
function addNewColumnCallbacks() {
$('.tableNameSelect').each(function () {
$(this).on('change', function () {
var $sibs = $(this).siblings('.columnNameSelect');
if ($sibs.length === 0) {
$sibs = $(this).parent().parent().find('.columnNameSelect');
}
$sibs.first().html($('#' + $(this).find(':selected').data('hash')).html());
});
});
$('.jsRemoveColumn').each(function () {
$(this).on('click', function () {
$(this).parent().remove();
});
});
$('.jsCriteriaButton').each(function () {
$(this).on('click', function (event, from) {
if (from === null) {
var $checkbox = $(this).siblings('.criteria_col').first();
$checkbox.prop('checked', !$checkbox.prop('checked'));
}
var $criteriaColCount = $('.criteria_col:checked').length;
if ($criteriaColCount > 1) {
$(this).siblings('.jsCriteriaOptions').first().find('.logical_operator').first().css('display', 'table-row');
}
});
});
$('.criteria_col').each(function () {
$(this).on('change', function () {
var $anchor = $(this).siblings('.jsCriteriaButton').first();
if ($(this).is(':checked') && !$anchor.hasClass('collapsed')) {
// Do not collapse on checkbox tick as it does not make sense
// The user has it open and wants to tick the box
return;
}
$anchor.trigger('click', ['Trigger']);
});
});
$('.criteria_rhs').each(function () {
$(this).on('change', function () {
var $rhsCol = $(this).parent().parent().siblings('.rhs_table').first();
var $rhsText = $(this).parent().parent().siblings('.rhs_text').first();
if ($(this).val() === 'text') {
$rhsCol.css('display', 'none');
$rhsText.css('display', 'table-row');
} else if ($(this).val() === 'anotherColumn') {
$rhsText.css('display', 'none');
$rhsCol.css('display', 'table-row');
} else {
$rhsText.css('display', 'none');
$rhsCol.css('display', 'none');
}
});
});
}
});

View file

@ -1,157 +0,0 @@
/**
* @fileoverview function used in server privilege pages
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Ajax event handlers here for /database/operations
*
* Actions Ajaxified here:
* Rename Database
* Copy Database
* Change Charset
* Drop Database
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/operations.js', function () {
$(document).off('submit', '#rename_db_form.ajax');
$(document).off('submit', '#copy_db_form.ajax');
$(document).off('submit', '#change_db_charset_form.ajax');
$(document).off('click', '#drop_db_anchor.ajax');
});
AJAX.registerOnload('database/operations.js', function () {
/**
* Ajax event handlers for 'Rename Database'
*/
$(document).on('submit', '#rename_db_form.ajax', function (event) {
event.preventDefault();
if (Functions.emptyCheckTheField(this, 'newname')) {
Functions.ajaxShowMessage(Messages.strFormEmpty, false, 'error');
return false;
}
var oldDbName = CommonParams.get('db');
var newDbName = $('#new_db_name').val();
if (newDbName === oldDbName) {
Functions.ajaxShowMessage(Messages.strDatabaseRenameToSameName, false, 'error');
return false;
}
var $form = $(this);
var question = Functions.escapeHtml('CREATE DATABASE ' + newDbName + ' / DROP DATABASE ' + oldDbName);
Functions.prepareForAjaxRequest($form);
$form.confirm(question, $form.attr('action'), function (url) {
Functions.ajaxShowMessage(Messages.strRenamingDatabases, false);
$.post(url, $('#rename_db_form').serialize() + CommonParams.get('arg_separator') + 'is_js_confirmed=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
CommonParams.set('db', data.newname);
Navigation.reload(function () {
$('#pma_navigation_tree').find('a:not(\'.expander\')').each(function () {
var $thisAnchor = $(this);
if ($thisAnchor.text() === data.newname) {
// simulate a click on the new db name
// in navigation
$thisAnchor.trigger('click');
}
});
});
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
}); // end Rename Database
/**
* Ajax Event Handler for 'Copy Database'
*/
$(document).on('submit', '#copy_db_form.ajax', function (event) {
event.preventDefault();
if (Functions.emptyCheckTheField(this, 'newname')) {
Functions.ajaxShowMessage(Messages.strFormEmpty, false, 'error');
return false;
}
Functions.ajaxShowMessage(Messages.strCopyingDatabase, false);
var $form = $(this);
Functions.prepareForAjaxRequest($form);
$.post($form.attr('action'), $form.serialize(), function (data) {
// use messages that stay on screen
$('.alert-success, .alert-danger').fadeOut();
if (typeof data !== 'undefined' && data.success === true) {
if ($('#checkbox_switch').is(':checked')) {
CommonParams.set('db', data.newname);
CommonActions.refreshMain(false, function () {
Functions.ajaxShowMessage(data.message);
});
} else {
CommonParams.set('db', data.db);
Functions.ajaxShowMessage(data.message);
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end copy database
/**
* Change tables columns visible only if change tables is checked
*/
$('#span_change_all_tables_columns_collations').hide();
$('#checkbox_change_all_tables_collations').on('click', function () {
$('#span_change_all_tables_columns_collations').toggle();
});
/**
* Ajax Event handler for 'Change Charset' of the database
*/
$(document).on('submit', '#change_db_charset_form.ajax', function (event) {
event.preventDefault();
var $form = $(this);
Functions.prepareForAjaxRequest($form);
Functions.ajaxShowMessage(Messages.strChangingCharset);
$.post($form.attr('action'), $form.serialize(), function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end change charset
/**
* Ajax event handlers for Drop Database
*/
$(document).on('click', '#drop_db_anchor.ajax', function (event) {
event.preventDefault();
var $link = $(this);
/**
* @var {String} question String containing the question to be asked for confirmation
*/
var question = Messages.strDropDatabaseStrongWarning + ' ';
question += Functions.sprintf(Messages.strDoYouReally, 'DROP DATABASE `' + Functions.escapeHtml(CommonParams.get('db') + '`'));
var params = Functions.getJsConfirmCommonParam(this, $link.getPostData());
$(this).confirm(question, $(this).attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strProcessingRequest);
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
// Database deleted successfully, refresh both the frames
Navigation.reload();
CommonParams.set('db', '');
CommonActions.refreshMain('index.php?route=/server/databases', function () {
Functions.ajaxShowMessage(data.message);
});
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
});
});

View file

@ -1,82 +0,0 @@
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Ajax event handlers here for /database/qbe
*
* Actions Ajaxified here:
* Select saved search
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/qbe.js', function () {
$(document).off('change', 'select[name^=criteriaColumn]');
$(document).off('change', '#searchId');
$(document).off('click', '#saveSearch');
$(document).off('click', '#updateSearch');
$(document).off('click', '#deleteSearch');
});
AJAX.registerOnload('database/qbe.js', function () {
Functions.getSqlEditor($('#textSqlquery'), {}, 'none');
$('#tblQbe').width($('#tblQbe').parent().width());
$('#tblQbeFooters').width($('#tblQbeFooters').parent().width());
$('#tblQbe').on('resize', function () {
var newWidthTblQbe = $('#textSqlquery').next().width();
$('#tblQbe').width(newWidthTblQbe);
$('#tblQbeFooters').width(newWidthTblQbe);
});
/**
* Ajax handler to check the corresponding 'show' checkbox when column is selected
*/
$(document).on('change', 'select[name^=criteriaColumn]', function () {
if ($(this).val()) {
var index = /\d+/.exec($(this).attr('name'));
$('input[name=criteriaShow\\[' + index + '\\]]').prop('checked', true);
}
});
/**
* Ajax event handlers for 'Select saved search'
*/
$(document).on('change', '#searchId', function () {
$('#action').val('load');
$('#formQBE').trigger('submit');
});
/**
* Ajax event handlers for 'Create bookmark'
*/
$(document).on('click', '#saveSearch', function () {
$('#action').val('create');
});
/**
* Ajax event handlers for 'Update bookmark'
*/
$(document).on('click', '#updateSearch', function () {
$('#action').val('update');
});
/**
* Ajax event handlers for 'Delete bookmark'
*/
$(document).on('click', '#deleteSearch', function () {
var question = Functions.sprintf(Messages.strConfirmDeleteQBESearch, $('#searchId').find('option:selected').text());
if (!confirm(question)) {
return false;
}
$('#action').val('delete');
});
var windowwidth = $(window).width();
$('.jsresponsive').css('max-width', windowwidth - 35 + 'px');
});

View file

@ -1,126 +0,0 @@
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/* global sprintf */ // js/vendor/sprintf.js
function getFormatsText() {
return {
'=': ' = \'%s\'',
'>': ' > \'%s\'',
'>=': ' >= \'%s\'',
'<': ' < \'%s\'',
'<=': ' <= \'%s\'',
'!=': ' != \'%s\'',
'LIKE': ' LIKE \'%s\'',
'LIKE %...%': ' LIKE \'%%%s%%\'',
'NOT LIKE': ' NOT LIKE \'%s\'',
'NOT LIKE %...%': ' NOT LIKE \'%%%s%%\'',
'BETWEEN': ' BETWEEN \'%s\'',
'NOT BETWEEN': ' NOT BETWEEN \'%s\'',
'IS NULL': ' \'%s\' IS NULL',
'IS NOT NULL': ' \'%s\' IS NOT NULL',
'REGEXP': ' REGEXP \'%s\'',
'REGEXP ^...$': ' REGEXP \'^%s$\'',
'NOT REGEXP': ' NOT REGEXP \'%s\''
};
}
function generateCondition(criteriaDiv, table) {
var query = '`' + Functions.escapeBacktick(table.val()) + '`.';
query += '`' + Functions.escapeBacktick(table.siblings('.columnNameSelect').first().val()) + '`';
if (criteriaDiv.find('.criteria_rhs').first().val() === 'text') {
var formatsText = getFormatsText();
query += sprintf(formatsText[criteriaDiv.find('.criteria_op').first().val()], Functions.escapeSingleQuote(criteriaDiv.find('.rhs_text_val').first().val()));
} else {
query += ' ' + criteriaDiv.find('.criteria_op').first().val();
query += ' `' + Functions.escapeBacktick(criteriaDiv.find('.tableNameSelect').first().val()) + '`.';
query += '`' + Functions.escapeBacktick(criteriaDiv.find('.columnNameSelect').first().val()) + '`';
}
return query;
}
// eslint-disable-next-line no-unused-vars
function generateWhereBlock() {
var count = 0;
var query = '';
$('.tableNameSelect').each(function () {
var criteriaDiv = $(this).siblings('.jsCriteriaOptions').first();
var useCriteria = $(this).siblings('.criteria_col').first();
if ($(this).val() !== '' && useCriteria.prop('checked')) {
if (count > 0) {
criteriaDiv.find('input.logical_op').each(function () {
if ($(this).prop('checked')) {
query += ' ' + $(this).val() + ' ';
}
});
}
query += generateCondition(criteriaDiv, $(this));
count++;
}
});
return query;
}
function generateJoin(newTable, tableAliases, fk) {
var query = '';
query += ' \n\tLEFT JOIN ' + '`' + Functions.escapeBacktick(newTable) + '`';
if (tableAliases[fk.TABLE_NAME][0] !== '') {
query += ' AS `' + Functions.escapeBacktick(tableAliases[newTable][0]) + '`';
query += ' ON `' + Functions.escapeBacktick(tableAliases[fk.TABLE_NAME][0]) + '`';
} else {
query += ' ON `' + Functions.escapeBacktick(fk.TABLE_NAME) + '`';
}
query += '.`' + fk.COLUMN_NAME + '`';
if (tableAliases[fk.REFERENCED_TABLE_NAME][0] !== '') {
query += ' = `' + Functions.escapeBacktick(tableAliases[fk.REFERENCED_TABLE_NAME][0]) + '`';
} else {
query += ' = `' + Functions.escapeBacktick(fk.REFERENCED_TABLE_NAME) + '`';
}
query += '.`' + fk.REFERENCED_COLUMN_NAME + '`';
return query;
}
function existReference(table, fk, usedTables) {
var isReferredBy = fk.TABLE_NAME === table && usedTables.includes(fk.REFERENCED_TABLE_NAME);
var isReferencedBy = fk.REFERENCED_TABLE_NAME === table && usedTables.includes(fk.TABLE_NAME);
return isReferredBy || isReferencedBy;
}
function tryJoinTable(table, tableAliases, usedTables, foreignKeys) {
for (var i = 0; i < foreignKeys.length; i++) {
var fk = foreignKeys[i];
if (existReference(table, fk, usedTables)) {
return generateJoin(table, tableAliases, fk);
}
}
return '';
}
function appendTable(table, tableAliases, usedTables, foreignKeys) {
var query = tryJoinTable(table, tableAliases, usedTables, foreignKeys);
if (query === '') {
if (usedTables.length > 0) {
query += '\n\t, ';
}
query += '`' + Functions.escapeBacktick(table) + '`';
if (tableAliases[table][0] !== '') {
query += ' AS `' + Functions.escapeBacktick(tableAliases[table][0]) + '`';
}
}
usedTables.push(table);
return query;
}
// eslint-disable-next-line no-unused-vars
function generateFromBlock(tableAliases, foreignKeys) {
var usedTables = [];
var query = '';
for (var table in tableAliases) {
if (tableAliases.hasOwnProperty(table)) {
query += appendTable(table, tableAliases, usedTables, foreignKeys);
}
}
return query;
}

View file

@ -1,914 +0,0 @@
AJAX.registerTeardown('database/routines.js', function () {
$(document).off('click', 'a.ajax.add_anchor');
$(document).off('click', 'a.ajax.edit_anchor');
$(document).off('click', 'a.ajax.exec_anchor');
$(document).off('click', 'a.ajax.export_anchor');
$(document).off('click', '#bulkActionExportButton');
$(document).off('click', 'a.ajax.drop_anchor');
$(document).off('click', '#bulkActionDropButton');
$(document).off('change', 'select[name=item_type]');
$(document).off('change', 'select[name^=item_param_type]');
$(document).off('change', 'select[name=item_returntype]');
$(document).off('click', '#addRoutineParameterButton');
$(document).off('click', 'a.routine_param_remove_anchor');
});
const DatabaseRoutines = {
/**
* @var {string} paramTemplate Template for a row in the routine editor
*/
paramTemplate: '',
/**
* @var $ajaxDialog Query object containing the reference to the
* dialog that contains the editor
*/
$ajaxDialog: null,
/**
* @var syntaxHiglighter Reference to the codemirror editor
*/
syntaxHiglighter: null,
/**
* Validate editor form fields.
*
* @return {bool}
*/
validate: function () {
/**
* @var $elm a jQuery object containing the reference
* to an element that is being validated
*/
var $elm = null;
// Common validation. At the very least the name
// and the definition must be provided for an item
$elm = $('table.rte_table').last().find('input[name=item_name]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
$elm = $('table.rte_table').find('textarea[name=item_definition]');
if ($elm.val() === '') {
if (this.syntaxHiglighter !== null) {
this.syntaxHiglighter.focus();
} else {
$('textarea[name=item_definition]').last().trigger('focus');
}
alert(Messages.strFormEmpty);
return false;
}
// The validation has so far passed, so now
// we can validate item-specific fields.
return this.validateCustom();
},
exportDialog: function ($this) {
var $msg = Functions.ajaxShowMessage();
if ($this.attr('id') === 'bulkActionExportButton') {
var combined = {
success: true,
title: Messages.strExport,
message: '',
error: ''
};
// export anchors of all selected rows
var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor');
var count = exportAnchors.length;
var returnCount = 0;
// No routine is exportable (due to privilege issues)
if (count === 0) {
Functions.ajaxShowMessage(Messages.NoExportable);
}
var p = $.when();
exportAnchors.each(function () {
var h = $(this).attr('href');
p = p.then(function () {
return $.get(h, {
'ajax_request': true
}, function (data) {
returnCount++;
if (data.success === true) {
combined.message += '\n' + data.message + '\n';
if (returnCount === count) {
showExport(combined);
}
} else {
// complain even if one export is failing
combined.success = false;
combined.error += '\n' + data.error + '\n';
if (returnCount === count) {
showExport(combined);
}
}
});
});
});
} else {
$.get($this.attr('href'), {
'ajax_request': true
}, showExport);
}
Functions.ajaxRemoveMessage($msg);
function showExport(data) {
if (data.success === true) {
Functions.ajaxRemoveMessage($msg);
/**
* @var buttonOptions Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-primary',
click: function () {
$(this).dialog('close').remove();
}
}
};
/**
* Display the dialog to the user
*/
data.message = '<textarea cols="40" rows="15" class="w-100">' + data.message + '</textarea>';
var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 500,
buttons: buttonOptions,
title: data.title
});
// Attach syntax highlighted editor to export dialog
/**
* @var $elm jQuery object containing the reference
* to the Export textarea.
*/
var $elm = $ajaxDialog.find('textarea');
Functions.getSqlEditor($elm);
} else {
Functions.ajaxShowMessage(data.error, false);
}
} // end showExport()
},
// end exportDialog()
editorDialog: function (isNew, $this) {
var that = this;
/**
* @var $edit_row jQuery object containing the reference to
* the row of the the item being edited
* from the list of items
*/
var $editRow = null;
if ($this.hasClass('edit_anchor')) {
// Remember the row of the item being edited for later,
// so that if the edit is successful, we can replace the
// row with info about the modified item.
$editRow = $this.parents('tr');
}
/**
* @var $msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage();
$.get($this.attr('href'), {
'ajax_request': true
}, function (data) {
if (data.success === true) {
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary'
},
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-secondary'
}
};
// We have successfully fetched the editor form
Functions.ajaxRemoveMessage($msg);
// Now define the function that is called when
// the user presses the "Go" button
buttonOptions[Messages.strGo].click = function () {
// Move the data from the codemirror editor back to the
// textarea, where it can be used in the form submission.
if (typeof CodeMirror !== 'undefined') {
that.syntaxHiglighter.save();
}
// Validate editor and submit request, if passed.
if (that.validate()) {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $('form.rte_form').last().serialize();
$msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var url = $('form.rte_form').last().attr('action');
$.post(url, data, function (data) {
if (data.success === true) {
// Item created successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
that.$ajaxDialog.dialog('close');
var tableId = '#' + data.tableType + 'Table';
// If we are in 'edit' mode, we must
// remove the reference to the old row.
if (mode === 'edit' && $editRow !== null) {
$editRow.remove();
}
// Sometimes, like when moving a trigger from
// a table to another one, the new row should
// not be inserted into the list. In this case
// "data.insert" will be set to false.
if (data.insert) {
// Insert the new row at the correct
// location in the list of items
/**
* @var text Contains the name of an item from
* the list that is used in comparisons
* to find the correct location where
* to insert a new row.
*/
var text = '';
/**
* @var inserted Whether a new item has been
* inserted in the list or not
*/
var inserted = false;
$(tableId + '.data').find('tr').each(function () {
text = $(this).children('td').eq(0).find('strong').text().toUpperCase().trim();
if (text !== '' && text > data.name) {
$(this).before(data.new_row);
inserted = true;
return false;
}
});
if (!inserted) {
// If we didn't manage to insert the row yet,
// it must belong at the end of the list,
// so we insert it there.
$(tableId + '.data').append(data.new_row);
}
// Fade-in the new row
$('tr.ajaxInsert').show('slow').removeClass('ajaxInsert');
} else if ($(tableId + '.data').find('tr').has('td').length === 0) {
// If we are not supposed to insert the new row,
// we will now check if the table is empty and
// needs to be hidden. This will be the case if
// we were editing the only item in the list,
// which we removed and will not be inserting
// something else in its place.
$(tableId + '.data').hide('slow', function () {
$('#nothing2display').show('slow');
});
}
// Now we have inserted the row at the correct
// position, but surely at least some row classes
// are wrong now. So we will iterate through
// all rows and assign correct classes to them
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$(tableId + '.data').find('tr').has('td').each(function () {
rowclass = ct % 2 === 0 ? 'odd' : 'even';
$(this).removeClass('odd even').addClass(rowclass);
ct++;
});
// If this is the first item being added, remove
// the "No items" message and show the list.
if ($(tableId + '.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible')) {
$('#nothing2display').hide('slow', function () {
$(tableId + '.data').show('slow');
});
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
} // end "if (that.validate())"
}; // end of function that handles the submission of the Editor
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close');
};
/**
* Display the dialog to the user
*/
that.$ajaxDialog = $('<div id="rteDialog">' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
height: 400,
width: 700,
minWidth: 500,
buttons: buttonOptions,
// Issue #15810 - use button titles for modals (eg: new procedure)
// Respect the order: title on href tag, href content, title sent in response
title: $this.attr('title') || $this.text() || $(data.title).text(),
modal: true,
open: function () {
$('#rteDialog').dialog('option', 'max-height', $(window).height());
if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) {
$('#rteDialog').dialog('option', 'height', $(window).height());
}
$(this).find('input[name=item_name]').trigger('focus');
$(this).find('input.datefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'date');
});
$(this).find('input.datetimefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'datetime');
});
$.datepicker.initialized = false;
},
close: function () {
$(this).remove();
}
});
/**
* @var mode Used to remember whether the editor is in
* "Edit" or "Add" mode
*/
var mode = 'add';
if ($('input[name=editor_process_edit]').length > 0) {
mode = 'edit';
}
// Attach syntax highlighted editor to the definition
/**
* @var elm jQuery object containing the reference to
* the Definition textarea.
*/
var $elm = $('textarea[name=item_definition]').last();
var linterOptions = {};
linterOptions.routineEditor = true;
that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions);
// Execute item-specific code
that.postDialogShow(data);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.get()
},
dropDialog: function ($this) {
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $this.parents('tr');
/**
* @var question String containing the question to be asked for confirmation
*/
var question = $('<div></div>').text($currRow.children('td').children('.drop_sql').html());
// We ask for confirmation first here, before submitting the ajax request
$this.confirm(question, $this.attr('href'), function (url) {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $this.getPostData());
$.post(url, params, function (data) {
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent().parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('slow', function () {
$(this).remove();
// Now we have removed the row from the list, but maybe
// some row classes are wrong now. So we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = ct % 2 === 1 ? 'odd' : 'even';
$(this).removeClass('odd even').addClass(rowclass);
ct++;
});
});
}
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
// Show the query that we just executed
Functions.slidingMessage(data.sql_query);
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
},
dropMultipleDialog: function ($this) {
// We ask for confirmation here
$this.confirm(Messages.strDropRTEitems, '', function () {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
// drop anchors of all selected rows
var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor');
var success = true;
var count = dropAnchors.length;
var returnCount = 0;
dropAnchors.each(function () {
var $anchor = $(this);
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $anchor.parents('tr');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
$.post($anchor.attr('href'), params, function (data) {
returnCount++;
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent().parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('fast', function () {
// we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = ct % 2 === 1 ? 'odd' : 'even';
$(this).removeClass('odd even').addClass(rowclass);
ct++;
});
});
$currRow.remove();
}
if (returnCount === count) {
if (success) {
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
$('#rteListForm_checkall').prop({
checked: false,
indeterminate: false
});
}
Navigation.reload();
}
} else {
Functions.ajaxShowMessage(data.error, false);
success = false;
if (returnCount === count) {
Navigation.reload();
}
}
}); // end $.post()
}); // end drop_anchors.each()
});
},
/**
* Execute some code after the ajax dialog for the editor is shown.
*
* @param data JSON-encoded data from the ajax request
*/
postDialogShow: function (data) {
// Cache the template for a parameter table row
DatabaseRoutines.paramTemplate = data.paramTemplate;
var that = this;
// Make adjustments in the dialog to make it AJAX compatible
$('td.routine_param_remove').show();
// Enable/disable the 'options' dropdowns for parameters as necessary
$('table.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1');
$('table.routine_params_table').last().find('tr').has('td').each(function () {
that.setOptionsForParameter($(this).find('select[name^=item_param_type]'), $(this).find('input[name^=item_param_length]'), $(this).find('select[name^=item_param_opts_text]'), $(this).find('select[name^=item_param_opts_num]'));
});
// Enable/disable the 'options' dropdowns for
// function return value as necessary
this.setOptionsForParameter($('table.rte_table').last().find('select[name=item_returntype]'), $('table.rte_table').last().find('input[name=item_returnlength]'), $('table.rte_table').last().find('select[name=item_returnopts_text]'), $('table.rte_table').last().find('select[name=item_returnopts_num]'));
// Allow changing parameter order
$('.routine_params_table tbody').sortable({
containment: '.routine_params_table tbody',
handle: '.dragHandle',
stop: function () {
that.reindexParameters();
}
});
},
/**
* Reindexes the parameters after dropping a parameter or reordering parameters
*/
reindexParameters: function () {
/**
* @var index Counter used for reindexing the input
* fields in the routine parameters table
*/
var index = 0;
$('table.routine_params_table tbody').find('tr').each(function () {
$(this).find(':input').each(function () {
/**
* @var inputname The value of the name attribute of
* the input field being reindexed
*/
var inputname = $(this).attr('name');
if (inputname.substr(0, 14) === 'item_param_dir') {
$(this).attr('name', inputname.substr(0, 14) + '[' + index + ']');
} else if (inputname.substr(0, 15) === 'item_param_name') {
$(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
} else if (inputname.substr(0, 15) === 'item_param_type') {
$(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
} else if (inputname.substr(0, 17) === 'item_param_length') {
$(this).attr('name', inputname.substr(0, 17) + '[' + index + ']');
$(this).attr('id', 'item_param_length_' + index);
} else if (inputname.substr(0, 20) === 'item_param_opts_text') {
$(this).attr('name', inputname.substr(0, 20) + '[' + index + ']');
} else if (inputname.substr(0, 19) === 'item_param_opts_num') {
$(this).attr('name', inputname.substr(0, 19) + '[' + index + ']');
}
});
index++;
});
},
/**
* Validate custom editor form fields.
*
* @return {bool}
*/
validateCustom: function () {
/**
* @var isSuccess Stores the outcome of the validation
*/
var isSuccess = true;
/**
* @var inputname The value of the "name" attribute for
* the field that is being processed
*/
var inputname = '';
this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
// Every parameter of a routine must have
// a non-empty direction, name and type
if (isSuccess) {
$(this).find(':input').each(function () {
inputname = $(this).attr('name');
if (inputname.substr(0, 14) === 'item_param_dir' || inputname.substr(0, 15) === 'item_param_name' || inputname.substr(0, 15) === 'item_param_type') {
if ($(this).val() === '') {
$(this).trigger('focus');
isSuccess = false;
return false;
}
}
});
} else {
return false;
}
});
if (!isSuccess) {
alert(Messages.strFormEmpty);
return false;
}
this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
// SET, ENUM, VARCHAR and VARBINARY fields must have length/values
var $inputtyp = $(this).find('select[name^=item_param_type]');
var $inputlen = $(this).find('input[name^=item_param_length]');
if ($inputtyp.length && $inputlen.length) {
if (($inputtyp.val() === 'ENUM' || $inputtyp.val() === 'SET' || $inputtyp.val().substr(0, 3) === 'VAR') && $inputlen.val() === '') {
$inputlen.trigger('focus');
isSuccess = false;
return false;
}
}
});
if (!isSuccess) {
alert(Messages.strFormEmpty);
return false;
}
if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
// The length/values of return variable for functions must
// be set, if the type is SET, ENUM, VARCHAR or VARBINARY.
var $returntyp = this.$ajaxDialog.find('select[name=item_returntype]');
var $returnlen = this.$ajaxDialog.find('input[name=item_returnlength]');
if (($returntyp.val() === 'ENUM' || $returntyp.val() === 'SET' || $returntyp.val().substr(0, 3) === 'VAR') && $returnlen.val() === '') {
$returnlen.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
}
if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
// A function must contain a RETURN statement in its definition
if (this.$ajaxDialog.find('table.rte_table').find('textarea[name=item_definition]').val().toUpperCase().indexOf('RETURN') < 0) {
this.syntaxHiglighter.focus();
alert(Messages.MissingReturn);
return false;
}
}
return true;
},
/**
* Enable/disable the "options" dropdown and "length" input for
* parameters and the return variable in the routine editor
* as necessary.
*
* @param $type a jQuery object containing the reference
* to the "Type" dropdown box
* @param $len a jQuery object containing the reference
* to the "Length" input box
* @param $text a jQuery object containing the reference
* to the dropdown box with options for
* parameters of text type
* @param $num a jQuery object containing the reference
* to the dropdown box with options for
* parameters of numeric type
*/
setOptionsForParameter: function ($type, $len, $text, $num) {
/**
* @var no_opts a jQuery object containing the reference
* to an element to be displayed when no
* options are available
*/
var $noOpts = $text.parent().parent().find('.no_opts');
/**
* @var no_len a jQuery object containing the reference
* to an element to be displayed when no
* "length/values" field is available
*/
var $noLen = $len.parent().parent().find('.no_len');
// Process for parameter options
switch ($type.val()) {
case 'TINYINT':
case 'SMALLINT':
case 'MEDIUMINT':
case 'INT':
case 'BIGINT':
case 'DECIMAL':
case 'FLOAT':
case 'DOUBLE':
case 'REAL':
$text.parent().hide();
$num.parent().show();
$noOpts.hide();
break;
case 'TINYTEXT':
case 'TEXT':
case 'MEDIUMTEXT':
case 'LONGTEXT':
case 'CHAR':
case 'VARCHAR':
case 'SET':
case 'ENUM':
$text.parent().show();
$num.parent().hide();
$noOpts.hide();
break;
default:
$text.parent().hide();
$num.parent().hide();
$noOpts.show();
break;
}
// Process for parameter length
switch ($type.val()) {
case 'DATE':
case 'TINYBLOB':
case 'TINYTEXT':
case 'BLOB':
case 'TEXT':
case 'MEDIUMBLOB':
case 'MEDIUMTEXT':
case 'LONGBLOB':
case 'LONGTEXT':
$text.closest('tr').find('a').first().hide();
$len.parent().hide();
$noLen.show();
break;
default:
if ($type.val() === 'ENUM' || $type.val() === 'SET') {
$text.closest('tr').find('a').first().show();
} else {
$text.closest('tr').find('a').first().hide();
}
$len.parent().show();
$noLen.hide();
break;
}
},
executeDialog: function ($this) {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage();
var params = Functions.getJsConfirmCommonParam($this[0], $this.getPostData());
$.post($this.attr('href'), params, function (data) {
if (data.success === true) {
Functions.ajaxRemoveMessage($msg);
// If 'data.dialog' is true we show a dialog with a form
// to get the input parameters for routine, otherwise
// we just show the results of the query
if (data.dialog) {
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary'
},
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-secondary'
}
};
// Define the function that is called when
// the user presses the "Go" button
buttonOptions[Messages.strGo].click = function () {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $('form.rte_form').last().serialize();
$msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
$.post('index.php?route=/database/routines', data, function (data) {
if (data.success === true) {
// Routine executed successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
$ajaxDialog.dialog('close');
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
};
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close');
};
/**
* Display the dialog to the user
*/
var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 650,
buttons: buttonOptions,
title: data.title,
modal: true,
close: function () {
$(this).remove();
}
});
$ajaxDialog.find('input[name^=params]').first().trigger('focus');
/**
* Attach the datepickers to the relevant form fields
*/
$ajaxDialog.find('input.datefield, input.datetimefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'));
});
/*
* Define the function if the user presses enter
*/
$('form.rte_form').on('keyup', function (event) {
event.preventDefault();
if (event.keyCode === 13) {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $(this).serialize();
$msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var url = $(this).attr('action');
$.post(url, data, function (data) {
if (data.success === true) {
// Routine executed successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
$('form.rte_form').off('keyup');
$ajaxDialog.remove();
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
}
});
} else {
// Routine executed successfully
Functions.slidingMessage(data.message);
}
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}
};
AJAX.registerOnload('database/routines.js', function () {
$(document).on('click', 'a.ajax.add_anchor', function (event) {
event.preventDefault();
$.datepicker.initialized = false;
DatabaseRoutines.editorDialog(true, $(this));
});
$(document).on('click', 'a.ajax.edit_anchor', function (event) {
event.preventDefault();
DatabaseRoutines.editorDialog(false, $(this));
});
$(document).on('click', 'a.ajax.exec_anchor', function (event) {
event.preventDefault();
DatabaseRoutines.executeDialog($(this));
});
$(document).on('click', 'a.ajax.export_anchor', function (event) {
event.preventDefault();
DatabaseRoutines.exportDialog($(this));
});
$(document).on('click', '#bulkActionExportButton', function (event) {
event.preventDefault();
DatabaseRoutines.exportDialog($(this));
});
$(document).on('click', 'a.ajax.drop_anchor', function (event) {
event.preventDefault();
DatabaseRoutines.dropDialog($(this));
});
$(document).on('click', '#bulkActionDropButton', function (event) {
event.preventDefault();
DatabaseRoutines.dropMultipleDialog($(this));
});
$(document).on('change', 'select[name=item_type]', function () {
$(this).closest('table').find('tr.routine_return_row, .routine_direction_cell').toggle();
});
$(document).on('change', 'select[name^=item_param_type]', function () {
const $row = $(this).parents('tr').first();
DatabaseRoutines.setOptionsForParameter($row.find('select[name^=item_param_type]'), $row.find('input[name^=item_param_length]'), $row.find('select[name^=item_param_opts_text]'), $row.find('select[name^=item_param_opts_num]'));
});
$(document).on('change', 'select[name=item_returntype]', function () {
const $table = $(this).closest('table.rte_table');
DatabaseRoutines.setOptionsForParameter($table.find('select[name=item_returntype]'), $table.find('input[name=item_returnlength]'), $table.find('select[name=item_returnopts_text]'), $table.find('select[name=item_returnopts_num]'));
});
$(document).on('click', '#addRoutineParameterButton', function (event) {
event.preventDefault();
/**
* @var routine_params_table jQuery object containing the reference
* to the routine parameters table
*/
const $routineParamsTable = $(this).closest('div.ui-dialog').find('.routine_params_table');
/**
* @var new_param_row A string containing the HTML code for the
* new row for the routine parameters table
*/
const newParamRow = DatabaseRoutines.paramTemplate.replace(/%s/g, $routineParamsTable.find('tr').length - 1);
// Append the new row to the parameters table
$routineParamsTable.append(newParamRow);
// Make sure that the row is correctly shown according to the type of routine
if ($(this).closest('div.ui-dialog').find('table.rte_table select[name=item_type]').val() === 'FUNCTION') {
$('tr.routine_return_row').show();
$('td.routine_direction_cell').hide();
}
/**
* @var newrow jQuery object containing the reference to the newly
* inserted row in the routine parameters table
*/
const $newrow = $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').last();
// Enable/disable the 'options' dropdowns for parameters as necessary
DatabaseRoutines.setOptionsForParameter($newrow.find('select[name^=item_param_type]'), $newrow.find('input[name^=item_param_length]'), $newrow.find('select[name^=item_param_opts_text]'), $newrow.find('select[name^=item_param_opts_num]'));
});
$(document).on('click', 'a.routine_param_remove_anchor', function (event) {
event.preventDefault();
$(this).parent().parent().remove();
// After removing a parameter, the indices of the name attributes in
// the input fields lose the correct order and need to be reordered.
DatabaseRoutines.reindexParameters();
});
});

View file

@ -1,240 +0,0 @@
/**
* JavaScript functions used on Database Search page
*
* @requires jQuery
* @requires js/functions.js
*
* @package PhpMyAdmin
*/
/* global makeGrid */ // js/makegrid.js
/**
* AJAX script for the Database Search page.
*
* Actions ajaxified here:
* Retrieve result of SQL query
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/search.js', function () {
$('a.browse_results').off('click');
$('a.delete_results').off('click');
$('#buttonGo').off('click');
$('#togglesearchresultlink').off('click');
$('#togglequerybox').off('click');
$('#togglesearchformlink').off('click');
$('#select_all').off('click');
$('#unselect_all').off('click');
$(document).off('submit', '#db_search_form.ajax');
});
AJAX.registerOnload('database/search.js', function () {
/** Hide the table link in the initial search result */
var icon = Functions.getImage('s_tbl', '', {
'id': 'table-image'
}).toString();
$('#table-info').prepend(icon).hide();
/** Hide the browse and deleted results in the new search criteria */
$('#buttonGo').on('click', function () {
$('#table-info').hide();
$('#browse-results').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
});
/**
* Prepare a div containing a link for toggle the search results
*/
$('#togglesearchresultsdiv')
/** don't show it until we have results on-screen */.hide();
/**
* Changing the displayed text according to
* the hide/show criteria in search result forms
*/
$('#togglesearchresultlink').html(Messages.strHideSearchResults).on('click', function () {
var $link = $(this);
$('#searchresults').slideToggle();
if ($link.text() === Messages.strHideSearchResults) {
$link.text(Messages.strShowSearchResults);
} else {
$link.text(Messages.strHideSearchResults);
}
/** avoid default click action */
return false;
});
/**
* Prepare a div containing a link for toggle the search form,
* otherwise it's incorrectly displayed after a couple of clicks
*/
$('#togglesearchformdiv').hide(); // don't show it until we have results on-screen
/**
* Changing the displayed text according to
* the hide/show criteria in search form
*/
$('#togglequerybox').hide().on('click', function () {
var $link = $(this);
$('#sqlqueryform').slideToggle('medium');
if ($link.text() === Messages.strHideQueryBox) {
$link.text(Messages.strShowQueryBox);
} else {
$link.text(Messages.strHideQueryBox);
}
/** avoid default click action */
return false;
});
/** don't show it until we have results on-screen */
/**
* Changing the displayed text according to
* the hide/show criteria in search criteria form
*/
$('#togglesearchformlink').html(Messages.strShowSearchCriteria).on('click', function () {
var $link = $(this);
$('#db_search_form').slideToggle();
if ($link.text() === Messages.strHideSearchCriteria) {
$link.text(Messages.strShowSearchCriteria);
} else {
$link.text(Messages.strHideSearchCriteria);
}
/** avoid default click action */
return false;
});
/*
* Ajax Event handler for retrieving the results from a table
*/
$(document).on('click', 'a.browse_results', function (e) {
e.preventDefault();
/** Hides the results shown by the delete criteria */
var $msg = Functions.ajaxShowMessage(Messages.strBrowsing, false);
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Load the browse results to the page */
$('#table-info').show();
var tableName = $(this).data('table-name');
$('#table-link').attr({
'href': $(this).attr('href')
}).text(tableName);
var url = $(this).attr('href') + '#searchresults';
var browseSql = $(this).data('browse-sql');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query': browseSql
};
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
$('#browse-results').html(data.message);
Functions.ajaxRemoveMessage($msg);
$('.table_results').each(function () {
makeGrid(this, true, true, true, true);
});
$('#browse-results').show();
Functions.highlightSql($('#browse-results'));
$('html, body').animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
/*
* Ajax Event handler for deleting the results from a table
*/
$(document).on('click', 'a.delete_results', function (e) {
e.preventDefault();
/** Hides the results shown by the browse criteria */
$('#table-info').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Conformation message for deletion */
var msg = Functions.sprintf(Messages.strConfirmDeleteResults, $(this).data('table-name'));
if (confirm(msg)) {
var $msg = Functions.ajaxShowMessage(Messages.strDeleting, false);
/** Load the deleted option to the page*/
$('#sqlqueryform').html('');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query': $(this).data('delete-sql')
};
var url = $(this).attr('href');
$.post(url, params, function (data) {
if (typeof data === 'undefined' || !data.success) {
Functions.ajaxShowMessage(data.error, false);
return;
}
$('#sqlqueryform').html(data.sql_query);
/** Refresh the search results after the deletion */
$('#buttonGo').trigger('click');
$('#togglequerybox').html(Messages.strHideQueryBox);
/** Show the results of the deletion option */
$('#browse-results').hide();
$('#sqlqueryform').show();
$('#togglequerybox').show();
$('html, body').animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
Functions.ajaxRemoveMessage($msg);
});
}
});
/**
* Ajax Event handler for retrieving the result of an SQL Query
*/
$(document).on('submit', '#db_search_form.ajax', function (event) {
event.preventDefault();
if ($('#criteriaTables :selected').length === 0) {
Functions.ajaxShowMessage(Messages.strNoTableSelected);
return;
}
var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false);
// jQuery object to reuse
var $form = $(this);
Functions.prepareForAjaxRequest($form);
var url = $form.serialize() + CommonParams.get('arg_separator') + 'submit_search=' + $('#buttonGo').val();
$.post($form.attr('action'), url, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
// found results
$('#searchresults').html(data.message);
$('#togglesearchresultlink')
// always start with the Show message
.text(Messages.strHideSearchResults);
$('#togglesearchresultsdiv')
// now it's time to show the div containing the link
.show();
$('#searchresults').show();
$('#db_search_form')
// workaround for Chrome problem (bug #3168569)
.slideToggle().hide();
$('#togglesearchformlink')
// always start with the Show message
.text(Messages.strShowSearchCriteria);
$('#togglesearchformdiv')
// now it's time to show the div containing the link
.show();
} else {
// error message (zero rows)
$('#searchresults').html(data.error).show();
}
Functions.ajaxRemoveMessage($msgbox);
});
});
$('#select_all').on('click', function () {
Functions.setSelectOptions('db_search', 'criteriaTables[]', true);
return false;
});
$('#unselect_all').on('click', function () {
Functions.setSelectOptions('db_search', 'criteriaTables[]', false);
return false;
});
}); // end $()

View file

@ -1,387 +0,0 @@
/**
* @fileoverview functions used on the database structure page
* @name Database Structure
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
var DatabaseStructure = {};
/**
* AJAX scripts for /database/structure
*
* Actions ajaxified here:
* Drop Database
* Truncate Table
* Drop Table
*
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/structure.js', function () {
$(document).off('click', 'a.truncate_table_anchor.ajax');
$(document).off('click', 'a.drop_table_anchor.ajax');
$(document).off('click', '#real_end_input');
$(document).off('click', 'a.favorite_table_anchor.ajax');
$('a.real_row_count').off('click');
$('a.row_count_sum').off('click');
$('select[name=submit_mult]').off('change');
});
/**
* Adjust number of rows and total size in the summary
* when truncating, creating, dropping or inserting into a table
*/
DatabaseStructure.adjustTotals = function () {
var byteUnits = [Messages.strB, Messages.strKiB, Messages.strMiB, Messages.strGiB, Messages.strTiB, Messages.strPiB, Messages.strEiB];
/**
* @var $allTr jQuery object that references all the rows in the list of tables
*/
var $allTr = $('#tablesForm').find('table.data tbody').first().find('tr');
// New summary values for the table
var tableSum = $allTr.length;
var rowsSum = 0;
var sizeSum = 0;
var overheadSum = 0;
var rowSumApproximated = false;
$allTr.each(function () {
var $this = $(this);
var i;
var tmpVal;
// Get the number of rows for this SQL table
var strRows = $this.find('.tbl_rows').text();
// If the value is approximated
if (strRows.indexOf('~') === 0) {
rowSumApproximated = true;
// The approximated value contains a preceding ~ (Eg 100 --> ~100)
strRows = strRows.substring(1, strRows.length);
}
strRows = strRows.replace(/[,.\s]/g, '');
var intRow = parseInt(strRows, 10);
if (!isNaN(intRow)) {
rowsSum += intRow;
}
// Extract the size and overhead
var valSize = 0;
var valOverhead = 0;
var strSize = $this.find('.tbl_size span:not(.unit)').text().trim();
var strSizeUnit = $this.find('.tbl_size span.unit').text().trim();
var strOverhead = $this.find('.tbl_overhead span:not(.unit)').text().trim();
var strOverheadUnit = $this.find('.tbl_overhead span.unit').text().trim();
// Given a value and a unit, such as 100 and KiB, for the table size
// and overhead calculate their numeric values in bytes, such as 102400
for (i = 0; i < byteUnits.length; i++) {
if (strSizeUnit === byteUnits[i]) {
tmpVal = parseFloat(strSize);
valSize = tmpVal * Math.pow(1024, i);
break;
}
}
for (i = 0; i < byteUnits.length; i++) {
if (strOverheadUnit === byteUnits[i]) {
tmpVal = parseFloat(strOverhead);
valOverhead = tmpVal * Math.pow(1024, i);
break;
}
}
sizeSum += valSize;
overheadSum += valOverhead;
});
// Add some commas for readability:
// 1000000 becomes 1,000,000
var strRowSum = rowsSum + '';
var regex = /(\d+)(\d{3})/;
while (regex.test(strRowSum)) {
strRowSum = strRowSum.replace(regex, '$1' + ',' + '$2');
}
// If approximated total value add ~ in front
if (rowSumApproximated) {
strRowSum = '~' + strRowSum;
}
// Calculate the magnitude for the size and overhead values
var sizeMagnitude = 0;
var overheadMagnitude = 0;
while (sizeSum >= 1024) {
sizeSum /= 1024;
sizeMagnitude++;
}
while (overheadSum >= 1024) {
overheadSum /= 1024;
overheadMagnitude++;
}
sizeSum = Math.round(sizeSum * 10) / 10;
overheadSum = Math.round(overheadSum * 10) / 10;
// Update summary with new data
var $summary = $('#tbl_summary_row');
$summary.find('.tbl_num').text(Functions.sprintf(Messages.strNTables, tableSum));
if (rowSumApproximated) {
$summary.find('.row_count_sum').text(strRowSum);
} else {
$summary.find('.tbl_rows').text(strRowSum);
}
$summary.find('.tbl_size').text(sizeSum + ' ' + byteUnits[sizeMagnitude]);
$summary.find('.tbl_overhead').text(overheadSum + ' ' + byteUnits[overheadMagnitude]);
};
/**
* Gets the real row count for a table or DB.
* @param {object} $target Target for appending the real count value.
*/
DatabaseStructure.fetchRealRowCount = function ($target) {
var $throbber = $('#pma_navigation').find('.throbber').first().clone().css({
visibility: 'visible',
display: 'inline-block'
}).on('click', false);
$target.html($throbber);
$.ajax({
type: 'GET',
url: $target.attr('href'),
cache: false,
dataType: 'json',
success: function (response) {
if (response.success) {
// If to update all row counts for a DB.
if (response.real_row_count_all) {
$.each(JSON.parse(response.real_row_count_all), function (index, table) {
// Update each table row count.
$('table.data td[data-table*="' + table.table + '"]').text(table.row_count);
});
}
// If to update a particular table's row count.
if (response.real_row_count) {
// Append the parent cell with real row count.
$target.parent().text(response.real_row_count);
}
// Adjust the 'Sum' displayed at the bottom.
DatabaseStructure.adjustTotals();
} else {
Functions.ajaxShowMessage(Messages.strErrorRealRowCount);
}
},
error: function () {
Functions.ajaxShowMessage(Messages.strErrorRealRowCount);
}
});
};
AJAX.registerOnload('database/structure.js', function () {
/**
* Event handler on select of "Make consistent with central list"
*/
$('select[name=submit_mult]').on('change', function (event) {
var url = 'index.php?route=/database/structure';
var action = $(this).val();
if (action === 'make_consistent_with_central_list') {
event.preventDefault();
event.stopPropagation();
$('#makeConsistentWithCentralListModal').modal('show').on('shown.bs.modal', function () {
$('#makeConsistentWithCentralListContinue').on('click', function () {
const $form = $('#tablesForm');
const argSep = CommonParams.get('arg_separator');
const data = $form.serialize() + argSep + 'ajax_request=true' + argSep + 'ajax_page_request=true';
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post('index.php?route=/database/structure/central-columns/make-consistent', data, AJAX.responseHandler);
$('#makeConsistentWithCentralListModal').modal('hide');
});
});
return;
}
if (action === 'copy_tbl' || action === 'add_prefix_tbl' || action === 'replace_prefix_tbl' || action === 'copy_tbl_change_prefix') {
event.preventDefault();
event.stopPropagation();
if ($('input[name="selected_tbl[]"]:checked').length === 0) {
return false;
}
var formData = $('#tablesForm').serialize();
var modalTitle = '';
if (action === 'copy_tbl') {
url = 'index.php?route=/database/structure/copy-form';
modalTitle = Messages.strCopyTablesTo;
} else if (action === 'add_prefix_tbl') {
url = 'index.php?route=/database/structure/add-prefix';
modalTitle = Messages.strAddPrefix;
} else if (action === 'replace_prefix_tbl') {
url = 'index.php?route=/database/structure/change-prefix-form';
modalTitle = Messages.strReplacePrefix;
} else if (action === 'copy_tbl_change_prefix') {
url = 'index.php?route=/database/structure/change-prefix-form';
modalTitle = Messages.strCopyPrefix;
}
$.ajax({
type: 'POST',
url: url,
dataType: 'html',
data: formData
}).done(function (modalBody) {
const bulkActionModal = $('#bulkActionModal');
bulkActionModal.on('show.bs.modal', function () {
this.querySelector('.modal-title').innerText = modalTitle;
this.querySelector('.modal-body').innerHTML = modalBody;
});
bulkActionModal.modal('show').on('shown.bs.modal', function () {
$('#bulkActionContinue').on('click', function () {
$('#ajax_form').trigger('submit');
$('#bulkActionModal').modal('hide');
});
});
});
return;
}
if (action === 'analyze_tbl') {
url = 'index.php?route=/table/maintenance/analyze';
} else if (action === 'sync_unique_columns_central_list') {
url = 'index.php?route=/database/structure/central-columns/add';
} else if (action === 'delete_unique_columns_central_list') {
url = 'index.php?route=/database/structure/central-columns/remove';
} else if (action === 'check_tbl') {
url = 'index.php?route=/table/maintenance/check';
} else if (action === 'checksum_tbl') {
url = 'index.php?route=/table/maintenance/checksum';
} else if (action === 'drop_tbl') {
url = 'index.php?route=/database/structure/drop-form';
} else if (action === 'empty_tbl') {
url = 'index.php?route=/database/structure/empty-form';
} else if (action === 'export') {
url = 'index.php?route=/export/tables';
} else if (action === 'optimize_tbl') {
url = 'index.php?route=/table/maintenance/optimize';
} else if (action === 'repair_tbl') {
url = 'index.php?route=/table/maintenance/repair';
} else if (action === 'show_create') {
url = 'index.php?route=/database/structure/show-create';
} else {
$('#tablesForm').trigger('submit');
return;
}
var $form = $(this).parents('form');
var argsep = CommonParams.get('arg_separator');
var data = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post(url, data, AJAX.responseHandler);
});
/**
* Ajax Event handler for 'Truncate Table'
*/
$(document).on('click', 'a.truncate_table_anchor.ajax', function (event) {
event.preventDefault();
/**
* @var $this_anchor Object referring to the anchor clicked
*/
var $thisAnchor = $(this);
// extract current table name and build the question string
/**
* @var curr_table_name String containing the name of the table to be truncated
*/
var currTableName = $thisAnchor.parents('tr').children('th').children('a').text();
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strTruncateTableStrongWarning + ' ' + Functions.sprintf(Messages.strDoYouReally, 'TRUNCATE `' + Functions.escapeHtml(currTableName) + '`') + Functions.getForeignKeyCheckboxLoader();
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
// Adjust table statistics
var $tr = $thisAnchor.closest('tr');
$tr.find('.tbl_rows').text('0');
$tr.find('.tbl_size, .tbl_overhead').text('-');
DatabaseStructure.adjustTotals();
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, Functions.loadForeignKeyCheckbox);
}); // end of Truncate Table Ajax action
/**
* Ajax Event handler for 'Drop Table' or 'Drop View'
*/
$(document).on('click', 'a.drop_table_anchor.ajax', function (event) {
event.preventDefault();
var $thisAnchor = $(this);
// extract current table name and build the question string
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $thisAnchor.parents('tr');
/**
* @var curr_table_name String containing the name of the table to be truncated
*/
var currTableName = $currRow.children('th').children('a').text();
/**
* @var is_view Boolean telling if we have a view
*/
var isView = $currRow.hasClass('is_view') || $thisAnchor.hasClass('view');
/**
* @var question String containing the question to be asked for confirmation
*/
var question;
if (!isView) {
question = Messages.strDropTableStrongWarning + ' ' + Functions.sprintf(Messages.strDoYouReally, 'DROP TABLE `' + Functions.escapeHtml(currTableName) + '`');
} else {
question = Functions.sprintf(Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(currTableName) + '`');
}
question += Functions.getForeignKeyCheckboxLoader();
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
$currRow.hide('medium').remove();
DatabaseStructure.adjustTotals();
Navigation.reload();
Functions.ajaxRemoveMessage($msg);
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, Functions.loadForeignKeyCheckbox);
}); // end of Drop Table Ajax action
// Calculate Real End for InnoDB
/**
* Ajax Event handler for calculating the real end for a InnoDB table
*
*/
$(document).on('click', '#real_end_input', function (event) {
event.preventDefault();
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strOperationTakesLongTime;
$(this).confirm(question, '', function () {
return true;
});
return false;
}); // end Calculate Real End for InnoDB
// Add tooltip to favorite icons.
$('.favorite_table_anchor').each(function () {
Functions.tooltip($(this), 'a', $(this).attr('title'));
});
// Get real row count via Ajax.
$('a.real_row_count').on('click', function (event) {
event.preventDefault();
DatabaseStructure.fetchRealRowCount($(this));
});
// Get all real row count.
$('a.row_count_sum').on('click', function (event) {
event.preventDefault();
DatabaseStructure.fetchRealRowCount($(this));
});
});

View file

@ -1,104 +0,0 @@
/**
* Unbind all event handlers before tearing down the page
*/
AJAX.registerTeardown('database/tracking.js', function () {
$('body').off('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]');
$('body').off('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]');
$('body').off('click', 'a.delete_tracking_anchor.ajax');
});
/**
* Bind event handlers
*/
AJAX.registerOnload('database/tracking.js', function () {
var $versions = $('#versions');
$versions.find('tr').first().find('th').append($('<div class="sorticon"></div>'));
$versions.tablesorter({
sortList: [[1, 0]],
headers: {
0: {
sorter: false
},
2: {
sorter: 'integer'
},
5: {
sorter: false
},
6: {
sorter: false
},
7: {
sorter: false
}
}
});
var $noVersions = $('#noversions');
$noVersions.find('tr').first().find('th').append($('<div class="sorticon"></div>'));
$noVersions.tablesorter({
sortList: [[1, 0]],
headers: {
0: {
sorter: false
},
2: {
sorter: false
}
}
});
var $body = $('body');
/**
* Handles multi submit for tracked tables
*/
$body.on('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
if ($button.val() === 'delete_tracking') {
var question = Messages.strDeleteTrackingDataMultiple;
$button.confirm(question, $form.attr('action'), function (url) {
Functions.ajaxShowMessage(Messages.strDeletingTrackingData);
AJAX.source = $form;
$.post(url, submitData, AJAX.responseHandler);
});
} else {
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
}
});
/**
* Handles multi submit for untracked tables
*/
$body.on('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
});
/**
* Ajax Event handler for 'Delete tracking'
*/
$body.on('click', 'a.delete_tracking_anchor.ajax', function (e) {
e.preventDefault();
var $anchor = $(this);
var question = Messages.strDeleteTrackingData;
$anchor.confirm(question, $anchor.attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strDeletingTrackingData);
AJAX.source = $anchor;
var argSep = CommonParams.get('arg_separator');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
params += argSep + 'ajax_page_request=1';
$.post(url, params, AJAX.responseHandler);
});
});
});

View file

@ -1,538 +0,0 @@
AJAX.registerTeardown('database/triggers.js', function () {
$(document).off('click', 'a.ajax.add_anchor, a.ajax.edit_anchor');
$(document).off('click', 'a.ajax.export_anchor');
$(document).off('click', '#bulkActionExportButton');
$(document).off('click', 'a.ajax.drop_anchor');
$(document).off('click', '#bulkActionDropButton');
});
const DatabaseTriggers = {
/**
* @var $ajaxDialog Query object containing the reference to the
* dialog that contains the editor
*/
$ajaxDialog: null,
/**
* @var syntaxHiglighter Reference to the codemirror editor
*/
syntaxHiglighter: null,
/**
* Validate editor form fields.
*
* @return {bool}
*/
validate: function () {
/**
* @var $elm a jQuery object containing the reference
* to an element that is being validated
*/
var $elm = null;
// Common validation. At the very least the name
// and the definition must be provided for an item
$elm = $('table.rte_table').last().find('input[name=item_name]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
$elm = $('table.rte_table').find('textarea[name=item_definition]');
if ($elm.val() === '') {
if (this.syntaxHiglighter !== null) {
this.syntaxHiglighter.focus();
} else {
$('textarea[name=item_definition]').last().trigger('focus');
}
alert(Messages.strFormEmpty);
return false;
}
// The validation has so far passed, so now
// we can validate item-specific fields.
return this.validateCustom();
},
// end validate()
/**
* Validate custom editor form fields.
* This function can be overridden by
* other files in this folder
*
* @return {bool}
*/
validateCustom: function () {
return true;
},
// end validateCustom()
exportDialog: function ($this) {
var $msg = Functions.ajaxShowMessage();
if ($this.attr('id') === 'bulkActionExportButton') {
var combined = {
success: true,
title: Messages.strExport,
message: '',
error: ''
};
// export anchors of all selected rows
var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor');
var count = exportAnchors.length;
var returnCount = 0;
var p = $.when();
exportAnchors.each(function () {
var h = $(this).attr('href');
p = p.then(function () {
return $.get(h, {
'ajax_request': true
}, function (data) {
returnCount++;
if (data.success === true) {
combined.message += '\n' + data.message + '\n';
if (returnCount === count) {
showExport(combined);
}
} else {
// complain even if one export is failing
combined.success = false;
combined.error += '\n' + data.error + '\n';
if (returnCount === count) {
showExport(combined);
}
}
});
});
});
} else {
$.get($this.attr('href'), {
'ajax_request': true
}, showExport);
}
Functions.ajaxRemoveMessage($msg);
function showExport(data) {
if (data.success === true) {
Functions.ajaxRemoveMessage($msg);
/**
* @var buttonOptions Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-primary'
}
};
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close').remove();
};
/**
* Display the dialog to the user
*/
data.message = '<textarea cols="40" rows="15" class="w-100">' + data.message + '</textarea>';
var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 500,
buttons: buttonOptions,
title: data.title
});
// Attach syntax highlighted editor to export dialog
/**
* @var $elm jQuery object containing the reference
* to the Export textarea.
*/
var $elm = $ajaxDialog.find('textarea');
Functions.getSqlEditor($elm);
} else {
Functions.ajaxShowMessage(data.error, false);
}
} // end showExport()
},
// end exportDialog()
editorDialog: function (isNew, $this) {
var that = this;
/**
* @var $edit_row jQuery object containing the reference to
* the row of the the item being edited
* from the list of items
*/
var $editRow = null;
if ($this.hasClass('edit_anchor')) {
// Remember the row of the item being edited for later,
// so that if the edit is successful, we can replace the
// row with info about the modified item.
$editRow = $this.parents('tr');
}
/**
* @var $msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage();
$.get($this.attr('href'), {
'ajax_request': true
}, function (data) {
if (data.success === true) {
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary'
},
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-secondary'
}
};
// We have successfully fetched the editor form
Functions.ajaxRemoveMessage($msg);
// Now define the function that is called when
// the user presses the "Go" button
buttonOptions[Messages.strGo].click = function () {
// Move the data from the codemirror editor back to the
// textarea, where it can be used in the form submission.
if (typeof CodeMirror !== 'undefined') {
that.syntaxHiglighter.save();
}
// Validate editor and submit request, if passed.
if (that.validate()) {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $('form.rte_form').last().serialize();
$msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var url = $('form.rte_form').last().attr('action');
$.post(url, data, function (data) {
if (data.success === true) {
// Item created successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
that.$ajaxDialog.dialog('close');
// If we are in 'edit' mode, we must
// remove the reference to the old row.
if (mode === 'edit' && $editRow !== null) {
$editRow.remove();
}
// Sometimes, like when moving a trigger from
// a table to another one, the new row should
// not be inserted into the list. In this case
// "data.insert" will be set to false.
if (data.insert) {
// Insert the new row at the correct
// location in the list of items
/**
* @var text Contains the name of an item from
* the list that is used in comparisons
* to find the correct location where
* to insert a new row.
*/
var text = '';
/**
* @var inserted Whether a new item has been
* inserted in the list or not
*/
var inserted = false;
$('table.data').find('tr').each(function () {
text = $(this).children('td').eq(0).find('strong').text().toUpperCase().trim();
if (text !== '' && text > data.name) {
$(this).before(data.new_row);
inserted = true;
return false;
}
});
if (!inserted) {
// If we didn't manage to insert the row yet,
// it must belong at the end of the list,
// so we insert it there.
$('table.data').append(data.new_row);
}
// Fade-in the new row
$('tr.ajaxInsert').show('slow').removeClass('ajaxInsert');
} else if ($('table.data').find('tr').has('td').length === 0) {
// If we are not supposed to insert the new row,
// we will now check if the table is empty and
// needs to be hidden. This will be the case if
// we were editing the only item in the list,
// which we removed and will not be inserting
// something else in its place.
$('table.data').hide('slow', function () {
$('#nothing2display').show('slow');
});
}
// Now we have inserted the row at the correct
// position, but surely at least some row classes
// are wrong now. So we will iterate through
// all rows and assign correct classes to them
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$('table.data').find('tr').has('td').each(function () {
rowclass = ct % 2 === 0 ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
// If this is the first item being added, remove
// the "No items" message and show the list.
if ($('table.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible')) {
$('#nothing2display').hide('slow', function () {
$('table.data').show('slow');
});
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
} // end "if (that.validate())"
}; // end of function that handles the submission of the Editor
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close');
};
/**
* Display the dialog to the user
*/
that.$ajaxDialog = $('<div id="rteDialog">' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 700,
minWidth: 500,
buttons: buttonOptions,
// Issue #15810 - use button titles for modals (eg: new procedure)
// Respect the order: title on href tag, href content, title sent in response
title: $this.attr('title') || $this.text() || $(data.title).text(),
modal: true,
open: function () {
$('#rteDialog').dialog('option', 'max-height', $(window).height());
if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) {
$('#rteDialog').dialog('option', 'height', $(window).height());
}
$(this).find('input[name=item_name]').trigger('focus');
$(this).find('input.datefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'date');
});
$(this).find('input.datetimefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'datetime');
});
$.datepicker.initialized = false;
},
close: function () {
$(this).remove();
}
});
/**
* @var mode Used to remember whether the editor is in
* "Edit" or "Add" mode
*/
var mode = 'add';
if ($('input[name=editor_process_edit]').length > 0) {
mode = 'edit';
}
// Attach syntax highlighted editor to the definition
/**
* @var elm jQuery object containing the reference to
* the Definition textarea.
*/
var $elm = $('textarea[name=item_definition]').last();
var linterOptions = {};
linterOptions.triggerEditor = true;
that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.get()
},
dropDialog: function ($this) {
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $this.parents('tr');
/**
* @var question String containing the question to be asked for confirmation
*/
var question = $('<div></div>').text($currRow.children('td').children('.drop_sql').html());
// We ask for confirmation first here, before submitting the ajax request
$this.confirm(question, $this.attr('href'), function (url) {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $this.getPostData());
$.post(url, params, function (data) {
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('slow', function () {
$(this).remove();
// Now we have removed the row from the list, but maybe
// some row classes are wrong now. So we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = ct % 2 === 1 ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
});
}
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
// Show the query that we just executed
Functions.slidingMessage(data.sql_query);
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
},
dropMultipleDialog: function ($this) {
// We ask for confirmation here
$this.confirm(Messages.strDropRTEitems, '', function () {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
// drop anchors of all selected rows
var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor');
var success = true;
var count = dropAnchors.length;
var returnCount = 0;
dropAnchors.each(function () {
var $anchor = $(this);
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $anchor.parents('tr');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
$.post($anchor.attr('href'), params, function (data) {
returnCount++;
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('fast', function () {
// we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = ct % 2 === 1 ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
});
$currRow.remove();
}
if (returnCount === count) {
if (success) {
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
$('#rteListForm_checkall').prop({
checked: false,
indeterminate: false
});
}
Navigation.reload();
}
} else {
Functions.ajaxShowMessage(data.error, false);
success = false;
if (returnCount === count) {
Navigation.reload();
}
}
}); // end $.post()
}); // end drop_anchors.each()
});
}
};
AJAX.registerOnload('database/triggers.js', function () {
/**
* Attach Ajax event handlers for the Add/Edit functionality.
*/
$(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) {
event.preventDefault();
if ($(this).hasClass('add_anchor')) {
$.datepicker.initialized = false;
}
DatabaseTriggers.editorDialog($(this).hasClass('add_anchor'), $(this));
});
/**
* Attach Ajax event handlers for Export
*/
$(document).on('click', 'a.ajax.export_anchor', function (event) {
event.preventDefault();
DatabaseTriggers.exportDialog($(this));
});
$(document).on('click', '#bulkActionExportButton', function (event) {
event.preventDefault();
DatabaseTriggers.exportDialog($(this));
});
/**
* Attach Ajax event handlers for Drop functionality
*/
$(document).on('click', 'a.ajax.drop_anchor', function (event) {
event.preventDefault();
DatabaseTriggers.dropDialog($(this));
});
$(document).on('click', '#bulkActionDropButton', function (event) {
event.preventDefault();
DatabaseTriggers.dropMultipleDialog($(this));
});
});

View file

@ -1,209 +0,0 @@
var designerTables = [{
name: 'pdf_pages',
key: 'pgNr',
autoIncrement: true
}, {
name: 'table_coords',
key: 'id',
autoIncrement: true
}];
// eslint-disable-next-line no-unused-vars
var DesignerOfflineDB = function () {
var designerDB = {};
/**
* @type {IDBDatabase|null}
*/
var datastore = null;
/**
* @param {String} table
* @return {IDBTransaction}
*/
designerDB.getTransaction = function (table) {
return datastore.transaction([table], 'readwrite');
};
/**
* @param {String} table
* @return {IDBObjectStore}
*/
designerDB.getObjectStore = function (table) {
var transaction = designerDB.getTransaction(table);
var objStore = transaction.objectStore(table);
return objStore;
};
/**
* @param {IDBTransaction} transaction
* @param {String} table
* @return {IDBObjectStore}
*/
designerDB.getCursorRequest = function (transaction, table) {
var objStore = transaction.objectStore(table);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = objStore.openCursor(keyRange);
return cursorRequest;
};
/**
* @param {Function} callback
* @return {void}
*/
designerDB.open = function (callback) {
var version = 1;
var request = window.indexedDB.open('pma_designer', version);
request.onupgradeneeded = function (e) {
var db = e.target.result;
e.target.transaction.onerror = designerDB.onerror;
var t;
for (t in designerTables) {
if (db.objectStoreNames.contains(designerTables[t].name)) {
db.deleteObjectStore(designerTables[t].name);
}
}
for (t in designerTables) {
db.createObjectStore(designerTables[t].name, {
keyPath: designerTables[t].key,
autoIncrement: designerTables[t].autoIncrement
});
}
};
request.onsuccess = function (e) {
datastore = e.target.result;
if (typeof callback === 'function') {
callback(true);
}
};
request.onerror = function () {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
};
};
/**
* @param {String} table
* @param {String} id
* @param {Function} callback
* @return {void}
*/
designerDB.loadObject = function (table, id, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var objStore = designerDB.getObjectStore(table);
var cursorRequest = objStore.get(parseInt(id));
cursorRequest.onsuccess = function (e) {
callback(e.target.result);
};
cursorRequest.onerror = designerDB.onerror;
};
/**
* @param {String} table
* @param {Function} callback
* @return {void}
*/
designerDB.loadAllObjects = function (table, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var transaction = designerDB.getTransaction(table);
var cursorRequest = designerDB.getCursorRequest(transaction, table);
var results = [];
transaction.oncomplete = function () {
callback(results);
};
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
if (Boolean(result) === false) {
return;
}
results.push(result.value);
result.continue();
};
cursorRequest.onerror = designerDB.onerror;
};
/**
* @param {String} table
* @param {Function} callback
* @return {void}
*/
designerDB.loadFirstObject = function (table, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var transaction = designerDB.getTransaction(table);
var cursorRequest = designerDB.getCursorRequest(transaction, table);
var firstResult = null;
transaction.oncomplete = function () {
callback(firstResult);
};
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
if (Boolean(result) === false) {
return;
}
firstResult = result.value;
};
cursorRequest.onerror = designerDB.onerror;
};
/**
* @param {String} table
* @param {Object} obj
* @param {Function} callback
* @return {void}
*/
designerDB.addObject = function (table, obj, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var objStore = designerDB.getObjectStore(table);
var request = objStore.put(obj);
request.onsuccess = function (e) {
if (typeof callback === 'function') {
callback(e.currentTarget.result);
}
};
request.onerror = designerDB.onerror;
};
/**
* @param {String} table
* @param {String} id
* @param {Function} callback
* @return {void}
*/
designerDB.deleteObject = function (table, id, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var objStore = designerDB.getObjectStore(table);
var request = objStore.delete(parseInt(id));
request.onsuccess = function () {
if (typeof callback === 'function') {
callback(true);
}
};
request.onerror = designerDB.onerror;
};
/**
* @param {Error} e
* @return {void}
*/
designerDB.onerror = function (e) {
// eslint-disable-next-line no-console
console.log(e);
};
// Export the designerDB object.
return designerDB;
}();

View file

@ -1,817 +0,0 @@
/**
* @fileoverview function used in this file builds history tab and generates query.
*
* @requires jQuery
* @requires move.js
*/
/* global contr */ // js/designer/init.js
/* global fromArray:writable */ // js/designer/move.js
/* global themeImagePath */ // templates/javascript/variables.twig
var DesignerHistory = {};
var historyArray = []; // Global array to store history objects
var selectField = []; // Global array to store information for columns which are used in select clause
var gIndex;
var vqbEditor = null;
/**
* To display details of objects(where,rename,Having,aggregate,groupby,orderby,having)
*
* @param {number} index index of historyArray where change is to be made
* @return {string}
*/
DesignerHistory.detail = function (index) {
var type = historyArray[index].getType();
var str;
if (type === 'Where') {
str = 'Where ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
} else if (type === 'Rename') {
str = 'Rename ' + historyArray[index].getColumnName() + ' To ' + historyArray[index].getObj().getRenameTo();
} else if (type === 'Aggregate') {
str = 'Select ' + historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )';
} else if (type === 'GroupBy') {
str = 'GroupBy ' + historyArray[index].getColumnName();
} else if (type === 'OrderBy') {
str = 'OrderBy ' + historyArray[index].getColumnName() + ' ' + historyArray[index].getObj().getOrder();
} else if (type === 'Having') {
str = 'Having ';
if (historyArray[index].getObj().getOperator() !== 'None') {
str += historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )';
str += historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
} else {
str = 'Having ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
}
}
return str;
};
/**
* Sorts historyArray[] first,using table name as the key and then generates the HTML code for history tab,
* clubbing all objects of same tables together
* This function is called whenever changes are made in historyArray[]
*
*
* @param {number} init starting index of unsorted array
* @param {number} finit last index of unsorted array
* @return {string}
*/
DesignerHistory.display = function (init, finit) {
var str;
var i;
var j;
var k;
var sto;
var temp;
// this part sorts the history array based on table name,this is needed for clubbing all object of same name together.
for (i = init; i < finit; i++) {
sto = historyArray[i];
temp = historyArray[i].getTab(); // + '.' + historyArray[i].getObjNo(); for Self JOINS
for (j = 0; j < i; j++) {
if (temp > historyArray[j].getTab()) {
// + '.' + historyArray[j].getObjNo())) { //for Self JOINS
for (k = i; k > j; k--) {
historyArray[k] = historyArray[k - 1];
}
historyArray[j] = sto;
break;
}
}
}
// this part generates HTML code for history tab.adds delete,edit,and/or and detail features with objects.
str = ''; // string to store Html code for history tab
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
temp = historyArray[i].getTab(); // + '.' + historyArray[i].getObjNo(); for Self JOIN
str += '<h3 class="tiger"><a href="#">' + temp + '</a></h3>';
str += '<div class="toggle_container">\n';
while (historyArray[i].getTab() === temp) {
// + '.' + historyArray[i].getObjNo()) === temp) {
str += '<div class="block"> <table class="table table-sm w-auto mb-0">';
str += '<thead><tr><td>';
if (historyArray[i].getAndOr()) {
str += '<img src="' + themeImagePath + 'designer/or_icon.png" onclick="DesignerHistory.andOr(' + i + ')" title="OR"></td>';
} else {
str += '<img src="' + themeImagePath + 'designer/and_icon.png" onclick="DesignerHistory.andOr(' + i + ')" title="AND"></td>';
}
str += '<td style="padding-left: 5px;" class="text-end">' + Functions.getImage('b_sbrowse', Messages.strColumnName) + '</td>' + '<td width="175" style="padding-left: 5px">' + $('<div/>').text(historyArray[i].getColumnName()).html() + '<td>';
if (historyArray[i].getType() === 'GroupBy' || historyArray[i].getType() === 'OrderBy') {
var detailDescGroupBy = $('<div/>').text(DesignerHistory.detail(i)).html();
str += '<td class="text-center">' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '</td>' + '<td title="' + detailDescGroupBy + '">' + historyArray[i].getType() + '</td>' + '<td onclick=DesignerHistory.historyDelete(' + i + ')>' + Functions.getImage('b_drop', Messages.strDelete) + '</td>';
} else {
var detailDesc = $('<div/>').text(DesignerHistory.detail(i)).html();
str += '<td class="text-center">' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '</td>' + '<td title="' + detailDesc + '">' + historyArray[i].getType() + '</td>' + '<td onclick=DesignerHistory.historyEdit(' + i + ')>' + Functions.getImage('b_edit', Messages.strEdit) + '</td>' + '<td onclick=DesignerHistory.historyDelete(' + i + ')>' + Functions.getImage('b_drop', Messages.strDelete) + '</td>';
}
str += '</tr></thead>';
i++;
if (i >= historyArrayLength) {
break;
}
str += '</table></div>';
}
i--;
str += '</div>';
}
return str;
};
/**
* To change And/Or relation in history tab
*
*
* @param {number} index index of historyArray where change is to be made
* @return {void}
*/
DesignerHistory.andOr = function (index) {
if (historyArray[index].getAndOr()) {
historyArray[index].setAndOr(0);
} else {
historyArray[index].setAndOr(1);
}
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* Deletes entry in historyArray
*
* @param {number} index of historyArray[] which is to be deleted
* @return {void}
*/
DesignerHistory.historyDelete = function (index) {
var fromArrayLength = fromArray.length;
for (var k = 0; k < fromArrayLength; k++) {
if (fromArray[k] === historyArray[index].getTab()) {
fromArray.splice(k, 1);
break;
}
}
historyArray.splice(index, 1);
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* @param {string} elementId
* @return {void}
*/
DesignerHistory.changeStyle = function (elementId) {
var element = document.getElementById(elementId);
element.style.left = '530px';
element.style.top = '130px';
element.style.position = 'absolute';
element.style.zIndex = '103';
element.style.visibility = 'visible';
element.style.display = 'block';
};
/**
* To show where,rename,aggregate,having forms to edit a object
*
* @param {number} index index of historyArray where change is to be made
* @return {void}
*/
DesignerHistory.historyEdit = function (index) {
gIndex = index;
var type = historyArray[index].getType();
if (type === 'Where') {
document.getElementById('eQuery').value = historyArray[index].getObj().getQuery();
document.getElementById('erel_opt').value = historyArray[index].getObj().getRelationOperator();
DesignerHistory.changeStyle('query_where');
} else if (type === 'Having') {
document.getElementById('hQuery').value = historyArray[index].getObj().getQuery();
document.getElementById('hrel_opt').value = historyArray[index].getObj().getRelationOperator();
document.getElementById('hoperator').value = historyArray[index].getObj().getOperator();
DesignerHistory.changeStyle('query_having');
} else if (type === 'Rename') {
document.getElementById('e_rename').value = historyArray[index].getObj().getRenameTo();
DesignerHistory.changeStyle('query_rename_to');
} else if (type === 'Aggregate') {
document.getElementById('e_operator').value = historyArray[index].getObj().getOperator();
DesignerHistory.changeStyle('query_Aggregate');
}
};
/**
* Make changes in historyArray when Edit button is clicked
* checks for the type of object and then sets the new value
*
* @param {string} type of historyArray where change is to be made
* @return {void}
*/
DesignerHistory.edit = function (type) {
if (type === 'Rename') {
if (document.getElementById('e_rename').value !== '') {
historyArray[gIndex].getObj().setRenameTo(document.getElementById('e_rename').value);
document.getElementById('e_rename').value = '';
}
document.getElementById('query_rename_to').style.visibility = 'hidden';
} else if (type === 'Aggregate') {
if (document.getElementById('e_operator').value !== '---') {
historyArray[gIndex].getObj().setOperator(document.getElementById('e_operator').value);
document.getElementById('e_operator').value = '---';
}
document.getElementById('query_Aggregate').style.visibility = 'hidden';
} else if (type === 'Where') {
if (document.getElementById('erel_opt').value !== '--' && document.getElementById('eQuery').value !== '') {
historyArray[gIndex].getObj().setQuery(document.getElementById('eQuery').value);
historyArray[gIndex].getObj().setRelationOperator(document.getElementById('erel_opt').value);
}
document.getElementById('query_where').style.visibility = 'hidden';
} else if (type === 'Having') {
if (document.getElementById('hrel_opt').value !== '--' && document.getElementById('hQuery').value !== '') {
historyArray[gIndex].getObj().setQuery(document.getElementById('hQuery').value);
historyArray[gIndex].getObj().setRelationOperator(document.getElementById('hrel_opt').value);
historyArray[gIndex].getObj().setOperator(document.getElementById('hoperator').value);
}
document.getElementById('query_having').style.visibility = 'hidden';
}
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* history object closure
*
* @param nColumnName name of the column on which conditions are put
* @param nObj object details(where,rename,orderby,groupby,aggregate)
* @param nTab table name of the column on which conditions are applied
* @param nObjNo object no used for inner join
* @param nType type of object
*
*/
DesignerHistory.HistoryObj = function (nColumnName, nObj, nTab, nObjNo, nType) {
var andOr;
var obj;
var tab;
var columnName;
var objNo;
var type;
this.setColumnName = function (nColumnName) {
columnName = nColumnName;
};
this.getColumnName = function () {
return columnName;
};
this.setAndOr = function (nAndOr) {
andOr = nAndOr;
};
this.getAndOr = function () {
return andOr;
};
this.getRelation = function () {
return andOr;
};
this.setObj = function (nObj) {
obj = nObj;
};
this.getObj = function () {
return obj;
};
this.setTab = function (nTab) {
tab = nTab;
};
this.getTab = function () {
return tab;
};
this.setObjNo = function (nObjNo) {
objNo = nObjNo;
};
this.getObjNo = function () {
return objNo;
};
this.setType = function (nType) {
type = nType;
};
this.getType = function () {
return type;
};
this.setObjNo(nObjNo);
this.setTab(nTab);
this.setAndOr(0);
this.setObj(nObj);
this.setColumnName(nColumnName);
this.setType(nType);
};
/**
* where object closure, makes an object with all information of where
*
* @param nRelationOperator type of relation operator to be applied
* @param nQuery stores value of value/sub-query
*
*/
DesignerHistory.Where = function (nRelationOperator, nQuery) {
var relationOperator;
var query;
this.setRelationOperator = function (nRelationOperator) {
relationOperator = nRelationOperator;
};
this.setQuery = function (nQuery) {
query = nQuery;
};
this.getQuery = function () {
return query;
};
this.getRelationOperator = function () {
return relationOperator;
};
this.setQuery(nQuery);
this.setRelationOperator(nRelationOperator);
};
/**
* Orderby object closure
*
* @param nOrder order, ASC or DESC
*/
DesignerHistory.OrderBy = function (nOrder) {
var order;
this.setOrder = function (nOrder) {
order = nOrder;
};
this.getOrder = function () {
return order;
};
this.setOrder(nOrder);
};
/**
* Having object closure, makes an object with all information of where
*
* @param nRelationOperator type of relation operator to be applied
* @param nQuery stores value of value/sub-query
* @param nOperator operator
*/
DesignerHistory.Having = function (nRelationOperator, nQuery, nOperator) {
var relationOperator;
var query;
var operator;
this.setOperator = function (nOperator) {
operator = nOperator;
};
this.setRelationOperator = function (nRelationOperator) {
relationOperator = nRelationOperator;
};
this.setQuery = function (nQuery) {
query = nQuery;
};
this.getQuery = function () {
return query;
};
this.getRelationOperator = function () {
return relationOperator;
};
this.getOperator = function () {
return operator;
};
this.setQuery(nQuery);
this.setRelationOperator(nRelationOperator);
this.setOperator(nOperator);
};
/**
* rename object closure,makes an object with all information of rename
*
* @param nRenameTo new name information
*
*/
DesignerHistory.Rename = function (nRenameTo) {
var renameTo;
this.setRenameTo = function (nRenameTo) {
renameTo = nRenameTo;
};
this.getRenameTo = function () {
return renameTo;
};
this.setRenameTo(nRenameTo);
};
/**
* aggregate object closure
*
* @param nOperator aggregate operator
*
*/
DesignerHistory.Aggregate = function (nOperator) {
var operator;
this.setOperator = function (nOperator) {
operator = nOperator;
};
this.getOperator = function () {
return operator;
};
this.setOperator(nOperator);
};
/**
* This function returns unique element from an array
*
* @param arrayName array from which duplicate elem are to be removed.
* @return unique array
*/
DesignerHistory.unique = function (arrayName) {
var newArray = [];
uniquetop: for (var i = 0; i < arrayName.length; i++) {
var newArrayLength = newArray.length;
for (var j = 0; j < newArrayLength; j++) {
if (newArray[j] === arrayName[i]) {
continue uniquetop;
}
}
newArray[newArrayLength] = arrayName[i];
}
return newArray;
};
/**
* This function takes in array and a value as input and returns 1 if values is present in array
* else returns -1
*
* @param arrayName array
* @param value value which is to be searched in the array
*/
DesignerHistory.found = function (arrayName, value) {
var arrayNameLength = arrayName.length;
for (var i = 0; i < arrayNameLength; i++) {
if (arrayName[i] === value) {
return 1;
}
}
return -1;
};
/**
* This function concatenates two array
*
* @param {object} add array elements of which are pushed in
* @param {obj[]} arr array in which elements are added
*
* @return {obj[]}
*/
DesignerHistory.addArray = function (add, arr) {
var addLength = add.length;
for (var i = 0; i < addLength; i++) {
arr.push(add[i]);
}
return arr;
};
/**
* This function removes all elements present in one array from the other.
*
* @param {object} rem array from which each element is removed from other array.
* @param {obj[]} arr array from which elements are removed.
*
* @return {obj[]}
*
*/
DesignerHistory.removeArray = function (rem, arr) {
var remLength = rem.length;
for (var i = 0; i < remLength; i++) {
var arrLength = arr.length;
for (var j = 0; j < arrLength; j++) {
if (rem[i] === arr[j]) {
arr.splice(j, 1);
}
}
}
return arr;
};
/**
* This function builds the groupby clause from history object
* @return {string}
*/
DesignerHistory.queryGroupBy = function () {
var i;
var str = '';
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
if (historyArray[i].getType() === 'GroupBy') {
str += '`' + historyArray[i].getColumnName() + '`, ';
}
}
str = str.substr(0, str.length - 2);
return str;
};
/**
* This function builds the Having clause from the history object.
* @return {string}
*/
DesignerHistory.queryHaving = function () {
var i;
var and = '(';
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
if (historyArray[i].getType() === 'Having') {
if (historyArray[i].getObj().getOperator() !== 'None') {
and += historyArray[i].getObj().getOperator() + '(`' + historyArray[i].getColumnName() + '`) ' + historyArray[i].getObj().getRelationOperator();
and += ' ' + historyArray[i].getObj().getQuery() + ', ';
} else {
and += '`' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ', ';
}
}
}
if (and === '(') {
and = '';
} else {
and = and.substr(0, and.length - 2) + ')';
}
return and;
};
/**
* This function builds the orderby clause from the history object.
* @return {string}
*/
DesignerHistory.queryOrderBy = function () {
var i;
var str = '';
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
if (historyArray[i].getType() === 'OrderBy') {
str += '`' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getOrder() + ', ';
}
}
str = str.substr(0, str.length - 2);
return str;
};
/**
* This function builds the Where clause from the history object.
* @return {string}
*/
DesignerHistory.queryWhere = function () {
var i;
var and = '(';
var or = '(';
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
if (historyArray[i].getType() === 'Where') {
if (historyArray[i].getAndOr() === 0) {
and += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')';
and += ' AND ';
} else {
or += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')';
or += ' OR ';
}
}
}
if (or !== '(') {
or = or.substring(0, or.length - 4) + ')';
} else {
or = '';
}
if (and !== '(') {
and = and.substring(0, and.length - 5) + ')';
} else {
and = '';
}
if (or !== '') {
and = and + ' OR ' + or + ' )';
}
return and;
};
DesignerHistory.checkAggregate = function (idThis) {
var i;
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`';
if (temp === idThis && historyArray[i].getType() === 'Aggregate') {
return historyArray[i].getObj().getOperator() + '(' + idThis + ')';
}
}
return '';
};
DesignerHistory.checkRename = function (idThis) {
var i;
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`';
if (temp === idThis && historyArray[i].getType() === 'Rename') {
return ' AS `' + historyArray[i].getObj().getRenameTo() + '`';
}
}
return '';
};
/**
* This function builds from clause of query
* makes automatic joins.
*
* @return {string}
*/
DesignerHistory.queryFrom = function () {
var i;
var tabLeft = [];
var tabUsed = [];
var tTabLeft = [];
var temp;
var query = '';
var quer = '';
var parts = [];
var tArray = [];
tArray = fromArray;
var K = 0;
var k;
var key;
var key2;
var key3;
var parts1;
// the constraints that have been used in the LEFT JOIN
var constraintsAdded = [];
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
fromArray.push(historyArray[i].getTab());
}
fromArray = DesignerHistory.unique(fromArray);
tabLeft = fromArray;
temp = tabLeft.shift();
quer = '`' + temp + '`';
tabUsed.push(temp);
// if master table (key2) matches with tab used get all keys and check if tab_left matches
// after this check if master table (key2) matches with tab left then check if any foreign matches with master .
for (i = 0; i < 2; i++) {
for (K in contr) {
for (key in contr[K]) {
// contr name
for (key2 in contr[K][key]) {
// table name
parts = key2.split('.');
if (DesignerHistory.found(tabUsed, parts[1]) > 0) {
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split('.');
if (DesignerHistory.found(tabLeft, parts1[1]) > 0) {
if (DesignerHistory.found(constraintsAdded, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += '\n' + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraintsAdded.push(key);
}
tTabLeft.push(parts[1]);
}
}
}
}
}
}
K = 0;
tTabLeft = DesignerHistory.unique(tTabLeft);
tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed);
tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft);
tTabLeft = [];
for (K in contr) {
for (key in contr[K]) {
for (key2 in contr[K][key]) {
// table name
parts = key2.split('.');
if (DesignerHistory.found(tabLeft, parts[1]) > 0) {
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split('.');
if (DesignerHistory.found(tabUsed, parts1[1]) > 0) {
if (DesignerHistory.found(constraintsAdded, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += '\n' + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraintsAdded.push(key);
}
tTabLeft.push(parts[1]);
}
}
}
}
}
}
tTabLeft = DesignerHistory.unique(tTabLeft);
tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed);
tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft);
tTabLeft = [];
}
for (k in tabLeft) {
quer += ' , `' + tabLeft[k] + '`';
}
query = quer + query;
fromArray = tArray;
return query;
};
/**
* This function is the main function for query building.
* uses history object details for this.
*
* @uses DesignerHistory.queryWhere()
* @uses DesignerHistory.queryGroupBy()
* @uses DesignerHistory.queryHaving()
* @uses DesignerHistory.queryOrderBy()
*/
DesignerHistory.buildQuery = function () {
var qSelect = 'SELECT ';
var temp;
var selectFieldLength = selectField.length;
if (selectFieldLength > 0) {
for (var i = 0; i < selectFieldLength; i++) {
temp = DesignerHistory.checkAggregate(selectField[i]);
if (temp !== '') {
qSelect += temp;
temp = DesignerHistory.checkRename(selectField[i]);
qSelect += temp + ', ';
} else {
temp = DesignerHistory.checkRename(selectField[i]);
qSelect += selectField[i] + temp + ', ';
}
}
qSelect = qSelect.substring(0, qSelect.length - 2);
} else {
qSelect += '* ';
}
qSelect += '\nFROM ' + DesignerHistory.queryFrom();
var qWhere = DesignerHistory.queryWhere();
if (qWhere !== '') {
qSelect += '\nWHERE ' + qWhere;
}
var qGroupBy = DesignerHistory.queryGroupBy();
if (qGroupBy !== '') {
qSelect += '\nGROUP BY ' + qGroupBy;
}
var qHaving = DesignerHistory.queryHaving();
if (qHaving !== '') {
qSelect += '\nHAVING ' + qHaving;
}
var qOrderBy = DesignerHistory.queryOrderBy();
if (qOrderBy !== '') {
qSelect += '\nORDER BY ' + qOrderBy;
}
$('#buildQuerySubmitButton').on('click', function () {
if (vqbEditor) {
var $elm = $('#buildQueryModal').find('textarea');
vqbEditor.save();
$elm.val(vqbEditor.getValue());
}
$('#vqb_form').trigger('submit');
});
$('#buildQueryModal').modal('show');
$('#buildQueryModalLabel').first().text('SELECT');
$('#buildQueryModal').on('shown.bs.modal', function () {
// Attach syntax highlighted editor to query dialog
/**
* @var $elm jQuery object containing the reference
* to the query textarea.
*/
var $elm = $('#buildQueryModal').find('textarea');
if (!vqbEditor) {
vqbEditor = Functions.getSqlEditor($elm);
}
if (vqbEditor) {
vqbEditor.setValue(qSelect);
vqbEditor.focus();
} else {
$elm.val(qSelect);
$elm.trigger('focus');
}
});
};
AJAX.registerTeardown('designer/history.js', function () {
vqbEditor = null;
historyArray = [];
selectField = [];
$('#ok_edit_rename').off('click');
$('#ok_edit_having').off('click');
$('#ok_edit_Aggr').off('click');
$('#ok_edit_where').off('click');
});
AJAX.registerOnload('designer/history.js', function () {
$('#ok_edit_rename').on('click', function () {
DesignerHistory.edit('Rename');
});
$('#ok_edit_having').on('click', function () {
DesignerHistory.edit('Having');
});
$('#ok_edit_Aggr').on('click', function () {
DesignerHistory.edit('Aggregate');
});
$('#ok_edit_where').on('click', function () {
DesignerHistory.edit('Where');
});
$('#ab').accordion({
collapsible: true,
active: 'none'
});
});

View file

@ -1,63 +0,0 @@
/**
* Initializes the data required to run Designer, then fires it up.
*/
/* global DesignerOfflineDB */ // js/designer/database.js
/* global DesignerHistory */ // js/designer/history.js
/* global DesignerMove */ // js/designer/move.js
/* global DesignerPage */ // js/designer/page.js
/* global designerConfig */ // templates/database/designer/main.twig
/* eslint-disable no-unused-vars */
var jTabs;
var hTabs;
var contr;
var displayField;
var server;
var selectedPage;
/* eslint-enable no-unused-vars */
var db;
var designerTablesEnabled;
AJAX.registerTeardown('designer/init.js', function () {
$('.trigger').off('click');
});
AJAX.registerOnload('designer/init.js', function () {
$('.trigger').on('click', function () {
$('.panel').toggle('fast');
$(this).toggleClass('active');
$('#ab').accordion('refresh');
return false;
});
jTabs = designerConfig.scriptTables.j_tabs;
hTabs = designerConfig.scriptTables.h_tabs;
contr = designerConfig.scriptContr;
displayField = designerConfig.scriptDisplayField;
server = designerConfig.server;
selectedPage = designerConfig.displayPage;
db = designerConfig.db;
designerTablesEnabled = designerConfig.tablesEnabled;
DesignerMove.main();
if (!designerTablesEnabled) {
DesignerOfflineDB.open(function (success) {
if (success) {
DesignerPage.showTablesInLandingPage(db);
}
});
}
$('#query_Aggregate_Button').on('click', function () {
$('#query_Aggregate').css('display', 'none');
});
$('#query_having_button').on('click', function () {
$('#query_having').css('display', 'none');
});
$('#query_rename_to_button').on('click', function () {
$('#query_rename_to').css('display', 'none');
});
$('#build_query_button').on('click', function () {
DesignerHistory.buildQuery('SQL Query on Database', 0);
});
$('#query_where_button').on('click', function () {
$('#query_where').css('display', 'none');
});
});

File diff suppressed because it is too large Load diff

View file

@ -1,22 +0,0 @@
// eslint-disable-next-line no-unused-vars
var DesignerObjects = {
PdfPage: function (dbName, pageDescr, tblCords) {
// no dot set the auto increment before put() in the database
// issue #12900
// eslint-disable-next-line no-unused-vars
var pgNr;
this.dbName = dbName;
this.pageDescr = pageDescr;
this.tblCords = tblCords;
},
TableCoordinate: function (dbName, tableName, pdfPgNr, x, y) {
// no dot set the auto increment before put() in the database
// issue #12900
// var id;
this.dbName = dbName;
this.tableName = tableName;
this.pdfPgNr = pdfPgNr;
this.x = x;
this.y = y;
}
};

View file

@ -1,165 +0,0 @@
/* global DesignerOfflineDB */ // js/designer/database.js
// eslint-disable-next-line no-unused-vars
/* global db, selectedPage:writable */ // js/designer/init.js
/* global DesignerMove */ // js/designer/move.js
/* global DesignerObjects */ // js/designer/objects.js
var DesignerPage = {};
DesignerPage.showTablesInLandingPage = function (db) {
DesignerPage.loadFirstPage(db, function (page) {
if (page) {
DesignerPage.loadHtmlForPage(page.pgNr);
selectedPage = page.pgNr;
} else {
DesignerPage.showNewPageTables(true);
}
});
};
DesignerPage.saveToNewPage = function (db, pageName, tablePositions, callback) {
DesignerPage.createNewPage(db, pageName, function (page) {
if (page) {
var tblCords = [];
var saveCallback = function (id) {
tblCords.push(id);
if (tablePositions.length === tblCords.length) {
page.tblCords = tblCords;
DesignerOfflineDB.addObject('pdf_pages', page);
}
};
for (var pos = 0; pos < tablePositions.length; pos++) {
tablePositions[pos].pdfPgNr = page.pgNr;
DesignerPage.saveTablePositions(tablePositions[pos], saveCallback);
}
if (typeof callback !== 'undefined') {
callback(page);
}
}
});
};
DesignerPage.saveToSelectedPage = function (db, pageId, pageName, tablePositions, callback) {
DesignerPage.deletePage(pageId);
DesignerPage.saveToNewPage(db, pageName, tablePositions, function (page) {
if (typeof callback !== 'undefined') {
callback(page);
}
selectedPage = page.pgNr;
});
};
DesignerPage.createNewPage = function (db, pageName, callback) {
var newPage = new DesignerObjects.PdfPage(db, pageName, []);
DesignerOfflineDB.addObject('pdf_pages', newPage, function (pgNr) {
newPage.pgNr = pgNr;
if (typeof callback !== 'undefined') {
callback(newPage);
}
});
};
DesignerPage.saveTablePositions = function (positions, callback) {
DesignerOfflineDB.addObject('table_coords', positions, callback);
};
DesignerPage.createPageList = function (db, callback) {
DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) {
var html = '';
for (var p = 0; p < pages.length; p++) {
var page = pages[p];
if (page.dbName === db) {
html += '<option value="' + page.pgNr + '">';
html += Functions.escapeHtml(page.pageDescr) + '</option>';
}
}
if (typeof callback !== 'undefined') {
callback(html);
}
});
};
DesignerPage.deletePage = function (pageId, callback) {
DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) {
if (page) {
for (var i = 0; i < page.tblCords.length; i++) {
DesignerOfflineDB.deleteObject('table_coords', page.tblCords[i]);
}
DesignerOfflineDB.deleteObject('pdf_pages', pageId, callback);
}
});
};
DesignerPage.loadFirstPage = function (db, callback) {
DesignerOfflineDB.loadAllObjects('pdf_pages', function (pages) {
var firstPage = null;
for (var i = 0; i < pages.length; i++) {
var page = pages[i];
if (page.dbName === db) {
// give preference to a page having same name as the db
if (page.pageDescr === db) {
callback(page);
return;
}
if (firstPage === null) {
firstPage = page;
}
}
}
callback(firstPage);
});
};
DesignerPage.showNewPageTables = function (check) {
var allTables = $('#id_scroll_tab').find('td input:checkbox');
allTables.prop('checked', check);
for (var tab = 0; tab < allTables.length; tab++) {
var input = allTables[tab];
if (input.value) {
var element = document.getElementById(input.value);
element.style.top = DesignerPage.getRandom(550, 20) + 'px';
element.style.left = DesignerPage.getRandom(700, 20) + 'px';
DesignerMove.visibleTab(input, input.value);
}
}
selectedPage = -1;
$('#page_name').text(Messages.strUntitled);
DesignerMove.markUnsaved();
};
DesignerPage.loadHtmlForPage = function (pageId) {
DesignerPage.showNewPageTables(true);
DesignerPage.loadPageObjects(pageId, function (page, tblCords) {
$('#name-panel').find('#page_name').text(page.pageDescr);
var tableMissing = false;
for (var t = 0; t < tblCords.length; t++) {
var tbId = db + '.' + tblCords[t].tableName;
var table = document.getElementById(tbId);
if (table === null) {
tableMissing = true;
continue;
}
table.style.top = tblCords[t].y + 'px';
table.style.left = tblCords[t].x + 'px';
var checkbox = document.getElementById('check_vis_' + tbId);
checkbox.checked = true;
DesignerMove.visibleTab(checkbox, checkbox.value);
}
DesignerMove.markSaved();
if (tableMissing === true) {
DesignerMove.markUnsaved();
Functions.ajaxShowMessage(Messages.strSavedPageTableMissing);
}
selectedPage = page.pgNr;
});
};
DesignerPage.loadPageObjects = function (pageId, callback) {
DesignerOfflineDB.loadObject('pdf_pages', pageId, function (page) {
var tblCords = [];
var count = page.tblCords.length;
for (var i = 0; i < count; i++) {
DesignerOfflineDB.loadObject('table_coords', page.tblCords[i], function (tblCord) {
tblCords.push(tblCord);
if (tblCords.length === count) {
if (typeof callback !== 'undefined') {
callback(page, tblCords);
}
}
});
}
});
};
DesignerPage.getRandom = function (max, min) {
var val = Math.random() * (max - min) + min;
return Math.floor(val);
};

View file

@ -1,365 +0,0 @@
/**
* Definition of links to MySQL documentation.
*/
// eslint-disable-next-line no-unused-vars
var mysqlDocKeyword = {
/* Multi word */
'CHARACTER SET': ['charset'],
'SHOW AUTHORS': ['show-authors'],
'SHOW BINARY LOGS': ['show-binary-logs'],
'SHOW BINLOG EVENTS': ['show-binlog-events'],
'SHOW CHARACTER SET': ['show-character-set'],
'SHOW COLLATION': ['show-collation'],
'SHOW COLUMNS': ['show-columns'],
'SHOW CONTRIBUTORS': ['show-contributors'],
'SHOW CREATE DATABASE': ['show-create-database'],
'SHOW CREATE EVENT': ['show-create-event'],
'SHOW CREATE FUNCTION': ['show-create-function'],
'SHOW CREATE PROCEDURE': ['show-create-procedure'],
'SHOW CREATE TABLE': ['show-create-table'],
'SHOW CREATE TRIGGER': ['show-create-trigger'],
'SHOW CREATE VIEW': ['show-create-view'],
'SHOW DATABASES': ['show-databases'],
'SHOW ENGINE': ['show-engine'],
'SHOW ENGINES': ['show-engines'],
'SHOW ERRORS': ['show-errors'],
'SHOW EVENTS': ['show-events'],
'SHOW FUNCTION CODE': ['show-function-code'],
'SHOW FUNCTION STATUS': ['show-function-status'],
'SHOW GRANTS': ['show-grants'],
'SHOW INDEX': ['show-index'],
'SHOW MASTER STATUS': ['show-master-status'],
'SHOW OPEN TABLES': ['show-open-tables'],
'SHOW PLUGINS': ['show-plugins'],
'SHOW PRIVILEGES': ['show-privileges'],
'SHOW PROCEDURE CODE': ['show-procedure-code'],
'SHOW PROCEDURE STATUS': ['show-procedure-status'],
'SHOW PROCESSLIST': ['show-processlist'],
'SHOW PROFILE': ['show-profile'],
'SHOW PROFILES': ['show-profiles'],
'SHOW RELAYLOG EVENTS': ['show-relaylog-events'],
'SHOW SLAVE HOSTS': ['show-slave-hosts'],
'SHOW SLAVE STATUS': ['show-slave-status'],
'SHOW STATUS': ['show-status'],
'SHOW TABLE STATUS': ['show-table-status'],
'SHOW TABLES': ['show-tables'],
'SHOW TRIGGERS': ['show-triggers'],
'SHOW VARIABLES': ['show-variables'],
'SHOW WARNINGS': ['show-warnings'],
'LOAD DATA INFILE': ['load-data'],
'LOAD XML': ['load-xml'],
'LOCK TABLES': ['lock-tables'],
'UNLOCK TABLES': ['lock-tables'],
'ALTER DATABASE': ['alter-database'],
'ALTER EVENT': ['alter-event'],
'ALTER LOGFILE GROUP': ['alter-logfile-group'],
'ALTER FUNCTION': ['alter-function'],
'ALTER PROCEDURE': ['alter-procedure'],
'ALTER SERVER': ['alter-server'],
'ALTER TABLE': ['alter-table'],
'ALTER TABLESPACE': ['alter-tablespace'],
'ALTER VIEW': ['alter-view'],
'CREATE DATABASE': ['create-database'],
'CREATE EVENT': ['create-event'],
'CREATE FUNCTION': ['create-function'],
'CREATE INDEX': ['create-index'],
'CREATE LOGFILE GROUP': ['create-logfile-group'],
'CREATE PROCEDURE': ['create-procedure'],
'CREATE SERVER': ['create-server'],
'CREATE TABLE': ['create-table'],
'CREATE TABLESPACE': ['create-tablespace'],
'CREATE TRIGGER': ['create-trigger'],
'CREATE VIEW': ['create-view'],
'DROP DATABASE': ['drop-database'],
'DROP EVENT': ['drop-event'],
'DROP FUNCTION': ['drop-function'],
'DROP INDEX': ['drop-index'],
'DROP LOGFILE GROUP': ['drop-logfile-group'],
'DROP PROCEDURE': ['drop-procedure'],
'DROP SERVER': ['drop-server'],
'DROP TABLE': ['drop-table'],
'DROP TABLESPACE': ['drop-tablespace'],
'DROP TRIGGER': ['drop-trigger'],
'DROP VIEW': ['drop-view'],
'RENAME TABLE': ['rename-table'],
'TRUNCATE TABLE': ['truncate-table'],
/* Statements */
'SELECT': ['select'],
'SET': ['set'],
'EXPLAIN': ['explain'],
'DESCRIBE': ['describe'],
'DELETE': ['delete'],
'SHOW': ['show'],
'UPDATE': ['update'],
'INSERT': ['insert'],
'REPLACE': ['replace'],
'CALL': ['call'],
'DO': ['do'],
'HANDLER': ['handler'],
'COLLATE': ['charset-collations'],
/* Functions */
'ABS': ['mathematical-functions', 'function_abs'],
'ACOS': ['mathematical-functions', 'function_acos'],
'ADDDATE': ['date-and-time-functions', 'function_adddate'],
'ADDTIME': ['date-and-time-functions', 'function_addtime'],
'AES_DECRYPT': ['encryption-functions', 'function_aes_decrypt'],
'AES_ENCRYPT': ['encryption-functions', 'function_aes_encrypt'],
'AND': ['logical-operators', 'operator_and'],
'ASCII': ['string-functions', 'function_ascii'],
'ASIN': ['mathematical-functions', 'function_asin'],
'ATAN2': ['mathematical-functions', 'function_atan2'],
'ATAN': ['mathematical-functions', 'function_atan'],
'AVG': ['aggregate-functions', 'function_avg'],
'BENCHMARK': ['information-functions', 'function_benchmark'],
'BIN': ['string-functions', 'function_bin'],
'BINARY': ['cast-functions', 'operator_binary'],
'BIT_AND': ['aggregate-functions', 'function_bit_and'],
'BIT_COUNT': ['bit-functions', 'function_bit_count'],
'BIT_LENGTH': ['string-functions', 'function_bit_length'],
'BIT_OR': ['aggregate-functions', 'function_bit_or'],
'BIT_XOR': ['aggregate-functions', 'function_bit_xor'],
'CASE': ['control-flow-functions', 'operator_case'],
'CAST': ['cast-functions', 'function_cast'],
'CEIL': ['mathematical-functions', 'function_ceil'],
'CEILING': ['mathematical-functions', 'function_ceiling'],
'CHAR_LENGTH': ['string-functions', 'function_char_length'],
'CHAR': ['string-functions', 'function_char'],
'CHARACTER_LENGTH': ['string-functions', 'function_character_length'],
'CHARSET': ['information-functions', 'function_charset'],
'COALESCE': ['comparison-operators', 'function_coalesce'],
'COERCIBILITY': ['information-functions', 'function_coercibility'],
'COLLATION': ['information-functions', 'function_collation'],
'COMPRESS': ['encryption-functions', 'function_compress'],
'CONCAT_WS': ['string-functions', 'function_concat_ws'],
'CONCAT': ['string-functions', 'function_concat'],
'CONNECTION_ID': ['information-functions', 'function_connection_id'],
'CONV': ['mathematical-functions', 'function_conv'],
'CONVERT_TZ': ['date-and-time-functions', 'function_convert_tz'],
'Convert': ['cast-functions', 'function_convert'],
'COS': ['mathematical-functions', 'function_cos'],
'COT': ['mathematical-functions', 'function_cot'],
'COUNT': ['aggregate-functions', 'function_count'],
'CRC32': ['mathematical-functions', 'function_crc32'],
'CURDATE': ['date-and-time-functions', 'function_curdate'],
'CURRENT_DATE': ['date-and-time-functions', 'function_current_date'],
'CURRENT_TIME': ['date-and-time-functions', 'function_current_time'],
'CURRENT_TIMESTAMP': ['date-and-time-functions', 'function_current_timestamp'],
'CURRENT_USER': ['information-functions', 'function_current_user'],
'CURTIME': ['date-and-time-functions', 'function_curtime'],
'DATABASE': ['information-functions', 'function_database'],
'DATE_ADD': ['date-and-time-functions', 'function_date_add'],
'DATE_FORMAT': ['date-and-time-functions', 'function_date_format'],
'DATE_SUB': ['date-and-time-functions', 'function_date_sub'],
'DATE': ['date-and-time-functions', 'function_date'],
'DATEDIFF': ['date-and-time-functions', 'function_datediff'],
'DAY': ['date-and-time-functions', 'function_day'],
'DAYNAME': ['date-and-time-functions', 'function_dayname'],
'DAYOFMONTH': ['date-and-time-functions', 'function_dayofmonth'],
'DAYOFWEEK': ['date-and-time-functions', 'function_dayofweek'],
'DAYOFYEAR': ['date-and-time-functions', 'function_dayofyear'],
'DECLARE': ['declare', 'declare'],
'DECODE': ['encryption-functions', 'function_decode'],
'DEFAULT': ['miscellaneous-functions', 'function_default'],
'DEGREES': ['mathematical-functions', 'function_degrees'],
'DES_DECRYPT': ['encryption-functions', 'function_des_decrypt'],
'DES_ENCRYPT': ['encryption-functions', 'function_des_encrypt'],
'DIV': ['arithmetic-functions', 'operator_div'],
'ELT': ['string-functions', 'function_elt'],
'ENCODE': ['encryption-functions', 'function_encode'],
'ENCRYPT': ['encryption-functions', 'function_encrypt'],
'EXP': ['mathematical-functions', 'function_exp'],
'EXPORT_SET': ['string-functions', 'function_export_set'],
'EXTRACT': ['date-and-time-functions', 'function_extract'],
'ExtractValue': ['xml-functions', 'function_extractvalue'],
'FIELD': ['string-functions', 'function_field'],
'FIND_IN_SET': ['string-functions', 'function_find_in_set'],
'FLOOR': ['mathematical-functions', 'function_floor'],
'FORMAT': ['string-functions', 'function_format'],
'FOUND_ROWS': ['information-functions', 'function_found_rows'],
'FROM_DAYS': ['date-and-time-functions', 'function_from_days'],
'FROM_UNIXTIME': ['date-and-time-functions', 'function_from_unixtime'],
'GET_FORMAT': ['date-and-time-functions', 'function_get_format'],
'GET_LOCK': ['miscellaneous-functions', 'function_get_lock'],
'GREATEST': ['comparison-operators', 'function_greatest'],
'GROUP_CONCAT': ['aggregate-functions', 'function_group_concat'],
'HEX': ['string-functions', 'function_hex'],
'HOUR': ['date-and-time-functions', 'function_hour'],
'IF': ['control-flow-functions', 'function_if'],
'IFNULL': ['control-flow-functions', 'function_ifnull'],
'IN': ['comparison-operators', 'function_in'],
'INET_ATON': ['miscellaneous-functions', 'function_inet_aton'],
'INET_NTOA': ['miscellaneous-functions', 'function_inet_ntoa'],
'INSTR': ['string-functions', 'function_instr'],
'INTERVAL': ['comparison-operators', 'function_interval'],
'IS_FREE_LOCK': ['miscellaneous-functions', 'function_is_free_lock'],
'IS_USED_LOCK': ['miscellaneous-functions', 'function_is_used_lock'],
'IS': ['comparison-operators', 'operator_is'],
'ISNULL': ['comparison-operators', 'function_isnull'],
'LAST_DAY': ['date-and-time-functions', 'function_last_day'],
'LAST_INSERT_ID': ['information-functions', 'function_last_insert_id'],
'LCASE': ['string-functions', 'function_lcase'],
'LEAST': ['comparison-operators', 'function_least'],
'LEFT': ['string-functions', 'function_left'],
'LENGTH': ['string-functions', 'function_length'],
'LIKE': ['string-comparison-functions', 'operator_like'],
'LN': ['mathematical-functions', 'function_ln'],
'LOAD_FILE': ['string-functions', 'function_load_file'],
'LOCALTIME': ['date-and-time-functions', 'function_localtime'],
'LOCALTIMESTAMP': ['date-and-time-functions', 'function_localtimestamp'],
'LOCATE': ['string-functions', 'function_locate'],
'LOG10': ['mathematical-functions', 'function_log10'],
'LOG2': ['mathematical-functions', 'function_log2'],
'LOG': ['mathematical-functions', 'function_log'],
'LOWER': ['string-functions', 'function_lower'],
'LPAD': ['string-functions', 'function_lpad'],
'LTRIM': ['string-functions', 'function_ltrim'],
'MAKE_SET': ['string-functions', 'function_make_set'],
'MAKEDATE': ['date-and-time-functions', 'function_makedate'],
'MAKETIME': ['date-and-time-functions', 'function_maketime'],
'MASTER_POS_WAIT': ['miscellaneous-functions', 'function_master_pos_wait'],
'MATCH': ['fulltext-search', 'function_match'],
'MAX': ['aggregate-functions', 'function_max'],
'MD5': ['encryption-functions', 'function_md5'],
'MICROSECOND': ['date-and-time-functions', 'function_microsecond'],
'MID': ['string-functions', 'function_mid'],
'MIN': ['aggregate-functions', 'function_min'],
'MINUTE': ['date-and-time-functions', 'function_minute'],
'MOD': ['mathematical-functions', 'function_mod'],
'MONTH': ['date-and-time-functions', 'function_month'],
'MONTHNAME': ['date-and-time-functions', 'function_monthname'],
'NAME_CONST': ['miscellaneous-functions', 'function_name_const'],
'NOT': ['logical-operators', 'operator_not'],
'NOW': ['date-and-time-functions', 'function_now'],
'NULLIF': ['control-flow-functions', 'function_nullif'],
'OCT': ['mathematical-functions', 'function_oct'],
'OCTET_LENGTH': ['string-functions', 'function_octet_length'],
'OLD_PASSWORD': ['encryption-functions', 'function_old_password'],
'OR': ['logical-operators', 'operator_or'],
'ORD': ['string-functions', 'function_ord'],
'PASSWORD': ['encryption-functions', 'function_password'],
'PERIOD_ADD': ['date-and-time-functions', 'function_period_add'],
'PERIOD_DIFF': ['date-and-time-functions', 'function_period_diff'],
'PI': ['mathematical-functions', 'function_pi'],
'POSITION': ['string-functions', 'function_position'],
'POW': ['mathematical-functions', 'function_pow'],
'POWER': ['mathematical-functions', 'function_power'],
'QUARTER': ['date-and-time-functions', 'function_quarter'],
'QUOTE': ['string-functions', 'function_quote'],
'RADIANS': ['mathematical-functions', 'function_radians'],
'RAND': ['mathematical-functions', 'function_rand'],
'REGEXP': ['regexp', 'operator_regexp'],
'RELEASE_LOCK': ['miscellaneous-functions', 'function_release_lock'],
'REPEAT': ['string-functions', 'function_repeat'],
'REVERSE': ['string-functions', 'function_reverse'],
'RIGHT': ['string-functions', 'function_right'],
'RLIKE': ['regexp', 'operator_rlike'],
'ROUND': ['mathematical-functions', 'function_round'],
'ROW_COUNT': ['information-functions', 'function_row_count'],
'RPAD': ['string-functions', 'function_rpad'],
'RTRIM': ['string-functions', 'function_rtrim'],
'SCHEMA': ['information-functions', 'function_schema'],
'SEC_TO_TIME': ['date-and-time-functions', 'function_sec_to_time'],
'SECOND': ['date-and-time-functions', 'function_second'],
'SESSION_USER': ['information-functions', 'function_session_user'],
'SHA': ['encryption-functions', 'function_sha1'],
'SHA1': ['encryption-functions', 'function_sha1'],
'SIGN': ['mathematical-functions', 'function_sign'],
'SIN': ['mathematical-functions', 'function_sin'],
'SLEEP': ['miscellaneous-functions', 'function_sleep'],
'SOUNDEX': ['string-functions', 'function_soundex'],
'SPACE': ['string-functions', 'function_space'],
'SQRT': ['mathematical-functions', 'function_sqrt'],
'STD': ['aggregate-functions', 'function_std'],
'STDDEV_POP': ['aggregate-functions', 'function_stddev_pop'],
'STDDEV_SAMP': ['aggregate-functions', 'function_stddev_samp'],
'STDDEV': ['aggregate-functions', 'function_stddev'],
'STR_TO_DATE': ['date-and-time-functions', 'function_str_to_date'],
'STRCMP': ['string-comparison-functions', 'function_strcmp'],
'SUBDATE': ['date-and-time-functions', 'function_subdate'],
'SUBSTR': ['string-functions', 'function_substr'],
'SUBSTRING_INDEX': ['string-functions', 'function_substring_index'],
'SUBSTRING': ['string-functions', 'function_substring'],
'SUBTIME': ['date-and-time-functions', 'function_subtime'],
'SUM': ['aggregate-functions', 'function_sum'],
'SYSDATE': ['date-and-time-functions', 'function_sysdate'],
'SYSTEM_USER': ['information-functions', 'function_system_user'],
'TAN': ['mathematical-functions', 'function_tan'],
'TIME_FORMAT': ['date-and-time-functions', 'function_time_format'],
'TIME_TO_SEC': ['date-and-time-functions', 'function_time_to_sec'],
'TIME': ['date-and-time-functions', 'function_time'],
'TIMEDIFF': ['date-and-time-functions', 'function_timediff'],
'TIMESTAMP': ['date-and-time-functions', 'function_timestamp'],
'TIMESTAMPADD': ['date-and-time-functions', 'function_timestampadd'],
'TIMESTAMPDIFF': ['date-and-time-functions', 'function_timestampdiff'],
'TO_DAYS': ['date-and-time-functions', 'function_to_days'],
'TRIM': ['string-functions', 'function_trim'],
'TRUNCATE': ['mathematical-functions', 'function_truncate'],
'UCASE': ['string-functions', 'function_ucase'],
'UNCOMPRESS': ['encryption-functions', 'function_uncompress'],
'UNCOMPRESSED_LENGTH': ['encryption-functions', 'function_uncompressed_length'],
'UNHEX': ['string-functions', 'function_unhex'],
'UNIX_TIMESTAMP': ['date-and-time-functions', 'function_unix_timestamp'],
'UpdateXML': ['xml-functions', 'function_updatexml'],
'UPPER': ['string-functions', 'function_upper'],
'USER': ['information-functions', 'function_user'],
'UTC_DATE': ['date-and-time-functions', 'function_utc_date'],
'UTC_TIME': ['date-and-time-functions', 'function_utc_time'],
'UTC_TIMESTAMP': ['date-and-time-functions', 'function_utc_timestamp'],
'UUID_SHORT': ['miscellaneous-functions', 'function_uuid_short'],
'UUID': ['miscellaneous-functions', 'function_uuid'],
'VALUES': ['miscellaneous-functions', 'function_values'],
'VAR_POP': ['aggregate-functions', 'function_var_pop'],
'VAR_SAMP': ['aggregate-functions', 'function_var_samp'],
'VARIANCE': ['aggregate-functions', 'function_variance'],
'VERSION': ['information-functions', 'function_version'],
'WEEK': ['date-and-time-functions', 'function_week'],
'WEEKDAY': ['date-and-time-functions', 'function_weekday'],
'WEEKOFYEAR': ['date-and-time-functions', 'function_weekofyear'],
'XOR': ['logical-operators', 'operator_xor'],
'YEAR': ['date-and-time-functions', 'function_year'],
'YEARWEEK': ['date-and-time-functions', 'function_yearweek'],
'SOUNDS_LIKE': ['string-functions', 'operator_sounds-like'],
'IS_NOT_NULL': ['comparison-operators', 'operator_is-not-null'],
'IS_NOT': ['comparison-operators', 'operator_is-not'],
'IS_NULL': ['comparison-operators', 'operator_is-null'],
'NOT_LIKE': ['string-comparison-functions', 'operator_not-like'],
'NOT_REGEXP': ['regexp', 'operator_not-regexp'],
'COUNT_DISTINCT': ['aggregate-functions', 'function_count-distinct'],
'NOT_IN': ['comparison-operators', 'function_not-in']
};
// eslint-disable-next-line no-unused-vars
var mysqlDocBuiltin = {
'TINYINT': ['numeric-types'],
'SMALLINT': ['numeric-types'],
'MEDIUMINT': ['numeric-types'],
'INT': ['numeric-types'],
'BIGINT': ['numeric-types'],
'DECIMAL': ['numeric-types'],
'FLOAT': ['numeric-types'],
'DOUBLE': ['numeric-types'],
'REAL': ['numeric-types'],
'BIT': ['numeric-types'],
'BOOLEAN': ['numeric-types'],
'SERIAL': ['numeric-types'],
'DATE': ['date-and-time-types'],
'DATETIME': ['date-and-time-types'],
'TIMESTAMP': ['date-and-time-types'],
'TIME': ['date-and-time-types'],
'YEAR': ['date-and-time-types'],
'CHAR': ['string-types'],
'VARCHAR': ['string-types'],
'TINYTEXT': ['string-types'],
'TEXT': ['string-types'],
'MEDIUMTEXT': ['string-types'],
'LONGTEXT': ['string-types'],
'BINARY': ['string-types'],
'VARBINARY': ['string-types'],
'TINYBLOB': ['string-types'],
'MEDIUMBLOB': ['string-types'],
'BLOB': ['string-types'],
'LONGBLOB': ['string-types'],
'ENUM': ['string-types'],
'SET': ['string-types']
};

View file

@ -1,351 +0,0 @@
/* This script handles PMA Drag Drop Import, loaded only when configuration is enabled.*/
/**
* Class to handle PMA Drag and Drop Import
* feature
*/
var DragDropImport = {
/**
* @var {number}, count of total uploads in this view
*/
uploadCount: 0,
/**
* @var {number}, count of live uploads
*/
liveUploadCount: 0,
/**
* @var {string[]} array, allowed extensions
*/
allowedExtensions: ['sql', 'xml', 'ldi', 'mediawiki', 'shp'],
/**
* @var {string[]} array, allowed extensions for compressed files
*/
allowedCompressedExtensions: ['gz', 'bz2', 'zip'],
/**
* @var {object[]}, array to store message returned by /import-status
*/
importStatus: [],
/**
* Checks if any dropped file has valid extension or not
*
* @param {string} file filename
*
* @return {string}, extension for valid extension, '' otherwise
*/
getExtension: function (file) {
var arr = file.split('.');
var ext = arr[arr.length - 1];
// check if compressed
if (jQuery.inArray(ext.toLowerCase(), DragDropImport.allowedCompressedExtensions) !== -1) {
ext = arr[arr.length - 2];
}
// Now check for extension
if (jQuery.inArray(ext.toLowerCase(), DragDropImport.allowedExtensions) !== -1) {
return ext;
}
return '';
},
/**
* Shows upload progress for different sql uploads
*
* @param {string} hash, hash for specific file upload
* @param {number} percent (float), file upload percentage
*
* @return {void}
*/
setProgress: function (hash, percent) {
$('.pma_sql_import_status div li[data-hash="' + hash + '"]').children('progress').val(percent);
},
/**
* Function to upload the file asynchronously
*
* @param {object} formData FormData object for a specific file
* @param {string} hash hash of the current file upload
*
* @return {void}
*/
sendFileToServer: function (formData, hash) {
var jqXHR = $.ajax({
xhr: function () {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener('progress', function (event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
// Set progress
DragDropImport.setProgress(hash, percent);
}, false);
}
return xhrobj;
},
url: 'index.php?route=/import',
type: 'POST',
contentType: false,
processData: false,
cache: false,
data: formData,
success: function (data) {
DragDropImport.importFinished(hash, false, data.success);
if (!data.success) {
DragDropImport.importStatus[DragDropImport.importStatus.length] = {
hash: hash,
message: data.error
};
}
}
});
// -- provide link to cancel the upload
$('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize').html('<span hash="' + hash + '" class="pma_drop_file_status" task="cancel">' + Messages.dropImportMessageCancel + '</span>');
// -- add event listener to this link to abort upload operation
$('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status').on('click', function () {
if ($(this).attr('task') === 'cancel') {
jqXHR.abort();
$(this).html('<span>' + Messages.dropImportMessageAborted + '</span>');
DragDropImport.importFinished(hash, true, false);
} else if ($(this).children('span').html() === Messages.dropImportMessageFailed) {
// -- view information
var $this = $(this);
$.each(DragDropImport.importStatus, function (key, value) {
if (value.hash === hash) {
$('.pma_drop_result:visible').remove();
var filename = $this.parent('span').attr('data-filename');
$('body').append('<div class="pma_drop_result"><h2>' + Messages.dropImportImportResultHeader + ' - ' + Functions.escapeHtml(filename) + '<span class="close">x</span></h2>' + value.message + '</div>');
$('.pma_drop_result').draggable(); // to make this dialog draggable
}
});
}
});
},
/**
* Triggered when an object is dragged into the PMA UI
*
* @param {MouseEvent} event obj
*
* @return {void}
*/
dragEnter: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
if (!DragDropImport.hasFiles(event)) {
return;
}
if (CommonParams.get('db') === '') {
$('.pma_drop_handler').html(Messages.dropImportSelectDB);
} else {
$('.pma_drop_handler').html(Messages.dropImportDropFiles);
}
$('.pma_drop_handler').fadeIn();
},
/**
* Check if dragged element contains Files
*
* @param event the event object
*
* @return {boolean}
*/
hasFiles: function (event) {
return !(typeof event.originalEvent.dataTransfer.types === 'undefined' || $.inArray('Files', event.originalEvent.dataTransfer.types) < 0 || $.inArray('application/x-moz-nativeimage', event.originalEvent.dataTransfer.types) >= 0);
},
/**
* Triggered when dragged file is being dragged over PMA UI
*
* @param {MouseEvent} event obj
*
* @return {void}
*/
dragOver: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
if (!DragDropImport.hasFiles(event)) {
return;
}
$('.pma_drop_handler').fadeIn();
},
/**
* Triggered when dragged objects are left
*
* @param {MouseEvent} event obj
*
* @return {void}
*/
dragLeave: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
event.stopPropagation();
event.preventDefault();
var $dropHandler = $('.pma_drop_handler');
$dropHandler.clearQueue().stop();
$dropHandler.fadeOut();
$dropHandler.html(Messages.dropImportDropFiles);
},
/**
* Called when upload has finished
*
* @param {string} hash unique hash for a certain upload
* @param {boolean} aborted true if upload was aborted
* @param {boolean} status status of sql upload, as sent by server
*
* @return {void}
*/
importFinished: function (hash, aborted, status) {
$('.pma_sql_import_status div li[data-hash="' + hash + '"]').children('progress').hide();
var icon = 'icon ic_s_success';
// -- provide link to view upload status
if (!aborted) {
if (status) {
$('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status').html('<span>' + Messages.dropImportMessageSuccess + '</a>');
} else {
$('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status').html('<span class="underline">' + Messages.dropImportMessageFailed + '</a>');
icon = 'icon ic_s_error';
}
} else {
icon = 'icon ic_s_notice';
}
$('.pma_sql_import_status div li[data-hash="' + hash + '"] span.filesize span.pma_drop_file_status').attr('task', 'info');
// Set icon
$('.pma_sql_import_status div li[data-hash="' + hash + '"]').prepend('<img src="./themes/dot.gif" title="finished" class="' + icon + '"> ');
// Decrease liveUploadCount by one
$('.pma_import_count').html(--DragDropImport.liveUploadCount);
if (!DragDropImport.liveUploadCount) {
$('.pma_sql_import_status h2 .close').fadeIn();
}
},
/**
* Triggered when dragged objects are dropped to UI
* From this function, the AJAX Upload operation is initiated
*
* @param event object
*
* @return {void}
*/
drop: function (event) {
// We don't want to prevent users from using
// browser's default drag-drop feature on some page(s)
if ($('.noDragDrop').length !== 0) {
return;
}
var dbname = CommonParams.get('db');
var server = CommonParams.get('server');
// if no database is selected -- no
if (dbname !== '') {
var files = event.originalEvent.dataTransfer.files;
if (!files || files.length === 0) {
// No files actually transferred
$('.pma_drop_handler').fadeOut();
event.stopPropagation();
event.preventDefault();
return;
}
$('.pma_sql_import_status').slideDown();
for (var i = 0; i < files.length; i++) {
var ext = DragDropImport.getExtension(files[i].name);
var hash = AJAX.hash(++DragDropImport.uploadCount);
var $sqlImportStatusDiv = $('.pma_sql_import_status div');
$sqlImportStatusDiv.append('<li data-hash="' + hash + '">' + (ext !== '' ? '' : '<img src="./themes/dot.gif" title="invalid format" class="icon ic_s_notice"> ') + Functions.escapeHtml(files[i].name) + '<span class="filesize" data-filename="' + Functions.escapeHtml(files[i].name) + '">' + (files[i].size / 1024).toFixed(2) + ' kb</span></li>');
// scroll the UI to bottom
$sqlImportStatusDiv.scrollTop($sqlImportStatusDiv.scrollTop() + 50); // 50 hardcoded for now
if (ext !== '') {
// Increment liveUploadCount by one
$('.pma_import_count').html(++DragDropImport.liveUploadCount);
$('.pma_sql_import_status h2 .close').fadeOut();
$('.pma_sql_import_status div li[data-hash="' + hash + '"]').append('<br><progress max="100" value="2"></progress>');
// uploading
var fd = new FormData();
fd.append('import_file', files[i]);
fd.append('noplugin', Math.random().toString(36).substring(2, 12));
fd.append('db', dbname);
fd.append('server', server);
fd.append('token', CommonParams.get('token'));
fd.append('import_type', 'database');
// todo: method to find the value below
fd.append('MAX_FILE_SIZE', '4194304');
// todo: method to find the value below
fd.append('charset_of_file', 'utf-8');
// todo: method to find the value below
fd.append('allow_interrupt', 'yes');
fd.append('skip_queries', '0');
fd.append('format', ext);
fd.append('sql_compatibility', 'NONE');
fd.append('sql_no_auto_value_on_zero', 'something');
fd.append('ajax_request', 'true');
fd.append('hash', hash);
// init uploading
DragDropImport.sendFileToServer(fd, hash);
} else if (!DragDropImport.liveUploadCount) {
$('.pma_sql_import_status h2 .close').fadeIn();
}
}
}
$('.pma_drop_handler').fadeOut();
event.stopPropagation();
event.preventDefault();
}
};
/**
* Called when some user drags, dragover, leave
* a file to the PMA UI
* @param {object}, Event data
* @return {void}
*/
$(document).on('dragenter', DragDropImport.dragEnter);
$(document).on('dragover', DragDropImport.dragOver);
$(document).on('dragleave', '.pma_drop_handler', DragDropImport.dragLeave);
// when file is dropped to PMA UI
$(document).on('drop', 'body', DragDropImport.drop);
// minimizing-maximizing the sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .minimize', function () {
if ($(this).attr('toggle') === 'off') {
$('.pma_sql_import_status div').css('height', '270px');
$(this).attr('toggle', 'on');
$(this).html('-'); // to minimize
} else {
$('.pma_sql_import_status div').css('height', '0px');
$(this).attr('toggle', 'off');
$(this).html('+'); // to maximise
}
});
// closing sql ajax upload status
$(document).on('click', '.pma_sql_import_status h2 .close', function () {
$('.pma_sql_import_status').fadeOut(function () {
$('.pma_sql_import_status div').html('');
DragDropImport.importStatus = []; // clear the message array
});
});
// Closing the import result box
$(document).on('click', '.pma_drop_result h2 .close', function () {
$(this).parent('h2').parent('div').remove();
});

View file

@ -1,285 +0,0 @@
/* global TraceKit */ // js/vendor/tracekit.js
/**
* general function, usually for data manipulation pages
*
*/
var ErrorReport = {
/**
* @var {object}, stores the last exception info
*/
lastException: null,
/**
* @var object stores the Error Report Data to prevent unnecessary data fetching
*/
errorReportData: null,
/**
* @var object maintains unique keys already used
*/
keyDict: {},
/**
* handles thrown error exceptions based on user preferences
*
* @param {object} data
* @param {any} exception
* @return {void}
*/
errorDataHandler: function (data, exception) {
if (data.success !== true) {
Functions.ajaxShowMessage(data.error, false);
return;
}
if (data.report_setting === 'ask') {
ErrorReport.showErrorNotification();
} else if (data.report_setting === 'always') {
var reportData = ErrorReport.getReportData(exception);
var postData = $.extend(reportData, {
'send_error_report': true,
'automatic': true
});
$.post('index.php?route=/error-report', postData, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
Functions.ajaxShowMessage(data.error, false);
} else {
Functions.ajaxShowMessage(data.message, false);
}
});
}
},
errorHandler: function (exception) {
// issue: 14359
if (JSON.stringify(ErrorReport.lastException) === JSON.stringify(exception)) {
return;
}
if (exception.name === null || typeof exception.name === 'undefined') {
exception.name = ErrorReport.extractExceptionName(exception);
}
ErrorReport.lastException = exception;
if (ErrorReport.errorReportData === null) {
$.post('index.php?route=/error-report', {
'ajax_request': true,
'server': CommonParams.get('server'),
'get_settings': true,
'exception_type': 'js'
}, function (data) {
ErrorReport.errorReportData = data;
ErrorReport.errorDataHandler(data, exception);
});
} else {
ErrorReport.errorDataHandler(ErrorReport.errorReportData, exception);
}
},
/**
* Shows the modal dialog previewing the report
*
* @param exception object error report info
*
* @return {void}
*/
showReportDialog: function (exception) {
const reportData = ErrorReport.getReportData(exception);
const sendErrorReport = function () {
const postData = $.extend(reportData, {
'send_error_report': true,
'description': $('#errorReportDescription').val(),
'always_send': $('#errorReportAlwaysSendCheckbox')[0].checked
});
$.post('index.php?route=/error-report', postData, function (data) {
if (data.success === false) {
Functions.ajaxShowMessage(data.error, false);
} else {
Functions.ajaxShowMessage(data.message, 3000);
}
});
$('#errorReportModal').modal('hide');
};
$.post('index.php?route=/error-report', reportData).done(function (data) {
// Delete the modal to refresh it in case the user changed SendErrorReports value
if (document.getElementById('errorReportModal') !== null) {
$('#errorReportModal').remove();
}
$('body').append($(data.report_modal));
const $errorReportModal = $('#errorReportModal');
$errorReportModal.on('show.bs.modal', function () {
// Prevents multiple onClick events
$('#errorReportModalConfirm').off('click', sendErrorReport);
$('#errorReportModalConfirm').on('click', sendErrorReport);
$('#errorReportModal .modal-body').html(data.message);
});
$errorReportModal.modal('show');
});
},
/**
* Shows the small notification that asks for user permission
*
* @return {void}
*/
showErrorNotification: function () {
var key = Math.random().toString(36).substring(2, 12);
while (key in ErrorReport.keyDict) {
key = Math.random().toString(36).substring(2, 12);
}
ErrorReport.keyDict[key] = 1;
var $div = $('<div class="alert alert-danger" role="alert" id="error_notification_' + key + '"></div>').append(Functions.getImage('s_error') + Messages.strErrorOccurred);
var $buttons = $('<div class="float-end"></div>');
var buttonHtml = '<button class="btn btn-primary" id="show_error_report_' + key + '">';
buttonHtml += Messages.strShowReportDetails;
buttonHtml += '</button>';
var settingsUrl = 'index.php?route=/preferences/features&server=' + CommonParams.get('server');
buttonHtml += '<a class="ajax" href="' + settingsUrl + '">';
buttonHtml += Functions.getImage('s_cog', Messages.strChangeReportSettings);
buttonHtml += '</a>';
buttonHtml += '<a href="#" id="ignore_error_' + key + '" data-notification-id="' + key + '">';
buttonHtml += Functions.getImage('b_close', Messages.strIgnore);
buttonHtml += '</a>';
$buttons.html(buttonHtml);
$div.append($buttons);
// eslint-disable-next-line compat/compat
$div.appendTo(document.body);
$(document).on('click', '#show_error_report_' + key, ErrorReport.createReportDialog);
$(document).on('click', '#ignore_error_' + key, ErrorReport.removeErrorNotification);
},
/**
* Removes the notification if it was displayed before
*
* @param {Event} e
* @return {void}
*/
removeErrorNotification: function (e) {
if (e) {
// don't remove the hash fragment by navigating to #
e.preventDefault();
}
$('#error_notification_' + $(this).data('notification-id')).fadeOut(function () {
$(this).remove();
});
},
/**
* Extracts Exception name from message if it exists
*
* @param exception
* @return {string}
*/
extractExceptionName: function (exception) {
if (exception.message === null || typeof exception.message === 'undefined') {
return '';
}
var reg = /([a-zA-Z]+):/;
var regexResult = reg.exec(exception.message);
if (regexResult && regexResult.length === 2) {
return regexResult[1];
}
return '';
},
/**
* Shows the modal dialog previewing the report
*
* @return {void}
*/
createReportDialog: function () {
ErrorReport.removeErrorNotification();
ErrorReport.showReportDialog(ErrorReport.lastException);
},
/**
* Returns the report data to send to the server
*
* @param exception object exception info
*
* @return {object}
*/
getReportData: function (exception) {
if (exception && exception.stack && exception.stack.length) {
for (var i = 0; i < exception.stack.length; i++) {
var stack = exception.stack[i];
if (stack.context && stack.context.length) {
for (var j = 0; j < stack.context.length; j++) {
if (stack.context[j].length > 80) {
stack.context[j] = stack.context[j].substring(-1, 75) + '//...';
}
}
}
}
}
var reportData = {
'server': CommonParams.get('server'),
'ajax_request': true,
'exception': exception,
'url': window.location.href,
'exception_type': 'js'
};
if (AJAX.scriptHandler.scripts.length > 0) {
reportData.scripts = AJAX.scriptHandler.scripts.map(function (script) {
return script;
});
}
return reportData;
},
/**
* Wraps given function in error reporting code and returns wrapped function
*
* @param {Function} func function to be wrapped
*
* @return {Function}
*/
wrapFunction: function (func) {
if (!func.wrapped) {
var newFunc = function () {
try {
return func.apply(this, arguments);
} catch (x) {
TraceKit.report(x);
}
};
newFunc.wrapped = true;
// Set guid of wrapped function same as original function, so it can be removed
// See bug#4146 (problem with jquery draggable and sortable)
newFunc.guid = func.guid = func.guid || newFunc.guid || jQuery.guid++;
return newFunc;
} else {
return func;
}
},
/**
* Automatically wraps the callback in AJAX.registerOnload
*
* @return {void}
*/
wrapAjaxOnloadCallback: function () {
var oldOnload = AJAX.registerOnload;
AJAX.registerOnload = function (file, func) {
var wrappedFunction = ErrorReport.wrapFunction(func);
oldOnload.call(this, file, wrappedFunction);
};
},
/**
* Automatically wraps the callback in $.fn.on
*
* @return {void}
*/
wrapJqueryOnCallback: function () {
var oldOn = $.fn.on;
$.fn.on = function () {
for (var i = 1; i <= 3; i++) {
if (typeof arguments[i] === 'function') {
arguments[i] = ErrorReport.wrapFunction(arguments[i]);
break;
}
}
return oldOn.apply(this, arguments);
};
},
/**
* Wraps the callback in AJAX.registerOnload automatically
*
* @return {void}
*/
setUpErrorReporting: function () {
ErrorReport.wrapAjaxOnloadCallback();
ErrorReport.wrapJqueryOnCallback();
}
};
AJAX.registerOnload('error_report.js', function () {
TraceKit.report.subscribe(ErrorReport.errorHandler);
ErrorReport.setUpErrorReporting();
});

View file

@ -1,882 +0,0 @@
/**
* Functions used in the export tab
*
*/
var Export = {};
/**
* Disables the "Dump some row(s)" sub-options
*/
Export.disableDumpSomeRowsSubOptions = function () {
$('label[for=\'limit_to\']').fadeTo('fast', 0.4);
$('label[for=\'limit_from\']').fadeTo('fast', 0.4);
$('input[type=\'text\'][name=\'limit_to\']').prop('disabled', 'disabled');
$('input[type=\'text\'][name=\'limit_from\']').prop('disabled', 'disabled');
};
/**
* Enables the "Dump some row(s)" sub-options
*/
Export.enableDumpSomeRowsSubOptions = function () {
$('label[for=\'limit_to\']').fadeTo('fast', 1);
$('label[for=\'limit_from\']').fadeTo('fast', 1);
$('input[type=\'text\'][name=\'limit_to\']').prop('disabled', '');
$('input[type=\'text\'][name=\'limit_from\']').prop('disabled', '');
};
/**
* Return template data as a json object
*
* @return {object} template data
*/
Export.getTemplateData = function () {
var $form = $('form[name="dump"]');
var excludeList = ['token', 'server', 'db', 'table', 'single_table', 'export_type', 'export_method', 'sql_query', 'template_id'];
var obj = {};
var arr = $form.serializeArray();
$.each(arr, function () {
if ($.inArray(this.name, excludeList) < 0) {
if (obj[this.name] !== undefined) {
if (!obj[this.name].push) {
obj[this.name] = [obj[this.name]];
}
obj[this.name].push(this.value || '');
} else {
obj[this.name] = this.value || '';
}
}
});
// include unchecked checkboxes (which are ignored by serializeArray()) with null
// to uncheck them when loading the template
$form.find('input[type="checkbox"]:not(:checked)').each(function () {
if (obj[this.name] === undefined) {
obj[this.name] = null;
}
});
// include empty multiselects
$form.find('select').each(function () {
if ($(this).find('option:selected').length === 0) {
obj[this.name] = [];
}
});
return obj;
};
/**
* Create a template with selected options
*
* @param name name of the template
*/
Export.createTemplate = function (name) {
var templateData = Export.getTemplateData();
var params = {
'ajax_request': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'exportType': $('input[name="export_type"]').val(),
'templateName': name,
'templateData': JSON.stringify(templateData)
};
Functions.ajaxShowMessage();
$.post('index.php?route=/export/template/create', params, function (response) {
if (response.success === true) {
$('#templateName').val('');
$('#template').html(response.data);
$('#template').find('option').each(function () {
if ($(this).text() === name) {
$(this).prop('selected', true);
}
});
Functions.ajaxShowMessage(Messages.strTemplateCreated);
} else {
Functions.ajaxShowMessage(response.error, false);
}
});
};
/**
* Loads a template
*
* @param id ID of the template to load
*/
Export.loadTemplate = function (id) {
var params = {
'ajax_request': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'exportType': $('input[name="export_type"]').val(),
'templateId': id
};
Functions.ajaxShowMessage();
$.post('index.php?route=/export/template/load', params, function (response) {
if (response.success === true) {
var $form = $('form[name="dump"]');
var options = JSON.parse(response.data);
$.each(options, function (key, value) {
var localValue = value;
var $element = $form.find('[name="' + key + '"]');
if ($element.length) {
if ($element.is('input') && $element.attr('type') === 'checkbox' && localValue === null) {
$element.prop('checked', false);
} else {
if ($element.is('input') && $element.attr('type') === 'checkbox' || $element.is('input') && $element.attr('type') === 'radio' || $element.is('select') && $element.attr('multiple') === 'multiple') {
if (!localValue.push) {
localValue = [localValue];
}
}
$element.val(localValue);
}
$element.trigger('change');
}
});
$('input[name="template_id"]').val(id);
Functions.ajaxShowMessage(Messages.strTemplateLoaded);
} else {
Functions.ajaxShowMessage(response.error, false);
}
});
};
/**
* Updates an existing template with current options
*
* @param id ID of the template to update
*/
Export.updateTemplate = function (id) {
var templateData = Export.getTemplateData();
var params = {
'ajax_request': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'exportType': $('input[name="export_type"]').val(),
'templateId': id,
'templateData': JSON.stringify(templateData)
};
Functions.ajaxShowMessage();
$.post('index.php?route=/export/template/update', params, function (response) {
if (response.success === true) {
Functions.ajaxShowMessage(Messages.strTemplateUpdated);
} else {
Functions.ajaxShowMessage(response.error, false);
}
});
};
/**
* Delete a template
*
* @param id ID of the template to delete
*/
Export.deleteTemplate = function (id) {
var params = {
'ajax_request': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'exportType': $('input[name="export_type"]').val(),
'templateId': id
};
Functions.ajaxShowMessage();
$.post('index.php?route=/export/template/delete', params, function (response) {
if (response.success === true) {
$('#template').find('option[value="' + id + '"]').remove();
Functions.ajaxShowMessage(Messages.strTemplateDeleted);
} else {
Functions.ajaxShowMessage(response.error, false);
}
});
};
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('export.js', function () {
$('#plugins').off('change');
$('input[type=\'radio\'][name=\'sql_structure_or_data\']').off('change');
$('input[type=\'radio\'][name$=\'_structure_or_data\']').off('change');
$('input[type=\'radio\'][name=\'output_format\']').off('change');
$('#checkbox_sql_include_comments').off('change');
$('input[type=\'radio\'][name=\'quick_or_custom\']').off('change');
$('input[type=\'radio\'][name=\'allrows\']').off('change');
$('#btn_alias_config').off('click');
$('.alias_remove').off('click');
$('#db_alias_button').off('click');
$('#table_alias_button').off('click');
$('#column_alias_button').off('click');
$('input[name="table_select[]"]').off('change');
$('input[name="table_structure[]"]').off('change');
$('input[name="table_data[]"]').off('change');
$('#table_structure_all').off('change');
$('#table_data_all').off('change');
$('input[name="createTemplate"]').off('click');
$('select[name="template"]').off('change');
$('input[name="updateTemplate"]').off('click');
$('input[name="deleteTemplate"]').off('click');
});
AJAX.registerOnload('export.js', function () {
$('#showsqlquery').on('click', function () {
// Creating a dialog box similar to preview sql container to show sql query
var modal = $('#showSqlQueryModal');
modal.modal('show');
modal.on('shown.bs.modal', function () {
$('#showSqlQueryModalLabel').first().html(Messages.strQuery);
Functions.highlightSql(modal);
});
});
/**
* Export template handling code
*/
// create a new template
$('input[name="createTemplate"]').on('click', function (e) {
e.preventDefault();
var name = $('input[name="templateName"]').val();
if (name.length) {
Export.createTemplate(name);
}
});
// load an existing template
$('select[name="template"]').on('change', function (e) {
e.preventDefault();
var id = $(this).val();
if (id.length) {
Export.loadTemplate(id);
}
});
// update an existing template with new criteria
$('input[name="updateTemplate"]').on('click', function (e) {
e.preventDefault();
var id = $('select[name="template"]').val();
if (id.length) {
Export.updateTemplate(id);
}
});
// delete an existing template
$('input[name="deleteTemplate"]').on('click', function (e) {
e.preventDefault();
var id = $('select[name="template"]').val();
if (id.length) {
Export.deleteTemplate(id);
}
});
/**
* Toggles the hiding and showing of each plugin's options
* according to the currently selected plugin from the dropdown list
*/
$('#plugins').on('change', function () {
$('#format_specific_opts').find('div.format_specific_options').addClass('d-none');
var selectedPluginName = $('#plugins').find('option:selected').val();
$('#' + selectedPluginName + '_options').removeClass('d-none');
});
/**
* Toggles the enabling and disabling of the SQL plugin's comment options that apply only when exporting structure
*/
$('input[type=\'radio\'][name=\'sql_structure_or_data\']').on('change', function () {
var commentsArePresent = $('#checkbox_sql_include_comments').prop('checked');
var show = $('input[type=\'radio\'][name=\'sql_structure_or_data\']:checked').val();
if (show === 'data') {
// disable the SQL comment options
if (commentsArePresent) {
$('#checkbox_sql_dates').prop('disabled', true).parent().fadeTo('fast', 0.4);
}
$('#checkbox_sql_relation').prop('disabled', true).parent().fadeTo('fast', 0.4);
$('#checkbox_sql_mime').prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
// enable the SQL comment options
if (commentsArePresent) {
$('#checkbox_sql_dates').prop('disabled', false).parent().fadeTo('fast', 1);
}
$('#checkbox_sql_relation').prop('disabled', false).parent().fadeTo('fast', 1);
$('#checkbox_sql_mime').prop('disabled', false).parent().fadeTo('fast', 1);
}
if (show === 'structure') {
$('#checkbox_sql_auto_increment').prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
$('#checkbox_sql_auto_increment').prop('disabled', false).parent().fadeTo('fast', 1);
}
});
// When MS Excel is selected as the Format automatically Switch to Character Set as windows-1252
$('#plugins').on('change', function () {
var selectedPluginName = $('#plugins').find('option:selected').val();
if (selectedPluginName === 'excel') {
$('#select_charset').val('windows-1252');
} else {
$('#select_charset').val('utf-8');
}
});
// For separate-file exports only ZIP compression is allowed
$('input[type="checkbox"][name="as_separate_files"]').on('change', function () {
if ($(this).is(':checked')) {
$('#compression').val('zip');
}
});
$('#compression').on('change', function () {
if ($('option:selected').val() !== 'zip') {
$('input[type="checkbox"][name="as_separate_files"]').prop('checked', false);
}
});
});
Export.setupTableStructureOrData = function () {
if ($('input[name=\'export_type\']').val() !== 'database') {
return;
}
var pluginName = $('#plugins').find('option:selected').val();
var formElemName = pluginName + '_structure_or_data';
var forceStructureOrData = !$('input[name=\'' + formElemName + '_default\']').length;
if (forceStructureOrData === true) {
$('input[name="structure_or_data_forced"]').val(1);
$('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]').prop('disabled', true);
$('.export_structure, .export_data').fadeTo('fast', 0.4);
} else {
$('input[name="structure_or_data_forced"]').val(0);
$('.export_structure input[type="checkbox"], .export_data input[type="checkbox"]').prop('disabled', false);
$('.export_structure, .export_data').fadeTo('fast', 1);
var structureOrData = $('input[name="' + formElemName + '_default"]').val();
if (structureOrData === 'structure') {
$('.export_data input[type="checkbox"]').prop('checked', false);
} else if (structureOrData === 'data') {
$('.export_structure input[type="checkbox"]').prop('checked', false);
}
if (structureOrData === 'structure' || structureOrData === 'structure_and_data') {
if (!$('.export_structure input[type="checkbox"]:checked').length) {
$('input[name="table_select[]"]:checked').closest('tr').find('.export_structure input[type="checkbox"]').prop('checked', true);
}
}
if (structureOrData === 'data' || structureOrData === 'structure_and_data') {
if (!$('.export_data input[type="checkbox"]:checked').length) {
$('input[name="table_select[]"]:checked').closest('tr').find('.export_data input[type="checkbox"]').prop('checked', true);
}
}
Export.checkSelectedTables();
Export.checkTableSelectAll();
Export.checkTableSelectStructureOrData();
}
};
/**
* Toggles the hiding and showing of plugin structure-specific and data-specific
* options
*/
Export.toggleStructureDataOpts = function () {
var pluginName = $('select#plugins').val();
var radioFormName = pluginName + '_structure_or_data';
var dataDiv = '#' + pluginName + '_data';
var structureDiv = '#' + pluginName + '_structure';
var show = $('input[type=\'radio\'][name=\'' + radioFormName + '\']:checked').val();
// Show the #rows if 'show' is not structure
$('#rows').toggle(show !== 'structure');
if (show === 'data') {
$(dataDiv).slideDown('slow');
$(structureDiv).slideUp('slow');
} else {
$(structureDiv).slideDown('slow');
if (show === 'structure') {
$(dataDiv).slideUp('slow');
} else {
$(dataDiv).slideDown('slow');
}
}
};
/**
* Toggles the disabling of the "save to file" options
*/
Export.toggleSaveToFile = function () {
var $ulSaveAsfile = $('#ul_save_asfile');
if (!$('#radio_dump_asfile').prop('checked')) {
$ulSaveAsfile.find('> li').fadeTo('fast', 0.4);
$ulSaveAsfile.find('> li > input').prop('disabled', true);
$ulSaveAsfile.find('> li > select').prop('disabled', true);
} else {
$ulSaveAsfile.find('> li').fadeTo('fast', 1);
$ulSaveAsfile.find('> li > input').prop('disabled', false);
$ulSaveAsfile.find('> li > select').prop('disabled', false);
}
};
AJAX.registerOnload('export.js', function () {
Export.toggleSaveToFile();
$('input[type=\'radio\'][name=\'output_format\']').on('change', Export.toggleSaveToFile);
});
/**
* For SQL plugin, toggles the disabling of the "display comments" options
*/
Export.toggleSqlIncludeComments = function () {
$('#checkbox_sql_include_comments').on('change', function () {
var $ulIncludeComments = $('#ul_include_comments');
if (!$('#checkbox_sql_include_comments').prop('checked')) {
$ulIncludeComments.find('> li').fadeTo('fast', 0.4);
$ulIncludeComments.find('> li > input').prop('disabled', true);
} else {
// If structure is not being exported, the comment options for structure should not be enabled
if ($('#radio_sql_structure_or_data_data').prop('checked')) {
$('#text_sql_header_comment').prop('disabled', false).parent('li').fadeTo('fast', 1);
} else {
$ulIncludeComments.find('> li').fadeTo('fast', 1);
$ulIncludeComments.find('> li > input').prop('disabled', false);
}
}
});
};
Export.checkTableSelectAll = function () {
var total = $('input[name="table_select[]"]').length;
var strChecked = $('input[name="table_structure[]"]:checked').length;
var dataChecked = $('input[name="table_data[]"]:checked').length;
var strAll = $('#table_structure_all');
var dataAll = $('#table_data_all');
if (strChecked === total) {
strAll.prop('indeterminate', false).prop('checked', true);
} else if (strChecked === 0) {
strAll.prop('indeterminate', false).prop('checked', false);
} else {
strAll.prop('indeterminate', true).prop('checked', false);
}
if (dataChecked === total) {
dataAll.prop('indeterminate', false).prop('checked', true);
} else if (dataChecked === 0) {
dataAll.prop('indeterminate', false).prop('checked', false);
} else {
dataAll.prop('indeterminate', true).prop('checked', false);
}
};
Export.checkTableSelectStructureOrData = function () {
var dataChecked = $('input[name="table_data[]"]:checked').length;
var autoIncrement = $('#checkbox_sql_auto_increment');
var pluginName = $('select#plugins').val();
var dataDiv = '#' + pluginName + '_data';
if (dataChecked === 0) {
$(dataDiv).slideUp('slow');
autoIncrement.prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
$(dataDiv).slideDown('slow');
autoIncrement.prop('disabled', false).parent().fadeTo('fast', 1);
}
};
Export.toggleTableSelectAllStr = function () {
var strAll = $('#table_structure_all').is(':checked');
if (strAll) {
$('input[name="table_structure[]"]').prop('checked', true);
} else {
$('input[name="table_structure[]"]').prop('checked', false);
}
};
Export.toggleTableSelectAllData = function () {
var dataAll = $('#table_data_all').is(':checked');
if (dataAll) {
$('input[name="table_data[]"]').prop('checked', true);
} else {
$('input[name="table_data[]"]').prop('checked', false);
}
};
Export.checkSelectedTables = function () {
$('.export_table_select tbody tr').each(function () {
Export.checkTableSelected(this);
});
};
Export.checkTableSelected = function (row) {
var $row = $(row);
var tableSelect = $row.find('input[name="table_select[]"]');
var strCheck = $row.find('input[name="table_structure[]"]');
var dataCheck = $row.find('input[name="table_data[]"]');
var data = dataCheck.is(':checked:not(:disabled)');
var structure = strCheck.is(':checked:not(:disabled)');
if (data && structure) {
tableSelect.prop({
checked: true,
indeterminate: false
});
$row.addClass('marked');
} else if (data || structure) {
tableSelect.prop({
checked: true,
indeterminate: true
});
$row.removeClass('marked');
} else {
tableSelect.prop({
checked: false,
indeterminate: false
});
$row.removeClass('marked');
}
};
Export.toggleTableSelect = function (row) {
var $row = $(row);
var tableSelected = $row.find('input[name="table_select[]"]').is(':checked');
if (tableSelected) {
$row.find('input[type="checkbox"]:not(:disabled)').prop('checked', true);
$row.addClass('marked');
} else {
$row.find('input[type="checkbox"]:not(:disabled)').prop('checked', false);
$row.removeClass('marked');
}
};
Export.handleAddProcCheckbox = function () {
if ($('#table_structure_all').is(':checked') === true && $('#table_data_all').is(':checked') === true) {
$('#checkbox_sql_procedure_function').prop('checked', true);
} else {
$('#checkbox_sql_procedure_function').prop('checked', false);
}
};
AJAX.registerOnload('export.js', function () {
/**
* For SQL plugin, if "CREATE TABLE options" is checked/unchecked, check/uncheck each of its sub-options
*/
var $create = $('#checkbox_sql_create_table_statements');
var $createOptions = $('#ul_create_table_statements').find('input');
$create.on('change', function () {
$createOptions.prop('checked', $(this).prop('checked'));
});
$createOptions.on('change', function () {
if ($createOptions.is(':checked')) {
$create.prop('checked', true);
}
});
/**
* Disables the view output as text option if the output must be saved as a file
*/
$('#plugins').on('change', function () {
var activePlugin = $('#plugins').find('option:selected').val();
var forceFile = $('#force_file_' + activePlugin).val();
if (forceFile === 'true') {
if ($('#radio_dump_asfile').prop('checked') !== true) {
$('#radio_dump_asfile').prop('checked', true);
Export.toggleSaveToFile();
}
$('#radio_view_as_text').prop('disabled', true).parent().fadeTo('fast', 0.4);
} else {
$('#radio_view_as_text').prop('disabled', false).parent().fadeTo('fast', 1);
}
});
$('input[type=\'radio\'][name$=\'_structure_or_data\']').on('change', function () {
Export.toggleStructureDataOpts();
});
$('input[name="table_select[]"]').on('change', function () {
Export.toggleTableSelect($(this).closest('tr'));
Export.checkTableSelectAll();
Export.handleAddProcCheckbox();
Export.checkTableSelectStructureOrData();
});
$('input[name="table_structure[]"]').on('change', function () {
Export.checkTableSelected($(this).closest('tr'));
Export.checkTableSelectAll();
Export.handleAddProcCheckbox();
Export.checkTableSelectStructureOrData();
});
$('input[name="table_data[]"]').on('change', function () {
Export.checkTableSelected($(this).closest('tr'));
Export.checkTableSelectAll();
Export.handleAddProcCheckbox();
Export.checkTableSelectStructureOrData();
});
$('#table_structure_all').on('change', function () {
Export.toggleTableSelectAllStr();
Export.checkSelectedTables();
Export.handleAddProcCheckbox();
Export.checkTableSelectStructureOrData();
});
$('#table_data_all').on('change', function () {
Export.toggleTableSelectAllData();
Export.checkSelectedTables();
Export.handleAddProcCheckbox();
Export.checkTableSelectStructureOrData();
});
if ($('input[name=\'export_type\']').val() === 'database') {
// Hide structure or data radio buttons
$('input[type=\'radio\'][name$=\'_structure_or_data\']').each(function () {
var $this = $(this);
var name = $this.prop('name');
var val = $('input[name="' + name + '"]:checked').val();
var nameDefault = name + '_default';
if (!$('input[name="' + nameDefault + '"]').length) {
$this.after($('<input type="hidden" name="' + nameDefault + '" value="' + val + '" disabled>')).after($('<input type="hidden" name="' + name + '" value="structure_and_data">'));
$this.parent().find('label').remove();
} else {
$this.parent().remove();
}
});
$('input[type=\'radio\'][name$=\'_structure_or_data\']').remove();
// Disable CREATE table checkbox for sql
var createTableCheckbox = $('#checkbox_sql_create_table');
createTableCheckbox.prop('checked', true);
var dummyCreateTable = $('#checkbox_sql_create_table').clone().removeAttr('id').attr('type', 'hidden');
createTableCheckbox.prop('disabled', true).after(dummyCreateTable).parent().fadeTo('fast', 0.4);
Export.setupTableStructureOrData();
}
/**
* Handle force structure_or_data
*/
$('#plugins').on('change', Export.setupTableStructureOrData);
});
/**
* Toggles display of options when quick and custom export are selected
*/
Export.toggleQuickOrCustom = function () {
if ($('input[name=\'quick_or_custom\']').length === 0 // custom_no_form option
|| $('#radio_custom_export').prop('checked') // custom
) {
$('#databases_and_tables').show();
$('#rows').show();
$('#output').show();
$('#format_specific_opts').show();
$('#output_quick_export').addClass('d-none');
var selectedPluginName = $('#plugins').find('option:selected').val();
$('#' + selectedPluginName + '_options').removeClass('d-none');
} else {
// quick
$('#databases_and_tables').hide();
$('#rows').hide();
$('#output').hide();
$('#format_specific_opts').hide();
$('#output_quick_export').removeClass('d-none');
}
};
var timeOut;
Export.checkTimeOut = function (timeLimit) {
var limit = timeLimit;
if (typeof limit === 'undefined' || limit === 0) {
return true;
}
// margin of one second to avoid race condition to set/access session variable
limit = limit + 1;
clearTimeout(timeOut);
timeOut = setTimeout(function () {
$.get('index.php?route=/export/check-time-out', {
'ajax_request': true
}, function (data) {
if (data.message === 'timeout') {
Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert">' + Messages.strTimeOutError + '</div>', false);
}
});
}, limit * 1000);
};
/**
* Handler for Alias dialog box
*
* @param event object the event object
*
* @return {void}
*/
Export.createAliasModal = function (event) {
event.preventDefault();
var modal = $('#renameExportModal');
modal.modal('show');
modal.on('shown.bs.modal', function () {
modal.closest('.ui-dialog').find('.ui-button').addClass('btn btn-secondary');
var db = CommonParams.get('db');
if (db) {
var option = $('<option></option>');
option.text(db);
option.attr('value', db);
$('#db_alias_select').append(option).val(db).trigger('change');
} else {
var params = {
'ajax_request': true,
'server': CommonParams.get('server')
};
$.post('index.php?route=/databases', params, function (response) {
if (response.success === true) {
$.each(response.databases, function (idx, value) {
var option = $('<option></option>');
option.text(value);
option.attr('value', value);
$('#db_alias_select').append(option);
});
} else {
Functions.ajaxShowMessage(response.error, false);
}
});
}
});
modal.on('hidden.bs.modal', function () {
var isEmpty = true;
$(this).find('input[type="text"]').each(function () {
// trim empty input fields on close
if ($(this).val()) {
isEmpty = false;
} else {
$(this).parents('tr').remove();
}
});
// Toggle checkbox based on aliases
$('input#btn_alias_config').prop('checked', !isEmpty);
});
$('#saveAndCloseBtn').on('click', function () {
$('#alias_modal').parent().appendTo($('form[name="dump"]'));
});
};
Export.aliasToggleRow = function (elm) {
var inputs = elm.parents('tr').find('input,button');
if (elm.val()) {
inputs.attr('disabled', false);
} else {
inputs.attr('disabled', true);
}
};
Export.aliasRow = null;
Export.addAlias = function (type, name, field, value) {
if (value === '') {
return;
}
if (Export.aliasRow === null) {
Export.aliasRow = $('#alias_data tfoot tr');
}
var row = Export.aliasRow.clone();
row.find('th').text(type);
row.find('td').first().text(name);
row.find('input').attr('name', field);
row.find('input').val(value);
row.find('.alias_remove').on('click', function () {
$(this).parents('tr').remove();
});
var matching = $('#alias_data [name="' + $.escapeSelector(field) + '"]');
if (matching.length > 0) {
matching.parents('tr').remove();
}
$('#alias_data tbody').append(row);
};
AJAX.registerOnload('export.js', function () {
$('input[type=\'radio\'][name=\'quick_or_custom\']').on('change', Export.toggleQuickOrCustom);
$('#format_specific_opts').find('div.format_specific_options').addClass('d-none').find('h3').remove();
Export.toggleQuickOrCustom();
Export.toggleStructureDataOpts();
Export.toggleSqlIncludeComments();
Export.checkTableSelectAll();
Export.handleAddProcCheckbox();
/**
* Initially disables the "Dump some row(s)" sub-options
*/
Export.disableDumpSomeRowsSubOptions();
/**
* Disables the "Dump some row(s)" sub-options when it is not selected
*/
$('input[type=\'radio\'][name=\'allrows\']').on('change', function () {
if ($('#radio_allrows_0').prop('checked')) {
Export.enableDumpSomeRowsSubOptions();
} else {
Export.disableDumpSomeRowsSubOptions();
}
});
// Open Alias Modal Dialog on click
$('#btn_alias_config').on('click', Export.createAliasModal);
$('.alias_remove').on('click', function () {
$(this).parents('tr').remove();
});
$('#db_alias_select').on('change', function () {
Export.aliasToggleRow($(this));
var table = CommonParams.get('table');
if (table) {
var option = $('<option></option>');
option.text(table);
option.attr('value', table);
$('#table_alias_select').append(option).val(table).trigger('change');
} else {
var database = $(this).val();
var params = {
'ajax_request': true,
'server': CommonParams.get('server'),
'db': database
};
var url = 'index.php?route=/tables';
$.post(url, params, function (response) {
if (response.success === true) {
$.each(response.tables, function (idx, value) {
var option = $('<option></option>');
option.text(value);
option.attr('value', value);
$('#table_alias_select').append(option);
});
} else {
Functions.ajaxShowMessage(response.error, false);
}
});
}
});
$('#table_alias_select').on('change', function () {
Export.aliasToggleRow($(this));
var database = $('#db_alias_select').val();
var table = $(this).val();
var params = {
'ajax_request': true,
'server': CommonParams.get('server'),
'db': database,
'table': table
};
var url = 'index.php?route=/columns';
$.post(url, params, function (response) {
if (response.success === true) {
$.each(response.columns, function (idx, value) {
var option = $('<option></option>');
option.text(value);
option.attr('value', value);
$('#column_alias_select').append(option);
});
} else {
Functions.ajaxShowMessage(response.error, false);
}
});
});
$('#column_alias_select').on('change', function () {
Export.aliasToggleRow($(this));
});
$('#db_alias_button').on('click', function (e) {
e.preventDefault();
var db = $('#db_alias_select').val();
Export.addAlias(Messages.strAliasDatabase, db, 'aliases[' + db + '][alias]', $('#db_alias_name').val());
$('#db_alias_name').val('');
});
$('#table_alias_button').on('click', function (e) {
e.preventDefault();
var db = $('#db_alias_select').val();
var table = $('#table_alias_select').val();
Export.addAlias(Messages.strAliasTable, db + '.' + table, 'aliases[' + db + '][tables][' + table + '][alias]', $('#table_alias_name').val());
$('#table_alias_name').val('');
});
$('#column_alias_button').on('click', function (e) {
e.preventDefault();
var db = $('#db_alias_select').val();
var table = $('#table_alias_select').val();
var column = $('#column_alias_select').val();
Export.addAlias(Messages.strAliasColumn, db + '.' + table + '.' + column, 'aliases[' + db + '][tables][' + table + '][colums][' + column + ']', $('#column_alias_name').val());
$('#column_alias_name').val('');
});
var setSelectOptions = function (doCheck) {
Functions.setSelectOptions('dump', 'db_select[]', doCheck);
};
$('#db_select_all').on('click', function (e) {
e.preventDefault();
setSelectOptions(true);
});
$('#db_unselect_all').on('click', function (e) {
e.preventDefault();
setSelectOptions(false);
});
$('#buttonGo').on('click', function () {
var timeLimit = parseInt($(this).attr('data-exec-time-limit'));
// If the time limit set is zero,
// then time out won't occur so no need to check for time out.
if (timeLimit > 0) {
Export.checkTimeOut(timeLimit);
}
});
});

View file

@ -1,12 +0,0 @@
AJAX.registerOnload('export_output.js', function () {
$(document).on('keydown', function (e) {
if ((e.which || e.keyCode) === 116) {
e.preventDefault();
$('#export_refresh_form').trigger('submit');
}
});
$('.export_refresh_btn').on('click', function (e) {
e.preventDefault();
$('#export_refresh_form').trigger('submit');
});
});

File diff suppressed because it is too large Load diff

View file

@ -1,356 +0,0 @@
/**
* @fileoverview functions used in GIS data editor
*
* @requires jQuery
*
*/
/* global addZoomPanControllers, storeGisSvgRef, selectVisualization, styleOSM, zoomAndPan */ // js/table/gis_visualization.js
/* global themeImagePath */ // templates/javascript/variables.twig
// eslint-disable-next-line no-unused-vars
var gisEditorLoaded = false;
/**
* Closes the GIS data editor and perform necessary clean up work.
*/
function closeGISEditor() {
$('#popup_background').fadeOut('fast');
$('#gis_editor').fadeOut('fast', function () {
$(this).empty();
});
}
/**
* Prepares the HTML received via AJAX.
*/
function prepareJSVersion() {
// Change the text on the submit button
$('#gis_editor').find('input[name=\'gis_data[save]\']').val(Messages.strCopy).insertAfter($('#gis_data_textarea')).before('<br><br>');
// Add close and cancel links
$('#gis_data_editor').prepend('<a class="close_gis_editor" href="#">' + Messages.strClose + '</a>');
$('<a class="cancel_gis_editor" href="#"> ' + Messages.strCancel + '</a>').insertAfter($('input[name=\'gis_data[save]\']'));
// Remove the unnecessary text
$('div#gis_data_output p').remove();
// Remove 'add' buttons and add links
$('#gis_editor').find('input.add').each(function () {
var $button = $(this);
$button.addClass('addJs').removeClass('add');
var classes = $button.attr('class');
$button.replaceWith('<a class="' + classes + '" name="' + $button.attr('name') + '" href="#">+ ' + $button.val() + '</a>');
});
}
/**
* Returns the HTML for a data point.
*
* @param {number} pointNumber point number
* @param {string} prefix prefix of the name
* @return {string} the HTML for a data point
*/
function addDataPoint(pointNumber, prefix) {
return '<br>' + Functions.sprintf(Messages.strPointN, pointNumber + 1) + ': ' + '<label for="x">' + Messages.strX + '</label>' + '<input type="text" name="' + prefix + '[' + pointNumber + '][x]" value="">' + '<label for="y">' + Messages.strY + '</label>' + '<input type="text" name="' + prefix + '[' + pointNumber + '][y]" value="">';
}
/**
* Initialize the visualization in the GIS data editor.
*/
function initGISEditorVisualization() {
storeGisSvgRef();
// Loads either SVG or OSM visualization based on the choice
selectVisualization();
// Adds necessary styles to the div that contains the openStreetMap
styleOSM();
// Adds controllers for zooming and panning
addZoomPanControllers();
zoomAndPan();
}
/**
* Loads JavaScript files and the GIS editor.
*
* @param value current value of the geometry field
* @param field field name
* @param type geometry type
* @param inputName name of the input field
* @param token token
*/
// eslint-disable-next-line no-unused-vars
function loadJSAndGISEditor(value, field, type, inputName) {
var head = document.getElementsByTagName('head')[0];
var script;
script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'js/dist/table/gis_visualization.js';
head.appendChild(script);
// OpenLayers.js is BIG and takes time. So asynchronous loading would not work.
// Load the JS and do a callback to load the content for the GIS Editor.
script = document.createElement('script');
script.type = 'text/javascript';
script.onreadystatechange = function () {
if (this.readyState === 'complete') {
loadGISEditor(value, field, type, inputName);
}
};
script.onload = function () {
loadGISEditor(value, field, type, inputName);
};
script.onerror = function () {
loadGISEditor(value, field, type, inputName);
};
script.src = 'js/vendor/openlayers/OpenLayers.js';
head.appendChild(script);
gisEditorLoaded = true;
}
/**
* Loads the GIS editor via AJAX
*
* @param value current value of the geometry field
* @param field field name
* @param type geometry type
* @param inputName name of the input field
*/
function loadGISEditor(value, field, type, inputName) {
var $gisEditor = $('#gis_editor');
$.post('index.php?route=/gis-data-editor', {
'field': field,
'value': value,
'type': type,
'input_name': inputName,
'get_gis_editor': true,
'ajax_request': true,
'server': CommonParams.get('server')
}, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$gisEditor.html(data.gis_editor);
initGISEditorVisualization();
prepareJSVersion();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}, 'json');
}
/**
* Opens up the dialog for the GIS data editor.
*/
// eslint-disable-next-line no-unused-vars
function openGISEditor() {
// Center the popup
var windowWidth = document.documentElement.clientWidth;
var windowHeight = document.documentElement.clientHeight;
var popupWidth = windowWidth * 0.9;
var popupHeight = windowHeight * 0.9;
var popupOffsetTop = windowHeight / 2 - popupHeight / 2;
var popupOffsetLeft = windowWidth / 2 - popupWidth / 2;
var $gisEditor = $('#gis_editor');
var $background = $('#popup_background');
$gisEditor.css({
'top': popupOffsetTop,
'left': popupOffsetLeft,
'width': popupWidth,
'height': popupHeight
});
$background.css({
'opacity': '0.7'
});
$gisEditor.append('<div id="gis_data_editor">' + '<img class="ajaxIcon" id="loadingMonitorIcon" src="' + themeImagePath + 'ajax_clock_small.gif" alt="">' + '</div>');
// Make it appear
$background.fadeIn('fast');
$gisEditor.fadeIn('fast');
}
/**
* Prepare and insert the GIS data in Well Known Text format
* to the input field.
*/
function insertDataAndClose() {
var $form = $('form#gis_data_editor_form');
var inputName = $form.find('input[name=\'input_name\']').val();
var argsep = CommonParams.get('arg_separator');
$.post('index.php?route=/gis-data-editor', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$('input[name=\'' + inputName + '\']').val(data.result);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}, 'json');
closeGISEditor();
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('gis_data_editor.js', function () {
$(document).off('click', '#gis_editor input[name=\'gis_data[save]\']');
$(document).off('submit', '#gis_editor');
$(document).off('change', '#gis_editor input[type=\'text\']');
$(document).off('change', '#gis_editor select.gis_type');
$(document).off('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor');
$(document).off('click', '#gis_editor a.addJs.addPoint');
$(document).off('click', '#gis_editor a.addLine.addJs');
$(document).off('click', '#gis_editor a.addJs.addPolygon');
$(document).off('click', '#gis_editor a.addJs.addGeom');
});
AJAX.registerOnload('gis_data_editor.js', function () {
/**
* Prepares and insert the GIS data to the input field on clicking 'copy'.
*/
$(document).on('click', '#gis_editor input[name=\'gis_data[save]\']', function (event) {
event.preventDefault();
insertDataAndClose();
});
/**
* Prepares and insert the GIS data to the input field on pressing 'enter'.
*/
$(document).on('submit', '#gis_editor', function (event) {
event.preventDefault();
insertDataAndClose();
});
/**
* Trigger asynchronous calls on data change and update the output.
*/
$(document).on('change', '#gis_editor input[type=\'text\']', function () {
var $form = $('form#gis_data_editor_form');
var argsep = CommonParams.get('arg_separator');
$.post('index.php?route=/gis-data-editor', $form.serialize() + argsep + 'generate=true' + argsep + 'ajax_request=true', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$('#gis_data_textarea').val(data.result);
$('#placeholder').empty().removeClass('hasSVG').html(data.visualization);
$('#openlayersmap').empty();
/* TODO: the gis_data_editor should rather return JSON than JS code to eval */
// eslint-disable-next-line no-eval
eval(data.openLayers);
initGISEditorVisualization();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}, 'json');
});
/**
* Update the form on change of the GIS type.
*/
$(document).on('change', '#gis_editor select.gis_type', function () {
var $gisEditor = $('#gis_editor');
var $form = $('form#gis_data_editor_form');
var argsep = CommonParams.get('arg_separator');
$.post('index.php?route=/gis-data-editor', $form.serialize() + argsep + 'get_gis_editor=true' + argsep + 'ajax_request=true', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$gisEditor.html(data.gis_editor);
initGISEditorVisualization();
prepareJSVersion();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}, 'json');
});
/**
* Handles closing of the GIS data editor.
*/
$(document).on('click', '#gis_editor a.close_gis_editor, #gis_editor a.cancel_gis_editor', function () {
closeGISEditor();
});
/**
* Handles adding data points
*/
$(document).on('click', '#gis_editor a.addJs.addPoint', function () {
var $a = $(this);
var name = $a.attr('name');
// Eg. name = gis_data[0][MULTIPOINT][add_point] => prefix = gis_data[0][MULTIPOINT]
var prefix = name.substr(0, name.length - 11);
// Find the number of points
var $noOfPointsInput = $('input[name=\'' + prefix + '[no_of_points]' + '\']');
var noOfPoints = parseInt($noOfPointsInput.val(), 10);
// Add the new data point
var html = addDataPoint(noOfPoints, prefix);
$a.before(html);
$noOfPointsInput.val(noOfPoints + 1);
});
/**
* Handles adding linestrings and inner rings
*/
$(document).on('click', '#gis_editor a.addLine.addJs', function () {
var $a = $(this);
var name = $a.attr('name');
// Eg. name = gis_data[0][MULTILINESTRING][add_line] => prefix = gis_data[0][MULTILINESTRING]
var prefix = name.substr(0, name.length - 10);
var type = prefix.slice(prefix.lastIndexOf('[') + 1, prefix.lastIndexOf(']'));
// Find the number of lines
var $noOfLinesInput = $('input[name=\'' + prefix + '[no_of_lines]' + '\']');
var noOfLines = parseInt($noOfLinesInput.val(), 10);
// Add the new linesting of inner ring based on the type
var html = '<br>';
var noOfPoints;
if (type === 'MULTILINESTRING') {
html += Messages.strLineString + ' ' + (noOfLines + 1) + ':';
noOfPoints = 2;
} else {
html += Messages.strInnerRing + ' ' + noOfLines + ':';
noOfPoints = 4;
}
html += '<input type="hidden" name="' + prefix + '[' + noOfLines + '][no_of_points]" value="' + noOfPoints + '">';
for (var i = 0; i < noOfPoints; i++) {
html += addDataPoint(i, prefix + '[' + noOfLines + ']');
}
html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfLines + '][add_point]" href="#">+ ' + Messages.strAddPoint + '</a><br>';
$a.before(html);
$noOfLinesInput.val(noOfLines + 1);
});
/**
* Handles adding polygons
*/
$(document).on('click', '#gis_editor a.addJs.addPolygon', function () {
var $a = $(this);
var name = $a.attr('name');
// Eg. name = gis_data[0][MULTIPOLYGON][add_polygon] => prefix = gis_data[0][MULTIPOLYGON]
var prefix = name.substr(0, name.length - 13);
// Find the number of polygons
var $noOfPolygonsInput = $('input[name=\'' + prefix + '[no_of_polygons]' + '\']');
var noOfPolygons = parseInt($noOfPolygonsInput.val(), 10);
// Add the new polygon
var html = Messages.strPolygon + ' ' + (noOfPolygons + 1) + ':<br>';
html += '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][no_of_lines]" value="1">' + '<br>' + Messages.strOuterRing + ':' + '<input type="hidden" name="' + prefix + '[' + noOfPolygons + '][0][no_of_points]" value="4">';
for (var i = 0; i < 4; i++) {
html += addDataPoint(i, prefix + '[' + noOfPolygons + '][0]');
}
html += '<a class="addPoint addJs" name="' + prefix + '[' + noOfPolygons + '][0][add_point]" href="#">+ ' + Messages.strAddPoint + '</a><br>' + '<a class="addLine addJs" name="' + prefix + '[' + noOfPolygons + '][add_line]" href="#">+ ' + Messages.strAddInnerRing + '</a><br><br>';
$a.before(html);
$noOfPolygonsInput.val(noOfPolygons + 1);
});
/**
* Handles adding geoms
*/
$(document).on('click', '#gis_editor a.addJs.addGeom', function () {
var $a = $(this);
var prefix = 'gis_data[GEOMETRYCOLLECTION]';
// Find the number of geoms
var $noOfGeomsInput = $('input[name=\'' + prefix + '[geom_count]' + '\']');
var noOfGeoms = parseInt($noOfGeomsInput.val(), 10);
var html1 = Messages.strGeometry + ' ' + (noOfGeoms + 1) + ':<br>';
var $geomType = $('select[name=\'gis_data[' + (noOfGeoms - 1) + '][gis_type]\']').clone();
$geomType.attr('name', 'gis_data[' + noOfGeoms + '][gis_type]').val('POINT');
var html2 = '<br>' + Messages.strPoint + ' :' + '<label for="x"> ' + Messages.strX + ' </label>' + '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][x]" value="">' + '<label for="y"> ' + Messages.strY + ' </label>' + '<input type="text" name="gis_data[' + noOfGeoms + '][POINT][y]" value="">' + '<br><br>';
$a.before(html1);
$geomType.insertBefore($a);
$a.before(html2);
$noOfGeomsInput.val(noOfGeoms + 1);
});
});

View file

@ -1,134 +0,0 @@
const GitInfo = {
/**
* Version string to integer conversion.
* @param {string} str
* @return {number | false}
*/
parseVersionString: function (str) {
if (typeof str !== 'string') {
return false;
}
let add = 0;
// Parse possible alpha/beta/rc/
const state = str.split('-');
if (state.length >= 2) {
if (state[1].substr(0, 2) === 'rc') {
add = -20 - parseInt(state[1].substr(2), 10);
} else if (state[1].substr(0, 4) === 'beta') {
add = -40 - parseInt(state[1].substr(4), 10);
} else if (state[1].substr(0, 5) === 'alpha') {
add = -60 - parseInt(state[1].substr(5), 10);
} else if (state[1].substr(0, 3) === 'dev') {
/* We don't handle dev, it's git snapshot */
add = 0;
}
}
// Parse version
const x = str.split('.');
// Use 0 for non existing parts
const maj = parseInt(x[0], 10) || 0;
const min = parseInt(x[1], 10) || 0;
const pat = parseInt(x[2], 10) || 0;
const hotfix = parseInt(x[3], 10) || 0;
return maj * 100000000 + min * 1000000 + pat * 10000 + hotfix * 100 + add;
},
/**
* Indicates current available version on main page.
* @param {object} data
*/
currentVersion: function (data) {
if (data && data.version && data.date) {
const current = GitInfo.parseVersionString($('span.version').text());
const latest = GitInfo.parseVersionString(data.version);
const url = './url.php?url=https://www.phpmyadmin.net/files/' + Functions.escapeHtml(encodeURIComponent(data.version)) + '/';
let versionInformationMessage = document.createElement('span');
versionInformationMessage.className = 'latest';
const versionInformationMessageLink = document.createElement('a');
versionInformationMessageLink.href = url;
versionInformationMessageLink.className = 'disableAjax';
versionInformationMessageLink.target = '_blank';
versionInformationMessageLink.rel = 'noopener noreferrer';
const versionInformationMessageLinkText = document.createTextNode(data.version);
versionInformationMessageLink.appendChild(versionInformationMessageLinkText);
const prefixMessage = document.createTextNode(Messages.strLatestAvailable + ' ');
versionInformationMessage.appendChild(prefixMessage);
versionInformationMessage.appendChild(versionInformationMessageLink);
if (latest > current) {
const message = Functions.sprintf(Messages.strNewerVersion, Functions.escapeHtml(data.version), Functions.escapeHtml(data.date));
let htmlClass = 'alert alert-primary';
if (Math.floor(latest / 10000) === Math.floor(current / 10000)) {
/* Security update */
htmlClass = 'alert alert-danger';
}
$('#newer_version_notice').remove();
const mainContainerDiv = document.createElement('div');
mainContainerDiv.id = 'newer_version_notice';
mainContainerDiv.className = htmlClass;
const mainContainerDivLink = document.createElement('a');
mainContainerDivLink.href = url;
mainContainerDivLink.className = 'disableAjax';
mainContainerDivLink.target = '_blank';
mainContainerDivLink.rel = 'noopener noreferrer';
const mainContainerDivLinkText = document.createTextNode(message);
mainContainerDivLink.appendChild(mainContainerDivLinkText);
mainContainerDiv.appendChild(mainContainerDivLink);
$('#maincontainer').append($(mainContainerDiv));
}
if (latest === current) {
versionInformationMessage = document.createTextNode(' (' + Messages.strUpToDate + ')');
}
/* Remove extra whitespace */
const versionInfo = $('#li_pma_version').contents().get(2);
if (typeof versionInfo !== 'undefined') {
versionInfo.textContent = versionInfo.textContent.trim();
}
const $liPmaVersion = $('#li_pma_version');
$liPmaVersion.find('span.latest').remove();
$liPmaVersion.append($(versionInformationMessage));
}
},
/**
* Loads Git revision data from ajax for index.php
*/
displayGitRevision: function () {
$('#is_git_revision').remove();
$('#li_pma_version_git').remove();
$.get('index.php?route=/git-revision', {
'server': CommonParams.get('server'),
'ajax_request': true,
'no_debug': true
}, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$(data.message).insertAfter('#li_pma_version');
}
});
}
};
AJAX.registerTeardown('home.js', function () {
$('#themesModal').off('show.bs.modal');
});
AJAX.registerOnload('home.js', function () {
$('#themesModal').on('show.bs.modal', function () {
$.get('index.php?route=/themes', function (data) {
$('#themesModal .modal-body').html(data.themes);
});
});
/**
* Load version information asynchronously.
*/
if ($('li.jsversioncheck').length > 0) {
$.ajax({
dataType: 'json',
url: 'index.php?route=/version-check',
method: 'POST',
data: {
'server': CommonParams.get('server')
},
success: GitInfo.currentVersion
});
}
if ($('#is_git_revision').length > 0) {
setTimeout(GitInfo.displayGitRevision, 10);
}
});

View file

@ -1,144 +0,0 @@
/**
* Functions used in the import tab
*
*/
/**
* Toggles the hiding and showing of each plugin's options
* according to the currently selected plugin from the dropdown list
*/
function changePluginOpts() {
$('#format_specific_opts').find('div.format_specific_options').each(function () {
$(this).hide();
});
var selectedPluginName = $('#plugins').find('option:selected').val();
$('#' + selectedPluginName + '_options').fadeIn('slow');
const importNotification = document.getElementById('import_notification');
importNotification.innerText = '';
if (selectedPluginName === 'csv') {
importNotification.innerHTML = '<div class="alert alert-info mb-0 mt-3" role="alert">' + Messages.strImportCSV + '</div>';
}
}
/**
* Toggles the hiding and showing of each plugin's options and sets the selected value
* in the plugin dropdown list according to the format of the selected file
*
* @param {string} fname
*/
function matchFile(fname) {
var fnameArray = fname.toLowerCase().split('.');
var len = fnameArray.length;
if (len !== 0) {
var extension = fnameArray[len - 1];
if (extension === 'gz' || extension === 'bz2' || extension === 'zip') {
len--;
}
// Only toggle if the format of the file can be imported
if ($('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).length === 1) {
$('select[name=\'format\'] option').filterByValue(fnameArray[len - 1]).prop('selected', true);
changePluginOpts();
}
}
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('import.js', function () {
$('#plugins').off('change');
$('#input_import_file').off('change');
$('#select_local_import_file').off('change');
$('#input_import_file').off('change').off('focus');
$('#select_local_import_file').off('focus');
$('#text_csv_enclosed').add('#text_csv_escaped').off('keyup');
});
AJAX.registerOnload('import.js', function () {
// import_file_form validation.
$(document).on('submit', '#import_file_form', function () {
var radioLocalImport = $('#localFileTab');
var radioImport = $('#uploadFileTab');
var fileMsg = '<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error"> ' + Messages.strImportDialogMessage + '</div>';
var wrongTblNameMsg = '<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error">' + Messages.strTableNameDialogMessage + '</div>';
var wrongDBNameMsg = '<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error">' + Messages.strDBNameDialogMessage + '</div>';
if (radioLocalImport.length !== 0) {
// remote upload.
if (radioImport.hasClass('active') && $('#input_import_file').val() === '') {
$('#input_import_file').trigger('focus');
Functions.ajaxShowMessage(fileMsg, false);
return false;
}
if (radioLocalImport.hasClass('active')) {
if ($('#select_local_import_file').length === 0) {
Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title="" alt="" class="icon ic_s_error"> ' + Messages.strNoImportFile + ' </div>', false);
return false;
}
if ($('#select_local_import_file').val() === '') {
$('#select_local_import_file').trigger('focus');
Functions.ajaxShowMessage(fileMsg, false);
return false;
}
}
} else {
// local upload.
if ($('#input_import_file').val() === '') {
$('#input_import_file').trigger('focus');
Functions.ajaxShowMessage(fileMsg, false);
return false;
}
if ($('#text_csv_new_tbl_name').length > 0) {
var newTblName = $('#text_csv_new_tbl_name').val();
if (newTblName.length > 0 && newTblName.trim().length === 0) {
Functions.ajaxShowMessage(wrongTblNameMsg, false);
return false;
}
}
if ($('#text_csv_new_db_name').length > 0) {
var newDBName = $('#text_csv_new_db_name').val();
if (newDBName.length > 0 && newDBName.trim().length === 0) {
Functions.ajaxShowMessage(wrongDBNameMsg, false);
return false;
}
}
}
// show progress bar.
$('#upload_form_status').css('display', 'inline');
$('#upload_form_status_info').css('display', 'inline');
});
// Initially display the options for the selected plugin
changePluginOpts();
// Whenever the selected plugin changes, change the options displayed
$('#plugins').on('change', function () {
changePluginOpts();
});
$('#input_import_file').on('change', function () {
matchFile($(this).val());
});
$('#select_local_import_file').on('change', function () {
matchFile($(this).val());
});
/**
* Set up the interface for Javascript-enabled browsers since the default is for
* Javascript-disabled browsers
*/
$('#format_specific_opts').find('div.format_specific_options').find('h3').remove();
// $("form[name=import] *").unwrap();
/**
* for input element text_csv_enclosed and text_csv_escaped allow just one character to enter.
* as mysql allows just one character for these fields,
* if first character is escape then allow two including escape character.
*/
$('#text_csv_enclosed').add('#text_csv_escaped').on('keyup', function () {
if ($(this).val().length === 2 && $(this).val().charAt(0) !== '\\') {
$(this).val($(this).val().substring(0, 1));
return false;
}
return true;
});
});

View file

@ -1,743 +0,0 @@
/**
* @fileoverview function used for index manipulation pages
* @name Table Structure
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
/* global fulltextIndexes:writable, indexes:writable, primaryIndexes:writable, spatialIndexes:writable, uniqueIndexes:writable */ // js/functions.js
var Indexes = {};
/**
* Returns the array of indexes based on the index choice
*
* @param {string} indexChoice index choice
*
* @return {null|object}
*/
Indexes.getIndexArray = function (indexChoice) {
var sourceArray = null;
switch (indexChoice.toLowerCase()) {
case 'primary':
sourceArray = primaryIndexes;
break;
case 'unique':
sourceArray = uniqueIndexes;
break;
case 'index':
sourceArray = indexes;
break;
case 'fulltext':
sourceArray = fulltextIndexes;
break;
case 'spatial':
sourceArray = spatialIndexes;
break;
default:
return null;
}
return sourceArray;
};
/**
* Hides/shows the inputs and submits appropriately depending
* on whether the index type chosen is 'SPATIAL' or not.
*/
Indexes.checkIndexType = function () {
/**
* @var {JQuery<HTMLElement}, Dropdown to select the index choice.
*/
var $selectIndexChoice = $('#select_index_choice');
/**
* @var {JQuery<HTMLElement}, Dropdown to select the index type.
*/
var $selectIndexType = $('#select_index_type');
/**
* @var {JQuery<HTMLElement}, Table header for the size column.
*/
var $sizeHeader = $('#index_columns').find('thead tr').children('th').eq(1);
/**
* @var {JQuery<HTMLElement}, Inputs to specify the columns for the index.
*/
var $columnInputs = $('select[name="index[columns][names][]"]');
/**
* @var {JQuery<HTMLElement}, Inputs to specify sizes for columns of the index.
*/
var $sizeInputs = $('input[name="index[columns][sub_parts][]"]');
/**
* @var {JQuery<HTMLElement}, Footer containing the controllers to add more columns
*/
var $addMore = $('#index_frm').find('.add_more');
if ($selectIndexChoice.val() === 'SPATIAL') {
// Disable and hide the size column
$sizeHeader.hide();
$sizeInputs.each(function () {
$(this).prop('disabled', true).parent('td').hide();
});
// Disable and hide the columns of the index other than the first one
var initial = true;
$columnInputs.each(function () {
var $columnInput = $(this);
if (!initial) {
$columnInput.prop('disabled', true).parent('td').hide();
} else {
initial = false;
}
});
// Hide controllers to add more columns
$addMore.hide();
} else {
// Enable and show the size column
$sizeHeader.show();
$sizeInputs.each(function () {
$(this).prop('disabled', false).parent('td').show();
});
// Enable and show the columns of the index
$columnInputs.each(function () {
$(this).prop('disabled', false).parent('td').show();
});
// Show controllers to add more columns
$addMore.show();
}
if ($selectIndexChoice.val() === 'SPATIAL' || $selectIndexChoice.val() === 'FULLTEXT') {
$selectIndexType.val('').prop('disabled', true);
} else {
$selectIndexType.prop('disabled', false);
}
};
/**
* Sets current index information into form parameters.
*
* @param {any[]} sourceArray Array containing index columns
* @param {string} indexChoice Choice of index
*
* @return {void}
*/
Indexes.setIndexFormParameters = function (sourceArray, indexChoice) {
if (indexChoice === 'index') {
$('input[name="indexes"]').val(JSON.stringify(sourceArray));
} else {
$('input[name="' + indexChoice + '_indexes"]').val(JSON.stringify(sourceArray));
}
};
/**
* Removes a column from an Index.
*
* @param {string} colIndex Index of column in form
*
* @return {void}
*/
Indexes.removeColumnFromIndex = function (colIndex) {
// Get previous index details.
var previousIndex = $('select[name="field_key[' + colIndex + ']"]').attr('data-index');
if (previousIndex.length) {
previousIndex = previousIndex.split(',');
var sourceArray = Indexes.getIndexArray(previousIndex[0]);
if (sourceArray === null) {
return;
}
// Remove column from index array.
var sourceLength = sourceArray[previousIndex[1]].columns.length;
for (var i = 0; i < sourceLength; i++) {
if (sourceArray[previousIndex[1]].columns[i].col_index === colIndex) {
sourceArray[previousIndex[1]].columns.splice(i, 1);
}
}
// Remove index completely if no columns left.
if (sourceArray[previousIndex[1]].columns.length === 0) {
sourceArray.splice(previousIndex[1], 1);
}
// Update current index details.
$('select[name="field_key[' + colIndex + ']"]').attr('data-index', '');
// Update form index parameters.
Indexes.setIndexFormParameters(sourceArray, previousIndex[0].toLowerCase());
}
};
/**
* Adds a column to an Index.
*
* @param {any[]} sourceArray Array holding corresponding indexes
* @param {string} arrayIndex Index of an INDEX in array
* @param {string} indexChoice Choice of Index
* @param {string} colIndex Index of column on form
*
* @return {void}
*/
Indexes.addColumnToIndex = function (sourceArray, arrayIndex, indexChoice, colIndex) {
if (colIndex >= 0) {
// Remove column from other indexes (if any).
Indexes.removeColumnFromIndex(colIndex);
}
var indexName = $('input[name="index[Key_name]"]').val();
var indexComment = $('input[name="index[Index_comment]"]').val();
var keyBlockSize = $('input[name="index[Key_block_size]"]').val();
var parser = $('input[name="index[Parser]"]').val();
var indexType = $('select[name="index[Index_type]"]').val();
var columns = [];
$('#index_columns').find('tbody').find('tr').each(function () {
// Get columns in particular order.
var colIndex = $(this).find('select[name="index[columns][names][]"]').val();
var size = $(this).find('input[name="index[columns][sub_parts][]"]').val();
columns.push({
'col_index': colIndex,
'size': size
});
});
// Update or create an index.
sourceArray[arrayIndex] = {
'Key_name': indexName,
'Index_comment': indexComment,
'Index_choice': indexChoice.toUpperCase(),
'Key_block_size': keyBlockSize,
'Parser': parser,
'Index_type': indexType,
'columns': columns
};
// Display index name (or column list)
var displayName = indexName;
if (displayName === '') {
var columnNames = [];
$.each(columns, function () {
columnNames.push($('input[name="field_name[' + this.col_index + ']"]').val());
});
displayName = '[' + columnNames.join(', ') + ']';
}
$.each(columns, function () {
var id = 'index_name_' + this.col_index + '_8';
var $name = $('#' + id);
if ($name.length === 0) {
$name = $('<a id="' + id + '" href="#" class="ajax show_index_dialog"></a>');
$name.insertAfter($('select[name="field_key[' + this.col_index + ']"]'));
}
var $text = $('<small>').text(displayName);
$name.html($text);
});
if (colIndex >= 0) {
// Update index details on form.
$('select[name="field_key[' + colIndex + ']"]').attr('data-index', indexChoice + ',' + arrayIndex);
}
Indexes.setIndexFormParameters(sourceArray, indexChoice.toLowerCase());
};
/**
* Get choices list for a column to create a composite index with.
*
* @param {any[]} sourceArray Array hodling columns for particular index
* @param {string} colIndex Choice of index
*
* @return {JQuery} jQuery Object
*/
Indexes.getCompositeIndexList = function (sourceArray, colIndex) {
// Remove any previous list.
if ($('#composite_index_list').length) {
$('#composite_index_list').remove();
}
// Html list.
var $compositeIndexList = $('<ul id="composite_index_list">' + '<div>' + Messages.strCompositeWith + '</div>' + '</ul>');
// Add each column to list available for composite index.
var sourceLength = sourceArray.length;
var alreadyPresent = false;
for (var i = 0; i < sourceLength; i++) {
var subArrayLen = sourceArray[i].columns.length;
var columnNames = [];
for (var j = 0; j < subArrayLen; j++) {
columnNames.push($('input[name="field_name[' + sourceArray[i].columns[j].col_index + ']"]').val());
if (colIndex === sourceArray[i].columns[j].col_index) {
alreadyPresent = true;
}
}
$compositeIndexList.append('<li>' + '<input type="radio" name="composite_with" ' + (alreadyPresent ? 'checked="checked"' : '') + ' id="composite_index_' + i + '" value="' + i + '">' + '<label for="composite_index_' + i + '">' + columnNames.join(', ') + '</label>' + '</li>');
}
return $compositeIndexList;
};
/**
* Shows 'Add Index' dialog.
*
* @param {any[]} sourceArray Array holding particular index
* @param {string} arrayIndex Index of an INDEX in array
* @param {any[]} targetColumns Columns for an INDEX
* @param {string} colIndex Index of column on form
* @param {object} index Index detail object
* @param {boolean} showDialog Whether to show index creation dialog or not
*
* @return {void}
*/
Indexes.showAddIndexDialog = function (sourceArray, arrayIndex, targetColumns, colIndex, index, showDialog) {
var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true;
// Prepare post-data.
var $table = $('input[name="table"]');
var table = $table.length > 0 ? $table.val() : '';
var postData = {
'server': CommonParams.get('server'),
'db': $('input[name="db"]').val(),
'table': table,
'ajax_request': 1,
'create_edit_table': 1,
'index': index
};
var columns = {};
for (var i = 0; i < targetColumns.length; i++) {
var columnName = $('input[name="field_name[' + targetColumns[i] + ']"]').val();
var columnType = $('select[name="field_type[' + targetColumns[i] + ']"]').val().toLowerCase();
columns[columnName] = [columnType, targetColumns[i]];
}
postData.columns = JSON.stringify(columns);
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary'
},
[Messages.strCancel]: {
text: Messages.strCancel,
class: 'btn btn-secondary'
}
};
buttonOptions[Messages.strGo].click = function () {
var isMissingValue = false;
$('select[name="index[columns][names][]"]').each(function () {
if ($(this).val() === '') {
isMissingValue = true;
}
});
if (!isMissingValue) {
Indexes.addColumnToIndex(sourceArray, arrayIndex, index.Index_choice, colIndex);
} else {
Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title="" alt=""' + ' class="icon ic_s_error"> ' + Messages.strMissingColumn + ' </div>', false);
return false;
}
$(this).remove();
};
buttonOptions[Messages.strCancel].click = function () {
if (colIndex >= 0) {
// Handle state on 'Cancel'.
var $selectList = $('select[name="field_key[' + colIndex + ']"]');
if (!$selectList.attr('data-index').length) {
$selectList.find('option[value*="none"]').attr('selected', 'selected');
} else {
var previousIndex = $selectList.attr('data-index').split(',');
$selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]').attr('selected', 'selected');
}
}
$(this).dialog('close');
};
var $msgbox = Functions.ajaxShowMessage();
$.post('index.php?route=/table/indexes', postData, function (data) {
if (data.success === false) {
// in the case of an error, show the error message returned.
Functions.ajaxShowMessage(data.error, false);
} else {
Functions.ajaxRemoveMessage($msgbox);
var $div = $('<div></div>');
if (showDialogLocal) {
// Show dialog if the request was successful
if ($('#addIndex').length > 0) {
$('#addIndex').remove();
}
$div.append(data.message).dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
title: Messages.strAddIndex,
width: 450,
minHeight: 250,
create: function () {
$(this).on('keypress', function (e) {
if (e.which === 13 || e.keyCode === 13 || window.event.keyCode === 13) {
e.preventDefault();
buttonOptions[Messages.strGo]();
$(this).remove();
}
});
},
open: function () {
Functions.checkIndexName('index_frm');
Functions.showHints($div);
$('#index_columns').find('td').each(function () {
$(this).css('width', $(this).width() + 'px');
});
$('#index_columns').find('tbody').sortable({
axis: 'y',
containment: $('#index_columns').find('tbody'),
tolerance: 'pointer'
});
},
modal: true,
buttons: buttonOptions,
close: function () {
$(this).remove();
}
});
} else {
$div.append(data.message);
$div.css({
'display': 'none'
});
$div.appendTo($('body'));
$div.attr({
'id': 'addIndex'
});
var isMissingValue = false;
$('select[name="index[columns][names][]"]').each(function () {
if ($(this).val() === '') {
isMissingValue = true;
}
});
if (!isMissingValue) {
Indexes.addColumnToIndex(sourceArray, arrayIndex, index.Index_choice, colIndex);
} else {
Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title="" alt=""' + ' class="icon ic_s_error"> ' + Messages.strMissingColumn + ' </div>', false);
return false;
}
}
}
});
};
/**
* Creates a advanced index type selection dialog.
*
* @param {any[]} sourceArray Array holding a particular type of indexes
* @param {string} indexChoice Choice of index
* @param {string} colIndex Index of new column on form
*
* @return {void}
*/
Indexes.indexTypeSelectionDialog = function (sourceArray, indexChoice, colIndex) {
var $singleColumnRadio = $('<input type="radio" id="single_column" name="index_choice"' + ' checked="checked">' + '<label for="single_column">' + Messages.strCreateSingleColumnIndex + '</label>');
var $compositeIndexRadio = $('<input type="radio" id="composite_index"' + ' name="index_choice">' + '<label for="composite_index">' + Messages.strCreateCompositeIndex + '</label>');
var $dialogContent = $('<fieldset class="pma-fieldset" id="advance_index_creator"></fieldset>');
$dialogContent.append('<legend>' + indexChoice.toUpperCase() + '</legend>');
// For UNIQUE/INDEX type, show choice for single-column and composite index.
$dialogContent.append($singleColumnRadio);
$dialogContent.append($compositeIndexRadio);
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary'
},
[Messages.strCancel]: {
text: Messages.strCancel,
class: 'btn btn-secondary'
}
};
// 'OK' operation.
buttonOptions[Messages.strGo].click = function () {
if ($('#single_column').is(':checked')) {
var index = {
'Key_name': indexChoice === 'primary' ? 'PRIMARY' : '',
'Index_choice': indexChoice.toUpperCase()
};
Indexes.showAddIndexDialog(sourceArray, sourceArray.length, [colIndex], colIndex, index);
}
if ($('#composite_index').is(':checked')) {
if ($('input[name="composite_with"]').length !== 0 && $('input[name="composite_with"]:checked').length === 0) {
Functions.ajaxShowMessage('<div class="alert alert-danger" role="alert"><img src="themes/dot.gif" title=""' + ' alt="" class="icon ic_s_error"> ' + Messages.strFormEmpty + ' </div>', false);
return false;
}
var arrayIndex = $('input[name="composite_with"]:checked').val();
var sourceLength = sourceArray[arrayIndex].columns.length;
var targetColumns = [];
for (var i = 0; i < sourceLength; i++) {
targetColumns.push(sourceArray[arrayIndex].columns[i].col_index);
}
targetColumns.push(colIndex);
Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex, sourceArray[arrayIndex]);
}
$(this).remove();
};
buttonOptions[Messages.strCancel].click = function () {
// Handle state on 'Cancel'.
var $selectList = $('select[name="field_key[' + colIndex + ']"]');
if (!$selectList.attr('data-index').length) {
$selectList.find('option[value*="none"]').attr('selected', 'selected');
} else {
var previousIndex = $selectList.attr('data-index').split(',');
$selectList.find('option[value*="' + previousIndex[0].toLowerCase() + '"]').attr('selected', 'selected');
}
$(this).remove();
};
$('<div></div>').append($dialogContent).dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
minWidth: 525,
minHeight: 200,
modal: true,
title: Messages.strAddIndex,
resizable: false,
buttons: buttonOptions,
open: function () {
$('#composite_index').on('change', function () {
if ($(this).is(':checked')) {
$dialogContent.append(Indexes.getCompositeIndexList(sourceArray, colIndex));
}
});
$('#single_column').on('change', function () {
if ($(this).is(':checked')) {
if ($('#composite_index_list').length) {
$('#composite_index_list').remove();
}
}
});
},
close: function () {
$('#composite_index').off('change');
$('#single_column').off('change');
$(this).remove();
}
});
};
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('indexes.js', function () {
$(document).off('click', '#save_index_frm');
$(document).off('click', '#preview_index_frm');
$(document).off('change', '#select_index_choice');
$(document).off('click', 'a.drop_primary_key_index_anchor.ajax');
$(document).off('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax');
$(document).off('click', '#table_index tbody tr td.rename_index.ajax');
$(document).off('click', '#index_frm input[type=submit]');
$('body').off('change', 'select[name*="field_key"]');
$(document).off('click', '.show_index_dialog');
});
/**
* @description <p>Ajax scripts for table index page</p>
*
* Actions ajaxified here:
* <ul>
* <li>Showing/hiding inputs depending on the index type chosen</li>
* <li>create/edit/drop indexes</li>
* </ul>
*/
AJAX.registerOnload('indexes.js', function () {
// Re-initialize variables.
primaryIndexes = [];
uniqueIndexes = [];
indexes = [];
fulltextIndexes = [];
spatialIndexes = [];
// for table creation form
var $engineSelector = $('.create_table_form select[name=tbl_storage_engine]');
if ($engineSelector.length) {
Functions.hideShowConnection($engineSelector);
}
var $form = $('#index_frm');
if ($form.length > 0) {
Functions.showIndexEditDialog($form);
}
$(document).on('click', '#save_index_frm', function (event) {
event.preventDefault();
var $form = $('#index_frm');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'do_save_data=1' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
Functions.ajaxShowMessage(Messages.strProcessingRequest);
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
});
$(document).on('click', '#preview_index_frm', function (event) {
event.preventDefault();
Functions.previewSql($('#index_frm'));
});
$(document).on('change', '#select_index_choice', function (event) {
event.preventDefault();
Indexes.checkIndexType();
Functions.checkIndexName('index_frm');
});
/**
* Ajax Event handler for 'Drop Index'
*/
$(document).on('click', 'a.drop_primary_key_index_anchor.ajax', function (event) {
event.preventDefault();
var $anchor = $(this);
/**
* @var $currRow Object containing reference to the current field's row
*/
var $currRow = $anchor.parents('tr');
/** @var {number} rows Number of columns in the key */
var rows = $anchor.parents('td').attr('rowspan') || 1;
/** @var {number} $rowsToHide Rows that should be hidden */
var $rowsToHide = $currRow;
for (var i = 1, $lastRow = $currRow.next(); i < rows; i++, $lastRow = $lastRow.next()) {
$rowsToHide = $rowsToHide.add($lastRow);
}
var question = $currRow.children('td').children('.drop_primary_key_index_msg').val();
Functions.confirmPreviewSql(question, $anchor.attr('href'), function (url) {
var $msg = Functions.ajaxShowMessage(Messages.strDroppingPrimaryKeyIndex, false);
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxRemoveMessage($msg);
var $tableRef = $rowsToHide.closest('table');
if ($rowsToHide.length === $tableRef.find('tbody > tr').length) {
// We are about to remove all rows from the table
$tableRef.hide('medium', function () {
$('div.no_indexes_defined').show('medium');
$rowsToHide.remove();
});
$tableRef.siblings('.alert-primary').hide('medium');
} else {
// We are removing some of the rows only
$rowsToHide.hide('medium', function () {
$(this).remove();
});
}
if ($('.result_query').length) {
$('.result_query').remove();
}
if (data.sql_query) {
$('<div class="result_query"></div>').html(data.sql_query).prependTo('#structure_content');
Functions.highlightSql($('#page_content'));
}
Navigation.reload();
CommonActions.refreshMain('index.php?route=/table/structure');
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
});
}); // end Drop Primary Key/Index
/**
* Ajax event handler for index edit
**/
$(document).on('click', '#table_index tbody tr td.edit_index.ajax, #index_div .add_index.ajax', function (event) {
event.preventDefault();
var url;
var title;
if ($(this).find('a').length === 0) {
// Add index
var valid = Functions.checkFormElementInRange($(this).closest('form')[0], 'added_fields', 'Column count has to be larger than zero.');
if (!valid) {
return;
}
url = $(this).closest('form').serialize();
title = Messages.strAddIndex;
} else {
// Edit index
url = $(this).find('a').getPostData();
title = Messages.strEditIndex;
}
url += CommonParams.get('arg_separator') + 'ajax_request=true';
Functions.indexEditorDialog(url, title, function (data) {
CommonParams.set('db', data.params.db);
CommonParams.set('table', data.params.table);
CommonActions.refreshMain('index.php?route=/table/structure');
});
});
/**
* Ajax event handler for index rename
**/
$(document).on('click', '#table_index tbody tr td.rename_index.ajax', function (event) {
event.preventDefault();
var url = $(this).find('a').getPostData();
var title = Messages.strRenameIndex;
url += CommonParams.get('arg_separator') + 'ajax_request=true';
Functions.indexRenameDialog(url, title, function (data) {
CommonParams.set('db', data.params.db);
CommonParams.set('table', data.params.table);
CommonActions.refreshMain('index.php?route=/table/structure');
});
});
/**
* Ajax event handler for advanced index creation during table creation
* and column addition.
*/
$('body').on('change', 'select[name*="field_key"]', function (e, showDialog) {
var showDialogLocal = typeof showDialog !== 'undefined' ? showDialog : true;
// Index of column on Table edit and create page.
var colIndex = /\d+/.exec($(this).attr('name'));
colIndex = colIndex[0];
// Choice of selected index.
var indexChoice = /[a-z]+/.exec($(this).val());
indexChoice = indexChoice[0];
// Array containing corresponding indexes.
var sourceArray = null;
if (indexChoice === 'none') {
Indexes.removeColumnFromIndex(colIndex);
var id = 'index_name_' + '0' + '_8';
var $name = $('#' + id);
if ($name.length === 0) {
$name = $('<a id="' + id + '" href="#" class="ajax show_index_dialog"></a>');
$name.insertAfter($('select[name="field_key[' + '0' + ']"]'));
}
$name.html('');
return false;
}
// Select a source array.
sourceArray = Indexes.getIndexArray(indexChoice);
if (sourceArray === null) {
return;
}
if (sourceArray.length === 0) {
var index = {
'Key_name': indexChoice === 'primary' ? 'PRIMARY' : '',
'Index_choice': indexChoice.toUpperCase()
};
Indexes.showAddIndexDialog(sourceArray, 0, [colIndex], colIndex, index, showDialogLocal);
} else {
if (indexChoice === 'primary') {
var arrayIndex = 0;
var sourceLength = sourceArray[arrayIndex].columns.length;
var targetColumns = [];
for (var i = 0; i < sourceLength; i++) {
targetColumns.push(sourceArray[arrayIndex].columns[i].col_index);
}
targetColumns.push(colIndex);
Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, colIndex, sourceArray[arrayIndex], showDialogLocal);
} else {
// If there are multiple columns selected for an index, show advanced dialog.
Indexes.indexTypeSelectionDialog(sourceArray, indexChoice, colIndex);
}
}
});
$(document).on('click', '.show_index_dialog', function (e) {
e.preventDefault();
// Get index details.
var previousIndex = $(this).prev('select').attr('data-index').split(',');
var indexChoice = previousIndex[0];
var arrayIndex = previousIndex[1];
var sourceArray = Indexes.getIndexArray(indexChoice);
if (sourceArray !== null) {
var sourceLength = sourceArray[arrayIndex].columns.length;
var targetColumns = [];
for (var i = 0; i < sourceLength; i++) {
targetColumns.push(sourceArray[arrayIndex].columns[i].col_index);
}
Indexes.showAddIndexDialog(sourceArray, arrayIndex, targetColumns, -1, sourceArray[arrayIndex]);
}
});
$('#index_frm').on('submit', function () {
if (typeof this.elements['index[Key_name]'].disabled !== 'undefined') {
this.elements['index[Key_name]'].disabled = false;
}
});
});

View file

@ -1,43 +0,0 @@
/**
* jqplot formatter for byte values
*
* @package phpMyAdmin
*/
(function ($) {
'use strict';
var formatByte = function (value, index) {
var val = value;
var i = index;
var units = [Messages.strB, Messages.strKiB, Messages.strMiB, Messages.strGiB, Messages.strTiB, Messages.strPiB, Messages.strEiB];
while (val >= 1024 && i <= 6) {
val /= 1024;
i++;
}
var format = '%.1f';
if (Math.floor(val) === val) {
format = '%.0f';
}
return $.jqplot.sprintf(format + ' ' + units[i], val);
};
/**
* The index indicates what unit the incoming data will be in.
* 0 for bytes, 1 for kilobytes and so on...
*
* @param index
*
* @return {String}
*/
$.jqplot.byteFormatter = function (index) {
var i = index || 0;
return function (format, value) {
var val = value;
if (typeof val === 'number') {
val = parseFloat(val) || 0;
return formatByte(val, i);
} else {
return String(val);
}
};
};
})(jQuery);

View file

@ -1,271 +0,0 @@
/**
* This file is internal to phpMyAdmin.
* @license see the main phpMyAdmin license.
*
* @fileoverview A jquery plugin that allows drag&drop sorting in tables.
* Coded because JQuery UI sortable doesn't support tables. Also it has no animation
*
* @name Sortable Table JQuery plugin
*
* @requires jQuery
*/
/**
* Options:
*
* $('table').sortableTable({
* ignoreRect: { top, left, width, height } - Relative coordinates on each element. If the user clicks
* in this area, it is not seen as a drag&drop request. Useful for toolbars etc.
* events: {
* start: callback function when the user starts dragging
* drop: callback function after an element has been dropped
* }
* })
*/
/**
* Commands:
*
* $('table').sortableTable('init') - equivalent to $('table').sortableTable()
* $('table').sortableTable('refresh') - if the table has been changed, refresh correctly assigns all events again
* $('table').sortableTable('destroy') - removes all events from the table
*/
/**
* Setup:
*
* Can be applied on any table, there is just one convention.
* Each cell (<td>) has to contain one and only one element (preferably div or span)
* which is the actually draggable element.
*/
(function ($) {
jQuery.fn.sortableTable = function (method) {
var methods = {
init: function (options) {
var tb = new SortableTableInstance(this, options);
tb.init();
$(this).data('sortableTable', tb);
},
refresh: function () {
$(this).data('sortableTable').refresh();
},
destroy: function () {
$(this).data('sortableTable').destroy();
}
};
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.sortableTable');
}
function SortableTableInstance(table) {
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var down = false;
var $draggedEl;
var oldCell;
var previewMove;
var id;
/* Mouse handlers on the child elements */
var onMouseUp = function (e) {
dropAt(e.pageX, e.pageY);
};
var onMouseDown = function (e) {
$draggedEl = $(this).children();
if ($draggedEl.length === 0) {
return;
}
if (options.ignoreRect && insideRect({
x: e.pageX - $draggedEl.offset().left,
y: e.pageY - $draggedEl.offset().top
}, options.ignoreRect)) {
return;
}
down = true;
oldCell = this;
if (options.events && options.events.start) {
options.events.start(this);
}
return false;
};
var globalMouseMove = function (e) {
if (down) {
move(e.pageX, e.pageY);
if (inside($(oldCell), e.pageX, e.pageY)) {
if (previewMove !== null) {
moveTo(previewMove);
previewMove = null;
}
} else {
$(table).find('td').each(function () {
if (inside($(this), e.pageX, e.pageY)) {
if ($(previewMove).attr('class') !== $(this).children().first().attr('class')) {
if (previewMove !== null) {
moveTo(previewMove);
}
previewMove = $(this).children().first();
if (previewMove.length > 0) {
moveTo($(previewMove), {
pos: {
top: $(oldCell).offset().top - $(previewMove).parent().offset().top,
left: $(oldCell).offset().left - $(previewMove).parent().offset().left
}
});
}
}
return false;
}
});
}
}
return false;
};
var globalMouseOut = function () {
if (down) {
down = false;
if (previewMove) {
moveTo(previewMove);
}
moveTo($draggedEl);
previewMove = null;
}
};
// Initialize sortable table
this.init = function () {
id = 1;
// Add some required css to each child element in the <td>s
$(table).find('td').children().each(function () {
// Remove any old occurrences of our added draggable-num class
$(this).attr('class', $(this).attr('class').replace(/\s*draggable-\d+/g, ''));
$(this).addClass('draggable-' + id++);
});
// Mouse events
$(table).find('td').on('mouseup', onMouseUp);
$(table).find('td').on('mousedown', onMouseDown);
$(document).on('mousemove', globalMouseMove);
$(document).on('mouseleave', globalMouseOut);
};
// Call this when the table has been updated
this.refresh = function () {
this.destroy();
this.init();
};
this.destroy = function () {
// Add some required css to each child element in the <td>s
$(table).find('td').children().each(function () {
// Remove any old occurrences of our added draggable-num class
$(this).attr('class', $(this).attr('class').replace(/\s*draggable-\d+/g, ''));
});
// Mouse events
$(table).find('td').off('mouseup', onMouseUp);
$(table).find('td').off('mousedown', onMouseDown);
$(document).off('mousemove', globalMouseMove);
$(document).off('mouseleave', globalMouseOut);
};
function switchElement(drag, dropTo) {
var dragPosDiff = {
left: $(drag).children().first().offset().left - $(dropTo).offset().left,
top: $(drag).children().first().offset().top - $(dropTo).offset().top
};
var dropPosDiff = null;
if ($(dropTo).children().length > 0) {
dropPosDiff = {
left: $(dropTo).children().first().offset().left - $(drag).offset().left,
top: $(dropTo).children().first().offset().top - $(drag).offset().top
};
}
/* I love you append(). It moves the DOM Elements so gracefully <3 */
// Put the element in the way to old place
$(drag).append($(dropTo).children().first()).children().stop(true, true).on('mouseup', onMouseUp);
if (dropPosDiff) {
$(drag).append($(dropTo).children().first()).children().css('left', dropPosDiff.left + 'px').css('top', dropPosDiff.top + 'px');
}
// Put our dragged element into the space we just freed up
$(dropTo).append($(drag).children().first()).children().on('mouseup', onMouseUp).css('left', dragPosDiff.left + 'px').css('top', dragPosDiff.top + 'px');
moveTo($(dropTo).children().first(), {
duration: 100
});
moveTo($(drag).children().first(), {
duration: 100
});
if (options.events && options.events.drop) {
// Drop event. The drag child element is moved into the drop element
// and vice versa. So the parameters are switched.
// Calculate row and column index
const colIdx = $(dropTo).prevAll().length;
const rowIdx = $(dropTo).parent().prevAll().length;
options.events.drop(drag, dropTo, {
col: colIdx,
row: rowIdx
});
}
}
function move(x, y) {
$draggedEl.offset({
top: Math.min($(document).height(), Math.max(0, y - $draggedEl.height() / 2)),
left: Math.min($(document).width(), Math.max(0, x - $draggedEl.width() / 2))
});
}
function inside($el, x, y) {
var off = $el.offset();
return y >= off.top && x >= off.left && x < off.left + $el.width() && y < off.top + $el.height();
}
function insideRect(pos, r) {
return pos.y > r.top && pos.x > r.left && pos.y < r.top + r.height && pos.x < r.left + r.width;
}
function dropAt(x, y) {
if (!down) {
return;
}
down = false;
var switched = false;
$(table).find('td').each(function () {
if ($(this).children().first().attr('class') !== $(oldCell).children().first().attr('class') && inside($(this), x, y)) {
switchElement(oldCell, this);
switched = true;
}
});
if (!switched) {
if (previewMove) {
moveTo(previewMove);
}
moveTo($draggedEl);
}
previewMove = null;
}
function moveTo(elem) {
let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (!opts.pos) {
opts.pos = {
left: 0,
top: 0
};
}
if (!opts.duration) {
opts.duration = 200;
}
$(elem).css('position', 'relative');
$(elem).animate({
top: opts.pos.top,
left: opts.pos.left
}, {
duration: opts.duration,
complete: function () {
if (opts.pos.left === 0 && opts.pos.top === 0) {
$(elem).css('position', '').css('left', '').css('top', '');
}
}
});
}
}
};
})(jQuery);

View file

@ -1,92 +0,0 @@
// global var that holds: 0- if ctrl key is not pressed 1- if ctrl key is pressed
var ctrlKeyHistory = 0;
/**
* Allows moving around inputs/select by Ctrl+arrows
*
* @param {object} event data
*/
function onKeyDownArrowsHandler(event) {
var e = event || window.event;
var o = e.srcElement || e.target;
if (!o) {
return;
}
if (o.tagName !== 'TEXTAREA' && o.tagName !== 'INPUT' && o.tagName !== 'SELECT') {
return;
}
if (e.which !== 17 && e.which !== 37 && e.which !== 38 && e.which !== 39 && e.which !== 40) {
return;
}
if (!o.id) {
return;
}
if (e.type === 'keyup') {
if (e.which === 17) {
ctrlKeyHistory = 0;
}
return;
} else if (e.type === 'keydown') {
if (e.which === 17) {
ctrlKeyHistory = 1;
}
}
if (ctrlKeyHistory !== 1) {
return;
}
e.preventDefault();
var pos = o.id.split('_');
if (pos[0] !== 'field' || typeof pos[2] === 'undefined') {
return;
}
var x = pos[2];
var y = pos[1];
switch (e.keyCode) {
case 38:
// up
y--;
break;
case 40:
// down
y++;
break;
case 37:
// left
x--;
break;
case 39:
// right
x++;
break;
default:
return;
}
var id = 'field_' + y + '_' + x;
var nO = document.getElementById(id);
if (!nO) {
id = 'field_' + y + '_' + x + '_0';
nO = document.getElementById(id);
}
// skip non existent fields
if (!nO) {
return;
}
nO.focus();
if (nO.tagName !== 'SELECT') {
nO.select();
}
e.returnValue = false;
}
AJAX.registerTeardown('keyhandler.js', function () {
$(document).off('keydown keyup', '#table_columns');
$(document).off('keydown keyup', 'table.insertRowTable');
});
AJAX.registerOnload('keyhandler.js', function () {
$(document).on('keydown keyup', '#table_columns', function (event) {
onKeyDownArrowsHandler(event.originalEvent);
});
$(document).on('keydown keyup', 'table.insertRowTable', function (event) {
onKeyDownArrowsHandler(event.originalEvent);
});
});

File diff suppressed because it is too large Load diff

View file

@ -1,191 +0,0 @@
/**
* Handles the resizing of a menu according to the available screen width
*
* Uses themes/original/css/resizable-menu.css.php
*
* To initialize:
* $('#myMenu').menuResizer(function () {
* // This function will be called to find out how much
* // available horizontal space there is for the menu
* return $('body').width() - 5; // Some extra margin for good measure
* });
*
* To trigger a resize operation:
* $('#myMenu').menuResizer('resize'); // Bind this to $(window).resize()
*
* To restore the menu to a state like before it was initialized:
* $('#myMenu').menuResizer('destroy');
*
* @package PhpMyAdmin
*/
(function ($) {
function MenuResizer($container, widthCalculator) {
var self = this;
self.$container = $container;
self.widthCalculator = widthCalculator;
var windowWidth = $(window).width();
if (windowWidth < 768) {
$('#pma_navigation_resizer').css({
'width': '0px'
});
}
// create submenu container
var link = $('<a></a>', {
'href': '#',
'class': 'nav-link dropdown-toggle',
'id': 'navbarDropdown',
'role': 'button',
'data-bs-toggle': 'dropdown',
'aria-haspopup': 'true',
'aria-expanded': 'false'
}).text(Messages.strMore);
var img = $container.find('li img');
if (img.length) {
$(Functions.getImage('b_more').toString()).prependTo(link);
}
var $submenu = $('<li></li>', {
'class': 'nav-item dropdown d-none'
}).append(link).append($('<ul></ul>', {
'class': 'dropdown-menu dropdown-menu-end',
'aria-labelledby': 'navbarDropdown'
}));
$container.append($submenu);
setTimeout(function () {
self.resize();
}, 4);
}
MenuResizer.prototype.resize = function () {
var wmax = this.widthCalculator.call(this.$container);
var windowWidth = $(window).width();
var $submenu = this.$container.find('.nav-item.dropdown').last();
var submenuW = $submenu.outerWidth(true);
var $submenuUl = $submenu.find('.dropdown-menu');
var $li = this.$container.find('> li');
var $li2 = $submenuUl.find('.dropdown-item');
var moreShown = $li2.length > 0;
// Calculate the total width used by all the shown tabs
var totalLen = moreShown ? submenuW : 0;
var l = $li.length - 1;
var i;
for (i = 0; i < l; i++) {
totalLen += $($li[i]).outerWidth(true);
}
// eslint-disable-next-line compat/compat
var hasVScroll = document.body.scrollHeight > document.body.clientHeight;
if (hasVScroll) {
windowWidth += 15;
}
if (windowWidth < 768) {
wmax = 2000;
}
// Now hide menu elements that don't fit into the menubar
var hidden = false; // Whether we have hidden any tabs
while (totalLen >= wmax && --l >= 0) {
// Process the tabs backwards
hidden = true;
var el = $($li[l]);
el.removeClass('nav-item').addClass('dropdown-item');
var elWidth = el.outerWidth(true);
el.data('width', elWidth);
if (!moreShown) {
totalLen -= elWidth;
el.prependTo($submenuUl);
totalLen += submenuW;
moreShown = true;
} else {
totalLen -= elWidth;
el.prependTo($submenuUl);
}
}
// If we didn't hide any tabs, then there might be some space to show some
if (!hidden) {
// Show menu elements that do fit into the menubar
for (i = 0, l = $li2.length; i < l; i++) {
totalLen += $($li2[i]).data('width');
// item fits or (it is the last item
// and it would fit if More got removed)
if (totalLen < wmax || i === $li2.length - 1 && totalLen - submenuW < wmax) {
$($li2[i]).removeClass('dropdown-item').addClass('nav-item');
$($li2[i]).insertBefore($submenu);
} else {
break;
}
}
}
// Show/hide the "More" tab as needed
if (windowWidth < 768) {
$('.navbar-collapse').css({
'width': windowWidth - 80 - $('#pma_navigation').width()
});
$submenu.addClass('d-none');
$('.navbar-collapse').css({
'overflow': 'hidden'
});
} else {
$('.navbar-collapse').css({
'width': 'auto'
});
$('.navbar-collapse').css({
'overflow': 'visible'
});
if ($submenuUl.find('li').length > 0) {
$submenu.removeClass('d-none');
} else {
$submenu.addClass('d-none');
}
}
};
MenuResizer.prototype.destroy = function () {
var $submenu = this.$container.find('.nav-item.dropdown').removeData();
$submenu.find('li').appendTo(this.$container);
$submenu.remove();
};
/** Public API */
var methods = {
init: function (widthCalculator) {
return this.each(function () {
var $this = $(this);
if (!$this.data('menuResizer')) {
$this.data('menuResizer', new MenuResizer($this, widthCalculator));
}
});
},
resize: function () {
return this.each(function () {
var self = $(this).data('menuResizer');
if (self) {
self.resize();
}
});
},
destroy: function () {
return this.each(function () {
var self = $(this).data('menuResizer');
if (self) {
self.destroy();
}
});
}
};
/**
* Extend jQuery
*
* @param {string} method
*
* @return {any}
*/
$.fn.menuResizer = function (method) {
if (methods[method]) {
return methods[method].call(this);
} else if (typeof method === 'function') {
return methods.init.apply(this, [method]);
} else {
$.error('Method ' + method + ' does not exist on jQuery.menuResizer');
}
};
})(jQuery);

View file

@ -1,31 +0,0 @@
/**
* @fileoverview Implements the shiftkey + click remove column
* from order by clause functionality
* @name columndelete
*
* @requires jQuery
*/
AJAX.registerOnload('keyhandler.js', function () {
$('th.draggable.column_heading.pointer.marker a').on('click', function (event) {
var orderUrlRemove = $(this).parent().find('input[name="url-remove-order"]').val();
var orderUrlAdd = $(this).parent().find('input[name="url-add-order"]').val();
var argsep = CommonParams.get('arg_separator');
if (event.ctrlKey || event.altKey) {
event.preventDefault();
AJAX.source = $(this);
Functions.ajaxShowMessage();
orderUrlRemove += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('index.php?route=/sql', orderUrlRemove, AJAX.responseHandler);
} else if (event.shiftKey) {
event.preventDefault();
AJAX.source = $(this);
Functions.ajaxShowMessage();
orderUrlAdd += argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
$.post('index.php?route=/sql', orderUrlAdd, AJAX.responseHandler);
}
});
});
AJAX.registerTeardown('keyhandler.js', function () {
$(document).off('click', 'th.draggable.column_heading.pointer.marker a');
});

View file

@ -1 +0,0 @@
$.widget.bridge('uiTooltip', $.ui.tooltip);

File diff suppressed because it is too large Load diff

View file

@ -1,715 +0,0 @@
/**
* @fileoverview events handling from normalization page
* @name normalization
*
* @requires jQuery
*/
// eslint-disable-next-line no-unused-vars
/* global centralColumnList:writable */ // js/functions.js
/**
* AJAX scripts for normalization
*
*/
var normalizeto = '1nf';
var primaryKey;
var dataParsed = null;
function appendHtmlColumnsList() {
$.post('index.php?route=/normalization', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'getColumns': true
}, function (data) {
if (data.success === true) {
$('select[name=makeAtomic]').html(data.message);
}
});
}
function goTo3NFStep1(newTables) {
var tables = newTables;
if (Object.keys(tables).length === 1) {
tables = [CommonParams.get('table')];
}
$.post('index.php?route=/normalization', {
'ajax_request': true,
'db': CommonParams.get('db'),
'server': CommonParams.get('server'),
'tables': tables,
'step': '3.1'
}, function (data) {
$('#page_content').find('h3').html(Messages.str3NFNormalization);
$('#mainContent').find('legend').html(data.legendText);
$('#mainContent').find('h4').html(data.headText);
$('#mainContent').find('p').html(data.subText);
$('#mainContent').find('#extra').html(data.extra);
$('#extra').find('form').each(function () {
var formId = $(this).attr('id');
var colName = $(this).data('colname');
$('#' + formId + ' input[value=\'' + colName + '\']').next().remove();
$('#' + formId + ' input[value=\'' + colName + '\']').remove();
});
$('#mainContent').find('#newCols').html('');
$('.tblFooters').html('');
if (data.subText !== '') {
$('<input>').attr({
type: 'button',
value: Messages.strDone,
class: 'btn btn-primary'
}).on('click', function () {
processDependencies('', true);
}).appendTo('.tblFooters');
}
});
}
function goTo2NFStep1() {
$.post('index.php?route=/normalization', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'step': '2.1'
}, function (data) {
$('#page_content h3').html(Messages.str2NFNormalization);
$('#mainContent legend').html(data.legendText);
$('#mainContent h4').html(data.headText);
$('#mainContent p').html(data.subText);
$('#mainContent #extra').html(data.extra);
$('#mainContent #newCols').html('');
if (data.subText !== '') {
$('<input>').attr({
type: 'submit',
value: Messages.strDone,
class: 'btn btn-primary'
}).on('click', function () {
processDependencies(data.primary_key);
}).appendTo('.tblFooters');
} else {
if (normalizeto === '3nf') {
$('#mainContent #newCols').html(Messages.strToNextStep);
setTimeout(function () {
goTo3NFStep1([CommonParams.get('table')]);
}, 3000);
}
}
});
}
function goToFinish1NF() {
if (normalizeto !== '1nf') {
goTo2NFStep1();
return true;
}
$('#mainContent legend').html(Messages.strEndStep);
$('#mainContent h4').html('<h3>' + Functions.sprintf(Messages.strFinishMsg, Functions.escapeHtml(CommonParams.get('table'))) + '</h3>');
$('#mainContent p').html('');
$('#mainContent #extra').html('');
$('#mainContent #newCols').html('');
$('.tblFooters').html('');
}
// eslint-disable-next-line no-unused-vars
function goToStep4() {
$.post('index.php?route=/normalization', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'step4': true
}, function (data) {
$('#mainContent legend').html(data.legendText);
$('#mainContent h4').html(data.headText);
$('#mainContent p').html(data.subText);
$('#mainContent #extra').html(data.extra);
$('#mainContent #newCols').html('');
$('.tblFooters').html('');
for (var pk in primaryKey) {
$('#extra input[value=\'' + Functions.escapeJsString(primaryKey[pk]) + '\']').attr('disabled', 'disabled');
}
});
}
function goToStep3() {
$.post('index.php?route=/normalization', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'step3': true
}, function (data) {
$('#mainContent legend').html(data.legendText);
$('#mainContent h4').html(data.headText);
$('#mainContent p').html(data.subText);
$('#mainContent #extra').html(data.extra);
$('#mainContent #newCols').html('');
$('.tblFooters').html('');
primaryKey = JSON.parse(data.primary_key);
for (var pk in primaryKey) {
$('#extra input[value=\'' + Functions.escapeJsString(primaryKey[pk]) + '\']').attr('disabled', 'disabled');
}
});
}
function goToStep2(extra) {
$.post('index.php?route=/normalization', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'step2': true
}, function (data) {
$('#mainContent legend').html(data.legendText);
$('#mainContent h4').html(data.headText);
$('#mainContent p').html(data.subText);
$('#mainContent #extra,#mainContent #newCols').html('');
$('.tblFooters').html('');
if (data.hasPrimaryKey === '1') {
if (extra === 'goToStep3') {
$('#mainContent h4').html(Messages.strPrimaryKeyAdded);
$('#mainContent p').html(Messages.strToNextStep);
}
if (extra === 'goToFinish1NF') {
goToFinish1NF();
} else {
setTimeout(function () {
goToStep3();
}, 3000);
}
} else {
// form to select columns to make primary
$('#mainContent #extra').html(data.extra);
}
});
}
function goTo2NFFinish(pd) {
var tables = {};
for (var dependson in pd) {
tables[dependson] = $('#extra input[name="' + dependson + '"]').val();
}
var datastring = {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'pd': JSON.stringify(pd),
'newTablesName': JSON.stringify(tables),
'createNewTables2NF': 1
};
$.ajax({
type: 'POST',
url: 'index.php?route=/normalization',
data: datastring,
async: false,
success: function (data) {
if (data.success === true) {
if (data.queryError === false) {
if (normalizeto === '3nf') {
$('#pma_navigation_reload').trigger('click');
goTo3NFStep1(tables);
return true;
}
$('#mainContent legend').html(data.legendText);
$('#mainContent h4').html(data.headText);
$('#mainContent p').html('');
$('#mainContent #extra').html('');
$('.tblFooters').html('');
} else {
Functions.ajaxShowMessage(data.extra, false);
}
$('#pma_navigation_reload').trigger('click');
} else {
Functions.ajaxShowMessage(data.error, false);
}
}
});
}
function goTo3NFFinish(newTables) {
for (var table in newTables) {
for (var newtbl in newTables[table]) {
var updatedname = $('#extra input[name="' + newtbl + '"]').val();
newTables[table][updatedname] = newTables[table][newtbl];
if (updatedname !== newtbl) {
delete newTables[table][newtbl];
}
}
}
var datastring = {
'ajax_request': true,
'db': CommonParams.get('db'),
'server': CommonParams.get('server'),
'newTables': JSON.stringify(newTables),
'createNewTables3NF': 1
};
$.ajax({
type: 'POST',
url: 'index.php?route=/normalization',
data: datastring,
async: false,
success: function (data) {
if (data.success === true) {
if (data.queryError === false) {
$('#mainContent legend').html(data.legendText);
$('#mainContent h4').html(data.headText);
$('#mainContent p').html('');
$('#mainContent #extra').html('');
$('.tblFooters').html('');
} else {
Functions.ajaxShowMessage(data.extra, false);
}
$('#pma_navigation_reload').trigger('click');
} else {
Functions.ajaxShowMessage(data.error, false);
}
}
});
}
var backup = '';
function goTo2NFStep2(pd, primaryKey) {
$('#newCols').html('');
$('#mainContent legend').html(Messages.strStep + ' 2.2 ' + Messages.strConfirmPd);
$('#mainContent h4').html(Messages.strSelectedPd);
$('#mainContent p').html(Messages.strPdHintNote);
var extra = '<div class="dependencies_box">';
var pdFound = false;
for (var dependson in pd) {
if (dependson !== primaryKey) {
pdFound = true;
extra += '<p class="d-block m-1">' + Functions.escapeHtml(dependson) + ' -> ' + Functions.escapeHtml(pd[dependson].toString()) + '</p>';
}
}
if (!pdFound) {
extra += '<p class="d-block m-1">' + Messages.strNoPdSelected + '</p>';
extra += '</div>';
} else {
extra += '</div>';
var datastring = {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'pd': JSON.stringify(pd),
'getNewTables2NF': 1
};
$.ajax({
type: 'POST',
url: 'index.php?route=/normalization',
data: datastring,
async: false,
success: function (data) {
if (data.success === true) {
extra += data.message;
} else {
Functions.ajaxShowMessage(data.error, false);
}
}
});
}
$('#mainContent #extra').html(extra);
$('.tblFooters').html('<input type="button" class="btn btn-primary" value="' + Messages.strBack + '" id="backEditPd"><input type="button" class="btn btn-primary" id="goTo2NFFinish" value="' + Messages.strGo + '">');
$('#goTo2NFFinish').on('click', function () {
goTo2NFFinish(pd);
});
}
function goTo3NFStep2(pd, tablesTds) {
$('#newCols').html('');
$('#mainContent legend').html(Messages.strStep + ' 3.2 ' + Messages.strConfirmTd);
$('#mainContent h4').html(Messages.strSelectedTd);
$('#mainContent p').html(Messages.strPdHintNote);
var extra = '<div class="dependencies_box">';
var pdFound = false;
for (var table in tablesTds) {
for (var i in tablesTds[table]) {
var dependson = tablesTds[table][i];
if (dependson !== '' && dependson !== table) {
pdFound = true;
extra += '<p class="d-block m-1">' + Functions.escapeHtml(dependson) + ' -> ' + Functions.escapeHtml(pd[dependson].toString()) + '</p>';
}
}
}
if (!pdFound) {
extra += '<p class="d-block m-1">' + Messages.strNoTdSelected + '</p>';
extra += '</div>';
} else {
extra += '</div>';
var datastring = {
'ajax_request': true,
'db': CommonParams.get('db'),
'tables': JSON.stringify(tablesTds),
'server': CommonParams.get('server'),
'pd': JSON.stringify(pd),
'getNewTables3NF': 1
};
$.ajax({
type: 'POST',
url: 'index.php?route=/normalization',
data: datastring,
async: false,
success: function (data) {
dataParsed = data;
if (data.success === true) {
extra += dataParsed.html;
} else {
Functions.ajaxShowMessage(data.error, false);
}
}
});
}
$('#mainContent #extra').html(extra);
$('.tblFooters').html('<input type="button" class="btn btn-primary" value="' + Messages.strBack + '" id="backEditPd"><input type="button" class="btn btn-primary" id="goTo3NFFinish" value="' + Messages.strGo + '">');
$('#goTo3NFFinish').on('click', function () {
if (!pdFound) {
goTo3NFFinish([]);
} else {
goTo3NFFinish(dataParsed.newTables);
}
});
}
function processDependencies(primaryKey, isTransitive) {
var pk = primaryKey;
var pd = {};
var tablesTds = {};
var dependsOn;
pd[pk] = [];
$('#extra form').each(function () {
var tblname;
if (isTransitive === true) {
tblname = $(this).data('tablename');
pk = tblname;
if (!(tblname in tablesTds)) {
tablesTds[tblname] = [];
}
tablesTds[tblname].push(pk);
}
var formId = $(this).attr('id');
$('#' + formId + ' input[type=checkbox]:not(:checked)').prop('checked', false);
dependsOn = '';
$('#' + formId + ' input[type=checkbox]:checked').each(function () {
dependsOn += $(this).val() + ', ';
$(this).attr('checked', 'checked');
});
if (dependsOn === '') {
dependsOn = pk;
} else {
dependsOn = dependsOn.slice(0, -2);
}
if (!(dependsOn in pd)) {
pd[dependsOn] = [];
}
pd[dependsOn].push($(this).data('colname'));
if (isTransitive === true) {
if (!(tblname in tablesTds)) {
tablesTds[tblname] = [];
}
if ($.inArray(dependsOn, tablesTds[tblname]) === -1) {
tablesTds[tblname].push(dependsOn);
}
}
});
backup = $('#mainContent').html();
if (isTransitive === true) {
goTo3NFStep2(pd, tablesTds);
} else {
goTo2NFStep2(pd, pk);
}
return false;
}
function moveRepeatingGroup(repeatingCols) {
var newTable = $('input[name=repeatGroupTable]').val();
var newColumn = $('input[name=repeatGroupColumn]').val();
if (!newTable) {
$('input[name=repeatGroupTable]').trigger('focus');
return false;
}
if (!newColumn) {
$('input[name=repeatGroupColumn]').trigger('focus');
return false;
}
var datastring = {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'repeatingColumns': repeatingCols,
'newTable': newTable,
'newColumn': newColumn,
'primary_columns': primaryKey.toString()
};
$.ajax({
type: 'POST',
url: 'index.php?route=/normalization',
data: datastring,
async: false,
success: function (data) {
if (data.success === true) {
if (data.queryError === false) {
goToStep3();
}
Functions.ajaxShowMessage(data.message, false);
$('#pma_navigation_reload').trigger('click');
} else {
Functions.ajaxShowMessage(data.error, false);
}
}
});
}
AJAX.registerTeardown('normalization.js', function () {
$('#extra').off('click', '#selectNonAtomicCol');
$('#splitGo').off('click');
$('.tblFooters').off('click', '#saveSplit');
$('#extra').off('click', '#addNewPrimary');
$('.tblFooters').off('click', '#saveNewPrimary');
$('#extra').off('click', '#removeRedundant');
$('#mainContent p').off('click', '#createPrimaryKey');
$('#mainContent').off('click', '#backEditPd');
$('#mainContent').off('click', '#showPossiblePd');
$('#mainContent').off('click', '.pickPd');
});
AJAX.registerOnload('normalization.js', function () {
var selectedCol;
normalizeto = $('#mainContent').data('normalizeto');
$('#extra').on('click', '#selectNonAtomicCol', function () {
if ($(this).val() === 'no_such_col') {
goToStep2();
} else {
selectedCol = $(this).val();
}
});
$('#splitGo').on('click', function () {
if (!selectedCol || selectedCol === '') {
return false;
}
var numField = $('#numField').val();
$.post('index.php?route=/normalization', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'splitColumn': true,
'numFields': numField
}, function (data) {
if (data.success === true) {
$('#newCols').html(data.message);
$('.default_value').hide();
$('.enum_notice').hide();
$('<input>').attr({
type: 'submit',
id: 'saveSplit',
value: Messages.strSave,
class: 'btn btn-primary'
}).appendTo('.tblFooters');
$('<input>').attr({
type: 'submit',
id: 'cancelSplit',
value: Messages.strCancel,
class: 'btn btn-secondary'
}).on('click', function () {
$('#newCols').html('');
$(this).parent().html('');
}).appendTo('.tblFooters');
}
});
return false;
});
$('.tblFooters').on('click', '#saveSplit', function () {
centralColumnList = [];
if ($('#newCols #field_0_1').val() === '') {
$('#newCols #field_0_1').trigger('focus');
return false;
}
var argsep = CommonParams.get('arg_separator');
var datastring = $('#newCols :input').serialize();
datastring += argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last';
$.post('index.php?route=/table/add-field', datastring, function (data) {
if (data.success) {
$.post('index.php?route=/sql', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'dropped_column': selectedCol,
'purge': 1,
'sql_query': 'ALTER TABLE `' + CommonParams.get('table') + '` DROP `' + selectedCol + '`;',
'is_js_confirmed': 1
}, function (data) {
if (data.success === true) {
appendHtmlColumnsList();
$('#newCols').html('');
$('.tblFooters').html('');
} else {
Functions.ajaxShowMessage(data.error, false);
}
selectedCol = '';
});
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
$('#extra').on('click', '#addNewPrimary', function () {
$.post('index.php?route=/normalization', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'addNewPrimary': true
}, function (data) {
if (data.success === true) {
$('#newCols').html(data.message);
$('.default_value').hide();
$('.enum_notice').hide();
$('<input>').attr({
type: 'submit',
id: 'saveNewPrimary',
value: Messages.strSave,
class: 'btn btn-primary'
}).appendTo('.tblFooters');
$('<input>').attr({
type: 'submit',
id: 'cancelSplit',
value: Messages.strCancel,
class: 'btn btn-secondary'
}).on('click', function () {
$('#newCols').html('');
$(this).parent().html('');
}).appendTo('.tblFooters');
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
return false;
});
$('.tblFooters').on('click', '#saveNewPrimary', function () {
var datastring = $('#newCols :input').serialize();
var argsep = CommonParams.get('arg_separator');
datastring += argsep + 'field_key[0]=primary_0' + argsep + 'ajax_request=1' + argsep + 'do_save_data=1' + argsep + 'field_where=last';
$.post('index.php?route=/table/add-field', datastring, function (data) {
if (data.success === true) {
$('#mainContent h4').html(Messages.strPrimaryKeyAdded);
$('#mainContent p').html(Messages.strToNextStep);
$('#mainContent #extra').html('');
$('#mainContent #newCols').html('');
$('.tblFooters').html('');
setTimeout(function () {
goToStep3();
}, 2000);
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
$('#extra').on('click', '#removeRedundant', function () {
var dropQuery = 'ALTER TABLE `' + CommonParams.get('table') + '` ';
$('#extra input[type=checkbox]:checked').each(function () {
dropQuery += 'DROP `' + $(this).val() + '`, ';
});
dropQuery = dropQuery.slice(0, -2);
$.post('index.php?route=/sql', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'sql_query': dropQuery,
'is_js_confirmed': 1
}, function (data) {
if (data.success === true) {
goToStep2('goToFinish1NF');
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
$('#extra').on('click', '#moveRepeatingGroup', function () {
var repeatingCols = '';
$('#extra input[type=checkbox]:checked').each(function () {
repeatingCols += $(this).val() + ', ';
});
if (repeatingCols !== '') {
var newColName = $('#extra input[type=checkbox]:checked').first().val();
repeatingCols = repeatingCols.slice(0, -2);
var confirmStr = Functions.sprintf(Messages.strMoveRepeatingGroup, Functions.escapeHtml(repeatingCols), Functions.escapeHtml(CommonParams.get('table')));
confirmStr += '<input type="text" name="repeatGroupTable" placeholder="' + Messages.strNewTablePlaceholder + '">' + '( ' + Functions.escapeHtml(primaryKey.toString()) + ', <input type="text" name="repeatGroupColumn" placeholder="' + Messages.strNewColumnPlaceholder + '" value="' + Functions.escapeHtml(newColName) + '">)' + '</ol>';
$('#newCols').html(confirmStr);
$('<input>').attr({
type: 'submit',
value: Messages.strCancel,
class: 'btn btn-secondary'
}).on('click', function () {
$('#newCols').html('');
$('#extra input[type=checkbox]').prop('checked', false);
}).appendTo('.tblFooters');
$('<input>').attr({
type: 'submit',
value: Messages.strGo,
class: 'btn btn-primary'
}).on('click', function () {
moveRepeatingGroup(repeatingCols);
}).appendTo('.tblFooters');
}
});
$('#mainContent p').on('click', '#createPrimaryKey', function (event) {
event.preventDefault();
var url = {
'create_index': 1,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'added_fields': 1,
'add_fields': 1,
'index': {
'Key_name': 'PRIMARY'
},
'ajax_request': true
};
var title = Messages.strAddPrimaryKey;
Functions.indexEditorDialog(url, title, function () {
// on success
$('.sqlqueryresults').remove();
$('.result_query').remove();
$('.tblFooters').html('');
goToStep2('goToStep3');
});
return false;
});
$('#mainContent').on('click', '#backEditPd', function () {
$('#mainContent').html(backup);
});
$('#mainContent').on('click', '#showPossiblePd', function () {
if ($(this).hasClass('hideList')) {
$(this).html('+ ' + Messages.strShowPossiblePd);
$(this).removeClass('hideList');
$('#newCols').slideToggle('slow');
return false;
}
if ($('#newCols').html() !== '') {
$('#showPossiblePd').html('- ' + Messages.strHidePd);
$('#showPossiblePd').addClass('hideList');
$('#newCols').slideToggle('slow');
return false;
}
$('#newCols').insertAfter('#mainContent h4');
$('#newCols').html('<div class="text-center">' + Messages.strLoading + '<br>' + Messages.strWaitForPd + '</div>');
$.post('index.php?route=/normalization', {
'ajax_request': true,
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'server': CommonParams.get('server'),
'findPdl': true
}, function (data) {
$('#showPossiblePd').html('- ' + Messages.strHidePd);
$('#showPossiblePd').addClass('hideList');
$('#newCols').html(data.message);
});
});
$('#mainContent').on('click', '.pickPd', function () {
var strColsLeft = $(this).next('.determinants').html();
var colsLeft = strColsLeft.split(',');
var strColsRight = $(this).next().next().html();
var colsRight = strColsRight.split(',');
for (var i in colsRight) {
$('form[data-colname="' + colsRight[i].trim() + '"] input[type="checkbox"]').prop('checked', false);
for (var j in colsLeft) {
$('form[data-colname="' + colsRight[i].trim() + '"] input[value="' + colsLeft[j].trim() + '"]').prop('checked', true);
}
}
});
});

View file

@ -1,62 +0,0 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _control = require("ol/control.js");
var _coordinate = require("ol/coordinate.js");
var _extent = require("ol/extent.js");
var _geom = require("ol/geom.js");
var _layer = require("ol/layer.js");
var _proj = require("ol/proj.js");
var _source = require("ol/source.js");
var _style = require("ol/style.js");
var _ol = require("ol");
const ol = {
control: {
Attribution: _control.Attribution,
MousePosition: _control.MousePosition,
Zoom: _control.Zoom
},
coordinate: {
createStringXY: _coordinate.createStringXY
},
extent: {
boundingExtent: _extent.boundingExtent
},
geom: {
LineString: _geom.LineString,
LinearRing: _geom.LinearRing,
MultiLineString: _geom.MultiLineString,
MultiPoint: _geom.MultiPoint,
MultiPolygon: _geom.MultiPolygon,
Point: _geom.Point,
Polygon: _geom.Polygon
},
layer: {
Tile: _layer.Tile,
Vector: _layer.Vector
},
proj: {
fromLonLat: _proj.fromLonLat,
get: _proj.get,
transformExtent: _proj.transformExtent
},
source: {
OSM: _source.OSM,
Vector: _source.Vector
},
style: {
Circle: _style.Circle,
Fill: _style.Fill,
Stroke: _style.Stroke,
Style: _style.Style,
Text: _style.Text
},
Feature: _ol.Feature,
Map: _ol.Map,
View: _ol.View
};
var _default = ol;
exports.default = _default;

View file

@ -1,64 +0,0 @@
/**
* @fileoverview function used for page-related settings
* @name Page-related settings
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
function showSettings(selector) {
var buttons = {
[Messages.strApply]: {
text: Messages.strApply,
class: 'btn btn-primary'
},
[Messages.strCancel]: {
text: Messages.strCancel,
class: 'btn btn-secondary'
}
};
buttons[Messages.strApply].click = function () {
$('.config-form').trigger('submit');
};
buttons[Messages.strCancel].click = function () {
$(this).dialog('close');
};
// Keeping a clone to restore in case the user cancels the operation
var $clone = $(selector + ' .page_settings').clone(true);
$(selector).dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
title: Messages.strPageSettings,
width: 700,
minHeight: 250,
modal: true,
open: function () {
$(this).dialog('option', 'maxHeight', $(window).height() - $(this).offset().top);
},
close: function () {
$(selector + ' .page_settings').replaceWith($clone);
},
buttons: buttons
});
}
function showPageSettings() {
showSettings('#page_settings_modal');
}
function showNaviSettings() {
showSettings('#pma_navigation_settings');
}
AJAX.registerTeardown('page_settings.js', function () {
$('#page_settings_icon').css('display', 'none');
$('#page_settings_icon').off('click');
$('#pma_navigation_settings_icon').off('click');
});
AJAX.registerOnload('page_settings.js', function () {
if ($('#page_settings_modal').length) {
$('#page_settings_icon').css('display', 'inline');
$('#page_settings_icon').on('click', showPageSettings);
}
$('#pma_navigation_settings_icon').on('click', showNaviSettings);
});

View file

@ -1,102 +0,0 @@
/**
* @fileoverview Javascript functions used in server replication page
* @name Server Replication
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*/
var randomServerId = Math.floor(Math.random() * 10000000);
var confPrefix = 'server-id=' + randomServerId + '\nlog_bin=mysql-bin\nlog_error=mysql-bin.err\n';
function updateConfig() {
var confIgnore = 'binlog_ignore_db=';
var confDo = 'binlog_do_db=';
var databaseList = '';
if ($('#db_select option:selected').length === 0) {
$('#rep').text(confPrefix);
} else if ($('#db_type option:selected').val() === 'all') {
$('#db_select option:selected').each(function () {
databaseList += confIgnore + $(this).val() + '\n';
});
$('#rep').text(confPrefix + databaseList);
} else {
$('#db_select option:selected').each(function () {
databaseList += confDo + $(this).val() + '\n';
});
$('#rep').text(confPrefix + databaseList);
}
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('replication.js', function () {
$('#db_type').off('change');
$('#db_select').off('change');
$('#primary_status_href').off('click');
$('#primary_replicas_href').off('click');
$('#replica_status_href').off('click');
$('#replica_control_href').off('click');
$('#replica_errormanagement_href').off('click');
$('#replica_synchronization_href').off('click');
$('#db_reset_href').off('click');
$('#db_select_href').off('click');
$('#reset_replica').off('click');
});
AJAX.registerOnload('replication.js', function () {
$('#rep').text(confPrefix);
$('#db_type').on('change', updateConfig);
$('#db_select').on('change', updateConfig);
$('#primary_status_href').on('click', function () {
$('#replication_primary_section').toggle();
});
$('#primary_replicas_href').on('click', function () {
$('#replication_replicas_section').toggle();
});
$('#replica_status_href').on('click', function () {
$('#replication_replica_section').toggle();
});
$('#replica_control_href').on('click', function () {
$('#replica_control_gui').toggle();
});
$('#replica_errormanagement_href').on('click', function () {
$('#replica_errormanagement_gui').toggle();
});
$('#replica_synchronization_href').on('click', function () {
$('#replica_synchronization_gui').toggle();
});
$('#db_reset_href').on('click', function () {
$('#db_select option:selected').prop('selected', false);
$('#db_select').trigger('change');
});
$('#db_select_href').on('click', function () {
$('#db_select option').prop('selected', true);
$('#db_select').trigger('change');
});
$('#reset_replica').on('click', function (e) {
e.preventDefault();
var $anchor = $(this);
var question = Messages.strResetReplicaWarning;
$anchor.confirm(question, $anchor.attr('href'), function (url) {
Functions.ajaxShowMessage();
AJAX.source = $anchor;
var params = Functions.getJsConfirmCommonParam({
'ajax_page_request': true,
'ajax_request': true
}, $anchor.getPostData());
$.post(url, params, AJAX.responseHandler);
});
});
$('#button_generate_password').on('click', function () {
Functions.suggestPassword(this.form);
});
$('#nopass_1').on('click', function () {
this.form.pma_pw.value = '';
this.form.pma_pw2.value = '';
this.checked = true;
});
$('#nopass_0').on('click', function () {
document.getElementById('text_pma_change_pw').focus();
});
});

View file

@ -1,125 +0,0 @@
/**
* @fileoverview functions used on the server databases list page
* @name Server Databases
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server/databases.js', function () {
$(document).off('submit', '#dbStatsForm');
$(document).off('submit', '#create_database_form.ajax');
});
/**
* AJAX scripts for /server/databases
*
* Actions ajaxified here:
* Drop Databases
*
*/
AJAX.registerOnload('server/databases.js', function () {
/**
* Attach Event Handler for 'Drop Databases'
*/
$(document).on('submit', '#dbStatsForm', function (event) {
event.preventDefault();
var $form = $(this);
/**
* @var selected_dbs Array containing the names of the checked databases
*/
var selectedDbs = [];
// loop over all checked checkboxes, except the .checkall_box checkbox
$form.find('input:checkbox:checked:not(.checkall_box)').each(function () {
$(this).closest('tr').addClass('removeMe');
selectedDbs[selectedDbs.length] = 'DROP DATABASE `' + Functions.escapeHtml($(this).val()) + '`;';
});
if (!selectedDbs.length) {
Functions.ajaxShowMessage($('<div class="alert alert-warning" role="alert"></div>').text(Messages.strNoDatabasesSelected), 2000);
return;
}
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strDropDatabaseStrongWarning + ' ' + Functions.sprintf(Messages.strDoYouReally, selectedDbs.join('<br>'));
const modal = $('#dropDatabaseModal');
modal.find('.modal-body').html(question);
modal.modal('show');
const url = 'index.php?route=/server/databases/destroy&' + $(this).serialize();
$('#dropDatabaseModalDropButton').on('click', function () {
Functions.ajaxShowMessage(Messages.strProcessingRequest, false);
var parts = url.split('?');
var params = Functions.getJsConfirmCommonParam(this, parts[1]);
$.post(parts[0], params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
var $rowsToRemove = $form.find('tr.removeMe');
var $databasesCount = $('#filter-rows-count');
var newCount = parseInt($databasesCount.text(), 10) - $rowsToRemove.length;
$databasesCount.text(newCount);
$rowsToRemove.remove();
$form.find('tbody').sortTable('.name');
if ($form.find('tbody').find('tr').length === 0) {
// user just dropped the last db on this page
CommonActions.refreshMain();
}
Navigation.reload();
} else {
$form.find('tr.removeMe').removeClass('removeMe');
Functions.ajaxShowMessage(data.error, false);
}
});
modal.modal('hide');
$('#dropDatabaseModalDropButton').off('click');
});
});
/**
* Attach Ajax event handlers for 'Create Database'.
*/
$(document).on('submit', '#create_database_form.ajax', function (event) {
event.preventDefault();
var $form = $(this);
// TODO Remove this section when all browsers support HTML5 "required" property
var newDbNameInput = $form.find('input[name=new_db]');
if (newDbNameInput.val() === '') {
newDbNameInput.trigger('focus');
alert(Messages.strFormEmpty);
return;
}
// end remove
Functions.ajaxShowMessage(Messages.strProcessingRequest);
Functions.prepareForAjaxRequest($form);
$.post($form.attr('action'), $form.serialize(), function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
var $databasesCountObject = $('#filter-rows-count');
var databasesCount = parseInt($databasesCountObject.text(), 10) + 1;
$databasesCountObject.text(databasesCount);
Navigation.reload();
// make ajax request to load db structure page - taken from ajax.js
var dbStructUrl = data.url;
dbStructUrl = dbStructUrl.replace(/amp;/ig, '');
var params = 'ajax_request=true' + CommonParams.get('arg_separator') + 'ajax_page_request=true';
$.get(dbStructUrl, params, AJAX.responseHandler);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end $(document).on()
var tableRows = $('.server_databases');
$.each(tableRows, function () {
$(this).on('click', function () {
CommonActions.setDb($(this).attr('data'));
});
});
}); // end $()

View file

@ -1,16 +0,0 @@
/**
* Functions used in server plugins pages
*/
AJAX.registerOnload('server/plugins.js', function () {
// Make columns sortable, but only for tables with more than 1 data row
var $tables = $('#plugins_plugins table:has(tbody tr + tr)');
$tables.tablesorter({
sortList: [[0, 0]],
headers: {
1: {
sorter: false
}
}
});
$tables.find('thead th').append('<div class="sorticon"></div>');
});

View file

@ -1,435 +0,0 @@
/**
* @fileoverview functions used in server privilege pages
* @name Server Privileges
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Validates the "add a user" form
*
* @param theForm
*
* @return {bool} whether the form is validated or not
*/
function checkAddUser(theForm) {
if (theForm.elements.hostname.value === '') {
alert(Messages.strHostEmpty);
theForm.elements.hostname.focus();
return false;
}
if (theForm.elements.pred_username && theForm.elements.pred_username.value === 'userdefined' && theForm.elements.username.value === '') {
alert(Messages.strUserEmpty);
theForm.elements.username.focus();
return false;
}
return Functions.checkPassword($(theForm));
}
/**
* Export privileges modal handler
*
* @param {object} data
*
* @param {JQuery} msgbox
*
*/
function exportPrivilegesModalHandler(data, msgbox) {
if (typeof data !== 'undefined' && data.success === true) {
var modal = $('#exportPrivilegesModal');
// Remove any previous privilege modal data, if any
modal.find('.modal-body').first().html('');
$('#exportPrivilegesModalLabel').first().html('Loading');
modal.modal('show');
modal.on('shown.bs.modal', function () {
modal.find('.modal-body').first().html(data.message);
$('#exportPrivilegesModalLabel').first().html(data.title);
Functions.ajaxRemoveMessage(msgbox);
// Attach syntax highlighted editor to export dialog
Functions.getSqlEditor(modal.find('textarea'));
});
return;
}
Functions.ajaxShowMessage(data.error, false);
}
/**
* @implements EventListener
*/
const EditUserGroup = {
/**
* @param {MouseEvent} event
*/
handleEvent: function (event) {
const editUserGroupModal = document.getElementById('editUserGroupModal');
const button = event.relatedTarget;
const username = button.getAttribute('data-username');
$.get('index.php?route=/server/user-groups/edit-form', {
'username': username,
'server': CommonParams.get('server')
}, data => {
if (typeof data === 'undefined' || data.success !== true) {
Functions.ajaxShowMessage(data.error, false, 'error');
return;
}
const modal = bootstrap.Modal.getInstance(editUserGroupModal);
const modalBody = editUserGroupModal.querySelector('.modal-body');
const saveButton = editUserGroupModal.querySelector('#editUserGroupModalSaveButton');
modalBody.innerHTML = data.message;
saveButton.addEventListener('click', () => {
const form = $(editUserGroupModal.querySelector('#changeUserGroupForm'));
$.post('index.php?route=/server/privileges', form.serialize() + CommonParams.get('arg_separator') + 'ajax_request=1', data => {
if (typeof data === 'undefined' || data.success !== true) {
Functions.ajaxShowMessage(data.error, false, 'error');
return;
}
const userGroup = form.serializeArray().find(el => el.name === 'userGroup').value;
// button -> td -> tr -> td.usrGroup
const userGroupTableCell = button.parentElement.parentElement.querySelector('.usrGroup');
userGroupTableCell.textContent = userGroup;
});
modal.hide();
});
});
}
};
/**
* @implements EventListener
*/
const AccountLocking = {
handleEvent: function () {
const button = this;
const isLocked = button.dataset.isLocked === 'true';
const url = isLocked ? 'index.php?route=/server/privileges/account-unlock' : 'index.php?route=/server/privileges/account-lock';
const params = {
'username': button.dataset.userName,
'hostname': button.dataset.hostName,
'ajax_request': true,
'server': CommonParams.get('server')
};
$.post(url, params, data => {
if (data.success === false) {
Functions.ajaxShowMessage(data.error);
return;
}
if (isLocked) {
const lockIcon = Functions.getImage('s_lock', Messages.strLock, {}).toString();
button.innerHTML = '<span class="text-nowrap">' + lockIcon + ' ' + Messages.strLock + '</span>';
button.title = Messages.strLockAccount;
button.dataset.isLocked = 'false';
} else {
const unlockIcon = Functions.getImage('s_unlock', Messages.strUnlock, {}).toString();
button.innerHTML = '<span class="text-nowrap">' + unlockIcon + ' ' + Messages.strUnlock + '</span>';
button.title = Messages.strUnlockAccount;
button.dataset.isLocked = 'true';
}
Functions.ajaxShowMessage(data.message);
});
}
};
/**
* AJAX scripts for /server/privileges page.
*
* Actions ajaxified here:
* Add user
* Revoke a user
* Edit privileges
* Export privileges
* Paginate table of users
* Flush privileges
*
* @memberOf jQuery
* @name document.ready
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server/privileges.js', function () {
$('#fieldset_add_user_login').off('change', 'input[name=\'username\']');
$(document).off('click', '#deleteUserCard .btn.ajax');
const editUserGroupModal = document.getElementById('editUserGroupModal');
if (editUserGroupModal) {
editUserGroupModal.removeEventListener('show.bs.modal', EditUserGroup);
}
$(document).off('click', 'button.mult_submit[value=export]');
$(document).off('click', 'a.export_user_anchor.ajax');
$('button.jsAccountLocking').off('click');
$('#dropUsersDbCheckbox').off('click');
$(document).off('click', '.checkall_box');
$(document).off('change', '#checkbox_SSL_priv');
$(document).off('change', 'input[name="ssl_type"]');
$(document).off('change', '#select_authentication_plugin');
});
AJAX.registerOnload('server/privileges.js', function () {
/**
* Display a warning if there is already a user by the name entered as the username.
*/
$('#fieldset_add_user_login').on('change', 'input[name=\'username\']', function () {
var username = $(this).val();
var $warning = $('#user_exists_warning');
if ($('#select_pred_username').val() === 'userdefined' && username !== '') {
var href = $('form[name=\'usersForm\']').attr('action');
var params = {
'ajax_request': true,
'server': CommonParams.get('server'),
'validate_username': true,
'username': username
};
$.get(href, params, function (data) {
if (data.user_exists) {
$warning.show();
} else {
$warning.hide();
}
});
} else {
$warning.hide();
}
});
/**
* Indicating password strength
*/
$('#text_pma_pw').on('keyup', function () {
var meterObj = $('#password_strength_meter');
var meterObjLabel = $('#password_strength');
var username = $('input[name="username"]');
username = username.val();
Functions.checkPasswordStrength($(this).val(), meterObj, meterObjLabel, username);
});
/**
* Automatically switching to 'Use Text field' from 'No password' once start writing in text area
*/
$('#text_pma_pw').on('input', function () {
if ($('#text_pma_pw').val() !== '') {
$('#select_pred_password').val('userdefined');
}
});
$('#text_pma_change_pw').on('keyup', function () {
var meterObj = $('#change_password_strength_meter');
var meterObjLabel = $('#change_password_strength');
Functions.checkPasswordStrength($(this).val(), meterObj, meterObjLabel, CommonParams.get('user'));
});
/**
* Display a notice if sha256_password is selected
*/
$(document).on('change', '#select_authentication_plugin', function () {
var selectedPlugin = $(this).val();
if (selectedPlugin === 'sha256_password') {
$('#ssl_reqd_warning').show();
} else {
$('#ssl_reqd_warning').hide();
}
});
/**
* AJAX handler for 'Revoke User'
*
* @see Functions.ajaxShowMessage()
* @memberOf jQuery
* @name revoke_user_click
*/
$(document).on('click', '#deleteUserCard .btn.ajax', function (event) {
event.preventDefault();
var $thisButton = $(this);
var $form = $('#usersForm');
$thisButton.confirm(Messages.strDropUserWarning, $form.attr('action'), function (url) {
var $dropUsersDbCheckbox = $('#dropUsersDbCheckbox');
if ($dropUsersDbCheckbox.is(':checked')) {
var isConfirmed = confirm(Messages.strDropDatabaseStrongWarning + '\n' + Functions.sprintf(Messages.strDoYouReally, 'DROP DATABASE'));
if (!isConfirmed) {
// Uncheck the drop users database checkbox
$dropUsersDbCheckbox.prop('checked', false);
}
}
Functions.ajaxShowMessage(Messages.strRemovingSelectedUsers);
var argsep = CommonParams.get('arg_separator');
$.post(url, $form.serialize() + argsep + 'delete=' + $thisButton.val() + argsep + 'ajax_request=true', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
// Refresh navigation, if we dropped some databases with the name
// that is the same as the username of the deleted user
if ($('#dropUsersDbCheckbox:checked').length) {
Navigation.reload();
}
// Remove the revoked user from the users list
$form.find('input:checkbox:checked').parents('tr').slideUp('medium', function () {
var thisUserInitial = $(this).find('input:checkbox').val().charAt(0).toUpperCase();
$(this).remove();
// If this is the last user with thisUserInitial, remove the link from #userAccountsPagination
if ($('#userRightsTable').find('input:checkbox[value^="' + thisUserInitial + '"], input:checkbox[value^="' + thisUserInitial.toLowerCase() + '"]').length === 0) {
$('#userAccountsPagination').find('.page-item > .page-link:contains(' + thisUserInitial + ')').parent('.page-item').addClass('disabled').html('<a class="page-link" href="#" tabindex="-1" aria-disabled="true">' + thisUserInitial + '</a>');
}
// Re-check the classes of each row
$form.find('tbody').find('tr').each(function (index) {
if (index >= 0 && index % 2 === 0) {
$(this).removeClass('odd').addClass('even');
} else if (index >= 0 && index % 2 !== 0) {
$(this).removeClass('even').addClass('odd');
}
});
// update the checkall checkbox
$(Functions.checkboxesSel).trigger('change');
});
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
}); // end Revoke User
const editUserGroupModal = document.getElementById('editUserGroupModal');
if (editUserGroupModal) {
editUserGroupModal.addEventListener('show.bs.modal', EditUserGroup);
}
/**
* AJAX handler for 'Export Privileges'
*
* @see Functions.ajaxShowMessage()
* @memberOf jQuery
* @name export_user_click
*/
$(document).on('click', 'button.mult_submit[value=export]', function (event) {
event.preventDefault();
// can't export if no users checked
if ($(this.form).find('input:checked').length === 0) {
Functions.ajaxShowMessage(Messages.strNoAccountSelected, 2000, 'success');
return;
}
var msgbox = Functions.ajaxShowMessage();
var argsep = CommonParams.get('arg_separator');
var serverId = CommonParams.get('server');
var selectedUsers = $('#usersForm input[name*=\'selected_usr\']:checkbox').serialize();
var postStr = selectedUsers + '&submit_mult=export' + argsep + 'ajax_request=true&server=' + serverId;
$.post($(this.form).prop('action'), postStr, function (data) {
exportPrivilegesModalHandler(data, msgbox);
}); // end $.post
});
// if exporting non-ajax, highlight anyways
Functions.getSqlEditor($('textarea.export'));
$(document).on('click', 'a.export_user_anchor.ajax', function (event) {
event.preventDefault();
var msgbox = Functions.ajaxShowMessage();
$.get($(this).attr('href'), {
'ajax_request': true
}, function (data) {
exportPrivilegesModalHandler(data, msgbox);
}); // end $.get
}); // end export privileges
$('button.jsAccountLocking').on('click', AccountLocking.handleEvent);
$(document).on('change', 'input[name="ssl_type"]', function () {
var $div = $('#specified_div');
if ($('#ssl_type_SPECIFIED').is(':checked')) {
$div.find('input').prop('disabled', false);
} else {
$div.find('input').prop('disabled', true);
}
});
$(document).on('change', '#checkbox_SSL_priv', function () {
var $div = $('#require_ssl_div');
if ($(this).is(':checked')) {
$div.find('input').prop('disabled', false);
$('#ssl_type_SPECIFIED').trigger('change');
} else {
$div.find('input').prop('disabled', true);
}
});
$('#checkbox_SSL_priv').trigger('change');
/*
* Create submenu for simpler interface
*/
var addOrUpdateSubmenu = function () {
var $subNav = $('.nav-pills');
var $editUserDialog = $('#edit_user_dialog');
var submenuLabel;
var submenuLink;
var linkNumber;
// if submenu exists yet, remove it first
if ($subNav.length > 0) {
$subNav.remove();
}
// construct a submenu from the existing fieldsets
$subNav = $('<ul></ul>').prop('class', 'nav nav-pills m-2');
$('#edit_user_dialog .submenu-item').each(function () {
submenuLabel = $(this).find('legend[data-submenu-label]').data('submenu-label');
submenuLink = $('<a></a>').prop('class', 'nav-link').prop('href', '#').html(submenuLabel);
$('<li></li>').prop('class', 'nav-item').append(submenuLink).appendTo($subNav);
});
// click handlers for submenu
$subNav.find('a').on('click', function (e) {
e.preventDefault();
// if already active, ignore click
if ($(this).hasClass('active')) {
return;
}
$subNav.find('a').removeClass('active');
$(this).addClass('active');
// which section to show now?
linkNumber = $subNav.find('a').index($(this));
// hide all sections but the one to show
$('#edit_user_dialog .submenu-item').hide().eq(linkNumber).show();
});
// make first menu item active
// TODO: support URL hash history
$subNav.find('> :first-child a').addClass('active');
$editUserDialog.prepend($subNav);
// hide all sections but the first
$('#edit_user_dialog .submenu-item').hide().eq(0).show();
// scroll to the top
$('html, body').animate({
scrollTop: 0
}, 'fast');
};
$('input.autofocus').trigger('focus');
$(Functions.checkboxesSel).trigger('change');
Functions.displayPasswordGenerateButton();
if ($('#edit_user_dialog').length > 0) {
addOrUpdateSubmenu();
}
/**
* Select all privileges
*
* @param {HTMLElement} e
* @return {void}
*/
var tableSelectAll = function (e) {
const method = e.target.getAttribute('data-select-target');
var options = $(method).first().children();
options.each(function (_, obj) {
obj.selected = true;
});
};
$('#select_priv_all').on('click', tableSelectAll);
$('#insert_priv_all').on('click', tableSelectAll);
$('#update_priv_all').on('click', tableSelectAll);
$('#references_priv_all').on('click', tableSelectAll);
var windowWidth = $(window).width();
$('.jsresponsive').css('max-width', windowWidth - 35 + 'px');
$('#addUsersForm').on('submit', function () {
return checkAddUser(this);
});
$('#copyUserForm').on('submit', function () {
return checkAddUser(this);
});
});

File diff suppressed because it is too large Load diff

View file

@ -1,182 +0,0 @@
/**
* Server Status Processes
*
* @package PhpMyAdmin
*/
// object to store process list state information
var processList = {
// denotes whether auto refresh is on or off
autoRefresh: false,
// stores the GET request which refresh process list
refreshRequest: null,
// stores the timeout id returned by setTimeout
refreshTimeout: null,
// the refresh interval in seconds
refreshInterval: null,
// the refresh URL (required to save last used option)
// i.e. full or sorting url
refreshUrl: null,
/**
* Handles killing of a process
*
* @return {void}
*/
init: function () {
processList.setRefreshLabel();
if (processList.refreshUrl === null) {
processList.refreshUrl = 'index.php?route=/server/status/processes/refresh';
}
if (processList.refreshInterval === null) {
processList.refreshInterval = $('#id_refreshRate').val();
} else {
$('#id_refreshRate').val(processList.refreshInterval);
}
},
/**
* Handles killing of a process
*
* @param {object} event the event object
*
* @return {void}
*/
killProcessHandler: function (event) {
event.preventDefault();
var argSep = CommonParams.get('arg_separator');
var params = $(this).getPostData();
params += argSep + 'ajax_request=1' + argSep + 'server=' + CommonParams.get('server');
// Get row element of the process to be killed.
var $tr = $(this).closest('tr');
$.post($(this).attr('href'), params, function (data) {
// Check if process was killed or not.
if (data.hasOwnProperty('success') && data.success) {
// remove the row of killed process.
$tr.remove();
// As we just removed a row, reapply odd-even classes
// to keep table stripes consistent
var $tableProcessListTr = $('#tableprocesslist').find('> tbody > tr');
$tableProcessListTr.each(function (index) {
if (index >= 0 && index % 2 === 0) {
$(this).removeClass('odd').addClass('even');
} else if (index >= 0 && index % 2 !== 0) {
$(this).removeClass('even').addClass('odd');
}
});
// Show process killed message
Functions.ajaxShowMessage(data.message, false);
} else {
// Show process error message
Functions.ajaxShowMessage(data.error, false);
}
}, 'json');
},
/**
* Handles Auto Refreshing
* @return {void}
*/
refresh: function () {
// abort any previous pending requests
// this is necessary, it may go into
// multiple loops causing unnecessary
// requests even after leaving the page.
processList.abortRefresh();
// if auto refresh is enabled
if (processList.autoRefresh) {
// Only fetch the table contents
processList.refreshUrl = 'index.php?route=/server/status/processes/refresh';
var interval = parseInt(processList.refreshInterval, 10) * 1000;
var urlParams = processList.getUrlParams();
processList.refreshRequest = $.post(processList.refreshUrl, urlParams, function (data) {
if (data.hasOwnProperty('success') && data.success) {
var $newTable = $(data.message);
$('#tableprocesslist').html($newTable.html());
Functions.highlightSql($('#tableprocesslist'));
}
processList.refreshTimeout = setTimeout(processList.refresh, interval);
});
}
},
/**
* Stop current request and clears timeout
*
* @return {void}
*/
abortRefresh: function () {
if (processList.refreshRequest !== null) {
processList.refreshRequest.abort();
processList.refreshRequest = null;
}
clearTimeout(processList.refreshTimeout);
},
/**
* Set label of refresh button
* change between play & pause
*
* @return {void}
*/
setRefreshLabel: function () {
var img = 'play';
var label = Messages.strStartRefresh;
if (processList.autoRefresh) {
img = 'pause';
label = Messages.strStopRefresh;
processList.refresh();
}
$('a#toggleRefresh').html(Functions.getImage(img) + Functions.escapeHtml(label));
},
/**
* Return the Url Parameters
* for autorefresh request,
* includes showExecuting if the filter is checked
*
* @return {object} urlParams - url parameters with autoRefresh request
*/
getUrlParams: function () {
var urlParams = {
'server': CommonParams.get('server'),
'ajax_request': true,
'refresh': true,
'full': $('input[name="full"]').val(),
'order_by_field': $('input[name="order_by_field"]').val(),
'column_name': $('input[name="column_name"]').val(),
'sort_order': $('input[name="sort_order"]').val()
};
if ($('#showExecuting').is(':checked')) {
urlParams.showExecuting = true;
return urlParams;
}
return urlParams;
}
};
AJAX.registerOnload('server/status/processes.js', function () {
processList.init();
// Bind event handler for kill_process
$('#tableprocesslist').on('click', 'a.kill_process', processList.killProcessHandler);
// Bind event handler for toggling refresh of process list
$('a#toggleRefresh').on('click', function (event) {
event.preventDefault();
processList.autoRefresh = !processList.autoRefresh;
processList.setRefreshLabel();
});
// Bind event handler for change in refresh rate
$('#id_refreshRate').on('change', function () {
processList.refreshInterval = $(this).val();
processList.refresh();
});
// Bind event handler for table header links
$('#tableprocesslist').on('click', 'thead a', function () {
processList.refreshUrl = $(this).attr('href');
});
});
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server/status/processes.js', function () {
$('#tableprocesslist').off('click', 'a.kill_process');
$('a#toggleRefresh').off('click');
$('#id_refreshRate').off('change');
$('#tableprocesslist').off('click', 'thead a');
// stop refreshing further
processList.abortRefresh();
});

View file

@ -1,37 +0,0 @@
/**
* @fileoverview Javascript functions used in server status query page
* @name Server Status Query
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*/
/* global initTableSorter */ // js/server/status/sorter.js
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server/status/queries.js', function () {
if (document.getElementById('serverstatusquerieschart') !== null) {
var queryPieChart = $('#serverstatusquerieschart').data('queryPieChart');
if (queryPieChart) {
queryPieChart.destroy();
}
}
});
AJAX.registerOnload('server/status/queries.js', function () {
// Build query statistics chart
var cdata = [];
try {
if (document.getElementById('serverstatusquerieschart') !== null) {
$.each($('#serverstatusquerieschart').data('chart'), function (key, value) {
cdata.push([key, parseInt(value, 10)]);
});
$('#serverstatusquerieschart').data('queryPieChart', Functions.createProfilingChart('serverstatusquerieschart', cdata));
}
} catch (exception) {
// Could not load chart, no big deal...
}
initTableSorter('statustabs_queries');
});

View file

@ -1,67 +0,0 @@
// TODO: tablesorter shouldn't sort already sorted columns
// eslint-disable-next-line no-unused-vars
function initTableSorter(tabid) {
var $table;
var opts;
switch (tabid) {
case 'statustabs_queries':
$table = $('#serverStatusQueriesDetails');
opts = {
sortList: [[3, 1]],
headers: {
1: {
sorter: 'fancyNumber'
},
2: {
sorter: 'fancyNumber'
}
}
};
break;
}
$table.tablesorter(opts);
$table.find('tr').first().find('th').append('<div class="sorticon"></div>');
}
$(function () {
$.tablesorter.addParser({
id: 'fancyNumber',
is: function (s) {
return /^[0-9]?[0-9,\\.]*\s?(k|M|G|T|%)?$/.test(s);
},
format: function (s) {
var num = jQuery.tablesorter.formatFloat(s.replace(Messages.strThousandsSeparator, '').replace(Messages.strDecimalSeparator, '.'));
var factor = 1;
switch (s.charAt(s.length - 1)) {
case '%':
factor = -2;
break;
// Todo: Complete this list (as well as in the regexp a few lines up)
case 'k':
factor = 3;
break;
case 'M':
factor = 6;
break;
case 'G':
factor = 9;
break;
case 'T':
factor = 12;
break;
}
return num * Math.pow(10, factor);
},
type: 'numeric'
});
$.tablesorter.addParser({
id: 'withinSpanNumber',
is: function (s) {
return /<span class="original"/.test(s);
},
format: function (s, table, html) {
var res = html.innerHTML.match(/<span(\s*style="display:none;"\s*)?\s*class="original">(.*)?<\/span>/);
return res && res.length >= 3 ? res[2] : 0;
},
type: 'numeric'
});
});

View file

@ -1,89 +0,0 @@
/**
*
*
* @package PhpMyAdmin
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server/status/variables.js', function () {
$('#filterAlert').off('change');
$('#filterText').off('keyup');
$('#filterCategory').off('change');
$('#dontFormat').off('change');
});
AJAX.registerOnload('server/status/variables.js', function () {
// Filters for status variables
var textFilter = null;
var alertFilter = $('#filterAlert').prop('checked');
var categoryFilter = $('#filterCategory').find(':selected').val();
var text = ''; // Holds filter text
/* 3 Filtering functions */
$('#filterAlert').on('change', function () {
alertFilter = this.checked;
filterVariables();
});
$('#filterCategory').on('change', function () {
categoryFilter = $(this).val();
filterVariables();
});
$('#dontFormat').on('change', function () {
// Hiding the table while changing values speeds up the process a lot
const serverStatusVariables = $('#serverStatusVariables');
serverStatusVariables.hide();
serverStatusVariables.find('td.value span.original').toggle(this.checked);
serverStatusVariables.find('td.value span.formatted').toggle(!this.checked);
serverStatusVariables.show();
}).trigger('change');
$('#filterText').on('keyup', function () {
var word = $(this).val().replace(/_/g, ' ');
if (word.length === 0 || word.length >= 32768) {
textFilter = null;
} else {
try {
textFilter = new RegExp('(^| )' + word, 'i');
$(this).removeClass('error');
} catch (e) {
if (e instanceof SyntaxError) {
$(this).addClass('error');
textFilter = null;
}
}
}
text = word;
filterVariables();
}).trigger('keyup');
/* Filters the status variables by name/category/alert in the variables tab */
function filterVariables() {
var usefulLinks = 0;
var section = text;
if (categoryFilter.length > 0) {
section = categoryFilter;
}
if (section.length > 1) {
$('#linkSuggestions').find('span').each(function () {
if ($(this).attr('class').indexOf('status_' + section) !== -1) {
usefulLinks++;
$(this).css('display', '');
} else {
$(this).css('display', 'none');
}
});
}
if (usefulLinks > 0) {
$('#linkSuggestions').css('display', '');
} else {
$('#linkSuggestions').css('display', 'none');
}
$('#serverStatusVariables').find('th.name').each(function () {
if ((textFilter === null || textFilter.exec($(this).text())) && (!alertFilter || $(this).next().find('span.text-danger').length > 0) && (categoryFilter.length === 0 || $(this).parent().hasClass('s_' + categoryFilter))) {
$(this).parent().css('display', '');
} else {
$(this).parent().css('display', 'none');
}
});
}
});

View file

@ -1,35 +0,0 @@
/**
* @fileoverview Javascript functions used in server user groups page
* @name Server User Groups
*
* @requires jQuery
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server/user_groups.js', function () {
$('#deleteUserGroupModal').off('show.bs.modal');
});
/**
* Bind event handlers
*/
AJAX.registerOnload('server/user_groups.js', function () {
const deleteUserGroupModal = $('#deleteUserGroupModal');
deleteUserGroupModal.on('show.bs.modal', function (event) {
const userGroupName = $(event.relatedTarget).data('user-group');
this.querySelector('.modal-body').innerText = Functions.sprintf(Messages.strDropUserGroupWarning, Functions.escapeHtml(userGroupName));
});
deleteUserGroupModal.on('shown.bs.modal', function (event) {
const userGroupName = $(event.relatedTarget).data('user-group');
$('#deleteUserGroupConfirm').on('click', function () {
$.post('index.php?route=/server/user-groups', {
'deleteUserGroup': true,
'userGroup': userGroupName,
'ajax_request': true
}, AJAX.responseHandler);
$('#deleteUserGroupModal').modal('hide');
});
});
});

View file

@ -1,98 +0,0 @@
/**
* @fileoverview Javascript functions used in server variables page
* @name Server Replication
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server/variables.js', function () {
$(document).off('click', 'a.editLink');
$('#serverVariables').find('.var-name').find('a img').remove();
});
AJAX.registerOnload('server/variables.js', function () {
var $saveLink = $('a.saveLink');
var $cancelLink = $('a.cancelLink');
$('#serverVariables').find('.var-name').find('a').append($('#docImage').clone().css('display', 'inline-block'));
/* Launches the variable editor */
$(document).on('click', 'a.editLink', function (event) {
event.preventDefault();
editVariable(this);
});
/* Allows the user to edit a server variable */
function editVariable(link) {
var $link = $(link);
var $cell = $link.parent();
var $valueCell = $link.parents('.var-row').find('.var-value');
var varName = $link.data('variable');
var $mySaveLink = $saveLink.clone().css('display', 'inline-block');
var $myCancelLink = $cancelLink.clone().css('display', 'inline-block');
var $msgbox = Functions.ajaxShowMessage();
var $myEditLink = $cell.find('a.editLink');
$cell.addClass('edit'); // variable is being edited
$myEditLink.remove(); // remove edit link
$mySaveLink.on('click', function () {
var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest);
$.post('index.php?route=/server/variables/set/' + encodeURIComponent(varName), {
'ajax_request': true,
'server': CommonParams.get('server'),
'varValue': $valueCell.find('input').val()
}, function (data) {
if (data.success) {
$valueCell.html(data.variable).data('content', data.variable);
Functions.ajaxRemoveMessage($msgbox);
} else {
if (data.error === '') {
Functions.ajaxShowMessage(Messages.strRequestFailed, false);
} else {
Functions.ajaxShowMessage(data.error, false);
}
$valueCell.html($valueCell.data('content'));
}
$cell.removeClass('edit').html($myEditLink);
});
return false;
});
$myCancelLink.on('click', function () {
$valueCell.html($valueCell.data('content'));
$cell.removeClass('edit').html($myEditLink);
return false;
});
$.get('index.php?route=/server/variables/get/' + encodeURIComponent(varName), {
'ajax_request': true,
'server': CommonParams.get('server')
}, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
var $links = $('<div></div>').append($myCancelLink).append('&nbsp;&nbsp;&nbsp;').append($mySaveLink);
var $editor = $('<div></div>', {
'class': 'serverVariableEditor'
}).append($('<div></div>').append($('<input>', {
type: 'text',
'class': 'form-control form-control-sm'
}).val(data.message)));
// Save and replace content
$cell.html($links).children().css('display', 'flex');
$valueCell.data('content', $valueCell.html()).html($editor).find('input').trigger('focus').on('keydown', function (event) {
// Keyboard shortcuts
if (event.keyCode === 13) {
// Enter key
$mySaveLink.trigger('click');
} else if (event.keyCode === 27) {
// Escape key
$myCancelLink.trigger('click');
}
});
Functions.ajaxRemoveMessage($msgbox);
} else {
$cell.removeClass('edit').html($myEditLink);
Functions.ajaxShowMessage(data.error);
}
});
}
});

View file

@ -1,10 +0,0 @@
/* eslint-disable no-unused-vars */
/**
* Dummy implementation of the ajax page loader
*/
var AJAX = {
registerOnload: function (idx, func) {
$(func);
},
registerTeardown: function (idx, func) {}
};

View file

@ -1,235 +0,0 @@
/**
* Functions used in Setup configuration forms
*/
/* global displayErrors, getAllValues, getIdPrefix, validators */ // js/config.js
// show this window in top frame
if (top !== self) {
window.top.location.href = location;
}
// ------------------------------------------------------------------
// Messages
//
$(function () {
if (window.location.protocol === 'https:') {
$('#no_https').remove();
} else {
$('#no_https a').on('click', function () {
var oldLocation = window.location;
window.location.href = 'https:' + oldLocation.href.substring(oldLocation.protocol.length);
return false;
});
}
var hiddenMessages = $('.hiddenmessage');
if (hiddenMessages.length > 0) {
hiddenMessages.hide();
var link = $('#show_hidden_messages');
link.on('click', function (e) {
e.preventDefault();
hiddenMessages.show();
$(this).remove();
});
link.html(link.html().replace('#MSG_COUNT', hiddenMessages.length));
link.show();
}
});
// set document width
$(function () {
var width = 0;
$('ul.tabs li').each(function () {
width += $(this).width() + 10;
});
var contentWidth = width;
width += 250;
$('body').css('min-width', width);
$('.tabs_contents').css('min-width', contentWidth);
});
//
// END: Messages
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// Form validation and field operations
//
/**
* Calls server-side validation procedures
*
* @param {Element} parent input field in <fieldset> or <fieldset>
* @param {String} id validator id
* @param {object} values values hash {element1_id: value, ...}
*
* @return {bool|void}
*/
function ajaxValidate(parent, id, values) {
var $parent = $(parent);
// ensure that parent is a fieldset
if ($parent.attr('tagName') !== 'FIELDSET') {
$parent = $parent.closest('fieldset');
if ($parent.length === 0) {
return false;
}
}
if ($parent.data('ajax') !== null) {
$parent.data('ajax').abort();
}
$parent.data('ajax', $.ajax({
url: 'validate.php',
cache: false,
type: 'POST',
data: {
token: $parent.closest('form').find('input[name=token]').val(),
id: id,
values: JSON.stringify(values)
},
success: function (response) {
if (response === null) {
return;
}
var error = {};
if (typeof response !== 'object') {
error[$parent.id] = [response];
} else if (typeof response.error !== 'undefined') {
error[$parent.id] = [response.error];
} else {
for (var key in response) {
var value = response[key];
error[key] = Array.isArray(value) ? value : [value];
}
}
displayErrors(error);
},
complete: function () {
$parent.removeData('ajax');
}
}));
return true;
}
/**
* Automatic form submission on change.
*/
$(document).on('change', '.autosubmit', function (e) {
e.target.form.submit();
});
$.extend(true, validators, {
// field validators
field: {
/**
* hide_db field
*
* @param {boolean} isKeyUp
*
* @return {true}
*/
hide_db: function (isKeyUp) {
// eslint-disable-line camelcase
if (!isKeyUp && this.value !== '') {
var data = {};
data[this.id] = this.value;
ajaxValidate(this, 'Servers/1/hide_db', data);
}
return true;
},
/**
* TrustedProxies field
*
* @param {boolean} isKeyUp
*
* @return {true}
*/
TrustedProxies: function (isKeyUp) {
if (!isKeyUp && this.value !== '') {
var data = {};
data[this.id] = this.value;
ajaxValidate(this, 'TrustedProxies', data);
}
return true;
}
},
// fieldset validators
fieldset: {
/**
* Validates Server fieldset
*
* @param {boolean} isKeyUp
*
* @return {true}
*/
Server: function (isKeyUp) {
if (!isKeyUp) {
ajaxValidate(this, 'Server', getAllValues());
}
return true;
},
/**
* Validates Server_login_options fieldset
*
* @param {boolean} isKeyUp
*
* @return {true}
*/
Server_login_options: function (isKeyUp) {
// eslint-disable-line camelcase
return validators.fieldset.Server.apply(this, [isKeyUp]);
},
/**
* Validates Server_pmadb fieldset
*
* @param {boolean} isKeyUp
*
* @return {true}
*/
Server_pmadb: function (isKeyUp) {
// eslint-disable-line camelcase
if (isKeyUp) {
return true;
}
var prefix = getIdPrefix($(this).find('input'));
if ($('#' + prefix + 'pmadb').val() !== '') {
ajaxValidate(this, 'Server_pmadb', getAllValues());
}
return true;
}
}
});
//
// END: Form validation and field operations
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// User preferences allow/disallow UI
//
$(function () {
$('.userprefs-allow').on('click', function (e) {
if (this !== e.target) {
return;
}
var el = $(this).find('input');
if (el.prop('disabled')) {
return;
}
el.prop('checked', !el.prop('checked'));
});
});
//
// END: User preferences allow/disallow UI
// ------------------------------------------------------------------
$(function () {
$('.delete-server').on('click', function (e) {
e.preventDefault();
var $this = $(this);
$.post($this.attr('href'), $this.attr('data-post'), function () {
window.location.replace('index.php');
});
});
});

View file

@ -1,111 +0,0 @@
/**
* @fileoverview Handle shortcuts in various pages
* @name Shortcuts handler
*
* @requires jQuery
* @requires jQueryUI
*/
/* global Console */ // js/console.js
/**
* Register key events on load
*/
$(function () {
var databaseOp = false;
var tableOp = false;
var keyD = 68;
var keyT = 84;
var keyK = 75;
var keyS = 83;
var keyF = 70;
var keyE = 69;
var keyH = 72;
var keyC = 67;
var keyBackSpace = 8;
$(document).on('keyup', function (e) {
// is a string but is also a boolean according to https://api.jquery.com/prop/
if ($(e.target).prop('contenteditable') === 'true' || $(e.target).prop('contenteditable') === true) {
return;
}
if (e.target.nodeName === 'INPUT' || e.target.nodeName === 'TEXTAREA' || e.target.nodeName === 'SELECT') {
return;
}
if (e.keyCode === keyD) {
setTimeout(function () {
databaseOp = false;
}, 2000);
} else if (e.keyCode === keyT) {
setTimeout(function () {
tableOp = false;
}, 2000);
}
});
$(document).on('keydown', function (e) {
// is a string but is also a boolean according to https://api.jquery.com/prop/
if ($(e.target).prop('contenteditable') === 'true' || $(e.target).prop('contenteditable') === true) {
return;
}
// disable the shortcuts when session has timed out.
if ($('#modalOverlay').length > 0) {
return;
}
if (e.ctrlKey && e.altKey && e.keyCode === keyC) {
Console.toggle();
}
if (e.ctrlKey && e.keyCode === keyK) {
e.preventDefault();
Console.toggle();
}
if (e.target.nodeName === 'INPUT' || e.target.nodeName === 'TEXTAREA' || e.target.nodeName === 'SELECT') {
return;
}
var isTable;
var isDb;
if (e.keyCode === keyD) {
databaseOp = true;
} else if (e.keyCode === keyK) {
e.preventDefault();
Console.toggle();
} else if (e.keyCode === keyS) {
if (databaseOp === true) {
isTable = CommonParams.get('table');
isDb = CommonParams.get('db');
if (isDb && !isTable) {
$('.nav-link .ic_b_props').first().trigger('click');
}
} else if (tableOp === true) {
isTable = CommonParams.get('table');
isDb = CommonParams.get('db');
if (isDb && isTable) {
$('.nav-link .ic_b_props').first().trigger('click');
}
} else {
$('#pma_navigation_settings_icon').trigger('click');
}
} else if (e.keyCode === keyF) {
if (databaseOp === true) {
isTable = CommonParams.get('table');
isDb = CommonParams.get('db');
if (isDb && !isTable) {
$('.nav-link .ic_b_search').first().trigger('click');
}
} else if (tableOp === true) {
isTable = CommonParams.get('table');
isDb = CommonParams.get('db');
if (isDb && isTable) {
$('.nav-link .ic_b_search').first().trigger('click');
}
}
} else if (e.keyCode === keyT) {
tableOp = true;
} else if (e.keyCode === keyE) {
$('.ic_b_export').first().trigger('click');
} else if (e.keyCode === keyBackSpace) {
window.history.back();
} else if (e.keyCode === keyH) {
$('.ic_b_home').first().trigger('click');
}
});
});

File diff suppressed because it is too large Load diff

View file

@ -1,767 +0,0 @@
/**
* @fileoverview function used in table data manipulation pages
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/* global extendingValidatorMessages */ // templates/javascript/variables.twig
/* global openGISEditor, gisEditorLoaded, loadJSAndGISEditor, loadGISEditor */ // js/gis_data_editor.js
/**
* Modify form controls when the "NULL" checkbox is checked
*
* @param {string} theType the MySQL field type
* @param {string} urlField the urlencoded field name - OBSOLETE
* @param {string} md5Field the md5 hashed field name
* @param {string} multiEdit the multi_edit row sequence number
*
* @return {boolean} always true
*/
function nullify(theType, urlField, md5Field, multiEdit) {
var rowForm = document.forms.insertForm;
if (typeof rowForm.elements['funcs' + multiEdit + '[' + md5Field + ']'] !== 'undefined') {
rowForm.elements['funcs' + multiEdit + '[' + md5Field + ']'].selectedIndex = -1;
}
// "ENUM" field with more than 20 characters
if (Number(theType) === 1) {
rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'][1].selectedIndex = -1;
// Other "ENUM" field
} else if (Number(theType) === 2) {
var elts = rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'];
// when there is just one option in ENUM:
if (elts.checked) {
elts.checked = false;
} else {
var eltsCnt = elts.length;
for (var i = 0; i < eltsCnt; i++) {
elts[i].checked = false;
} // end for
} // end if
// "SET" field
} else if (Number(theType) === 3) {
rowForm.elements['fields' + multiEdit + '[' + md5Field + '][]'].selectedIndex = -1;
// Foreign key field (drop-down)
} else if (Number(theType) === 4) {
rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].selectedIndex = -1;
// foreign key field (with browsing icon for foreign values)
} else if (Number(theType) === 6) {
rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].value = '';
// Other field types
} else /* if (theType === 5)*/{
rowForm.elements['fields' + multiEdit + '[' + md5Field + ']'].value = '';
} // end if... else if... else
return true;
} // end of the 'nullify()' function
/**
* javascript DateTime format validation.
* its used to prevent adding default (0000-00-00 00:00:00) to database when user enter wrong values
* Start of validation part
*/
// function checks the number of days in febuary
function daysInFebruary(year) {
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0) ? 29 : 28;
}
// function to convert single digit to double digit
function fractionReplace(number) {
var num = parseInt(number, 10);
return num >= 1 && num <= 9 ? '0' + num : '00';
}
/* function to check the validity of date
* The following patterns are accepted in this validation (accepted in mysql as well)
* 1) 2001-12-23
* 2) 2001-1-2
* 3) 02-12-23
* 4) And instead of using '-' the following punctuations can be used (+,.,*,^,@,/) All these are accepted by mysql as well. Therefore no issues
*/
function isDate(val, tmstmp) {
var value = val.replace(/[.|*|^|+|//|@]/g, '-');
var arrayVal = value.split('-');
for (var a = 0; a < arrayVal.length; a++) {
if (arrayVal[a].length === 1) {
arrayVal[a] = fractionReplace(arrayVal[a]);
}
}
value = arrayVal.join('-');
var pos = 2;
var dtexp = new RegExp(/^([0-9]{4})-(((01|03|05|07|08|10|12)-((0[0-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)-((0[0-9])|([1-2][0-9])|30))|((00)-(00)))$/);
if (value.length === 8) {
pos = 0;
}
if (dtexp.test(value)) {
var month = parseInt(value.substring(pos + 3, pos + 5), 10);
var day = parseInt(value.substring(pos + 6, pos + 8), 10);
var year = parseInt(value.substring(0, pos + 2), 10);
if (month === 2 && day > daysInFebruary(year)) {
return false;
}
if (value.substring(0, pos + 2).length === 2) {
year = parseInt('20' + value.substring(0, pos + 2), 10);
}
if (tmstmp === true) {
if (year < 1978) {
return false;
}
if (year > 2038 || year > 2037 && day > 19 && month >= 1 || year > 2037 && month > 1) {
return false;
}
}
} else {
return false;
}
return true;
}
/* function to check the validity of time
* The following patterns are accepted in this validation (accepted in mysql as well)
* 1) 2:3:4
* 2) 2:23:43
* 3) 2:23:43.123456
*/
function isTime(val) {
var arrayVal = val.split(':');
for (var a = 0, l = arrayVal.length; a < l; a++) {
if (arrayVal[a].length === 1) {
arrayVal[a] = fractionReplace(arrayVal[a]);
}
}
var newVal = arrayVal.join(':');
var tmexp = new RegExp(/^(-)?(([0-7]?[0-9][0-9])|(8[0-2][0-9])|(83[0-8])):((0[0-9])|([1-5][0-9])):((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$/);
return tmexp.test(newVal);
}
/**
* To check whether insert section is ignored or not
* @param {string} multiEdit
* @return {boolean}
*/
function checkForCheckbox(multiEdit) {
if ($('#insert_ignore_' + multiEdit).length) {
return $('#insert_ignore_' + multiEdit).is(':unchecked');
}
return true;
}
// used in Search page mostly for INT fields
// eslint-disable-next-line no-unused-vars
function verifyAfterSearchFieldChange(index, searchFormId) {
var $thisInput = $('input[name=\'criteriaValues[' + index + ']\']');
// Add data-skip-validators attribute to skip validation in changeValueFieldType function
if ($('#fieldID_' + index).data('data-skip-validators')) {
$(searchFormId).validate().destroy();
return;
}
// validation for integer type
if ($thisInput.data('type') === 'INT' || $thisInput.data('type') === 'TINYINT') {
// Trim spaces if it's an integer
$thisInput.val($thisInput.val().trim());
var hasMultiple = $thisInput.prop('multiple');
if (hasMultiple) {
$(searchFormId).validate({
// update errors as we write
onkeyup: function (element) {
$(element).valid();
}
});
// validator method for IN(...), NOT IN(...)
// BETWEEN and NOT BETWEEN
jQuery.validator.addMethod('validationFunctionForMultipleInt', function (value) {
return value.match(/^(?:(?:\d\s*)|\s*)+(?:,\s*\d+)*$/i) !== null;
}, Messages.strEnterValidNumber);
validateMultipleIntField($thisInput, true);
} else {
$(searchFormId).validate({
// update errors as we write
onkeyup: function (element) {
$(element).valid();
}
});
validateIntField($thisInput, true);
}
// Update error on dropdown change
$thisInput.valid();
}
}
/**
* Validate the an input contains multiple int values
* @param {jQuery} jqueryInput the Jquery object
* @param {boolean} returnValueIfFine the value to return if the validator passes
* @return {void}
*/
function validateMultipleIntField(jqueryInput, returnValueIfFine) {
// removing previous rules
jqueryInput.rules('remove');
jqueryInput.rules('add', {
validationFunctionForMultipleInt: {
param: jqueryInput.value,
depends: function () {
return returnValueIfFine;
}
}
});
}
/**
* Validate the an input contains an int value
* @param {jQuery} jqueryInput the Jquery object
* @param {boolean} returnValueIfIsNumber the value to return if the validator passes
* @return {void}
*/
function validateIntField(jqueryInput, returnValueIfIsNumber) {
var mini = parseInt(jqueryInput.data('min'));
var maxi = parseInt(jqueryInput.data('max'));
// removing previous rules
jqueryInput.rules('remove');
jqueryInput.rules('add', {
number: {
param: true,
depends: function () {
return returnValueIfIsNumber;
}
},
min: {
param: mini,
depends: function () {
if (isNaN(jqueryInput.val())) {
return false;
} else {
return returnValueIfIsNumber;
}
}
},
max: {
param: maxi,
depends: function () {
if (isNaN(jqueryInput.val())) {
return false;
} else {
return returnValueIfIsNumber;
}
}
}
});
}
function verificationsAfterFieldChange(urlField, multiEdit, theType) {
var evt = window.event || arguments.callee.caller.arguments[0];
var target = evt.target || evt.srcElement;
var $thisInput = $(':input[name^=\'fields[multi_edit][' + multiEdit + '][' + urlField + ']\']');
// the function drop-down that corresponds to this input field
var $thisFunction = $('select[name=\'funcs[multi_edit][' + multiEdit + '][' + urlField + ']\']');
var functionSelected = false;
if (typeof $thisFunction.val() !== 'undefined' && $thisFunction.val() !== null && $thisFunction.val().length > 0) {
functionSelected = true;
}
// To generate the textbox that can take the salt
var newSaltBox = '<br><input type=text name=salt[multi_edit][' + multiEdit + '][' + urlField + ']' + ' id=salt_' + target.id + ' placeholder=\'' + Messages.strEncryptionKey + '\'>';
// If encrypting or decrypting functions that take salt as input is selected append the new textbox for salt
if (target.value === 'AES_ENCRYPT' || target.value === 'AES_DECRYPT' || target.value === 'DES_ENCRYPT' || target.value === 'DES_DECRYPT' || target.value === 'ENCRYPT') {
if (!$('#salt_' + target.id).length) {
$thisInput.after(newSaltBox);
}
} else {
// Remove the textbox for salt
$('#salt_' + target.id).prev('br').remove();
$('#salt_' + target.id).remove();
}
// Remove possible blocking rules if the user changed functions
$('#' + target.id).rules('remove', 'validationFunctionForMd5');
$('#' + target.id).rules('remove', 'validationFunctionForAesDesEncrypt');
if (target.value === 'MD5') {
$('#' + target.id).rules('add', {
validationFunctionForMd5: {
param: $thisInput,
depends: function () {
return checkForCheckbox(multiEdit);
}
}
});
}
if (target.value === 'DES_ENCRYPT' || target.value === 'AES_ENCRYPT') {
$('#' + target.id).rules('add', {
validationFunctionForAesDesEncrypt: {
param: $thisInput,
depends: function () {
return checkForCheckbox(multiEdit);
}
}
});
}
if (target.value === 'HEX' && theType.substring(0, 3) === 'int') {
// Add note when HEX function is selected on a int
var newHexInfo = '<br><p id="note' + target.id + '">' + Messages.HexConversionInfo + '</p>';
if (!$('#note' + target.id).length) {
$thisInput.after(newHexInfo);
}
} else {
$('#note' + target.id).prev('br').remove();
$('#note' + target.id).remove();
}
// Unchecks the corresponding "NULL" control
$('input[name=\'fields_null[multi_edit][' + multiEdit + '][' + urlField + ']\']').prop('checked', false);
// Unchecks the Ignore checkbox for the current row
$('input[name=\'insert_ignore_' + multiEdit + '\']').prop('checked', false);
var charExceptionHandling;
if (theType.substring(0, 4) === 'char') {
charExceptionHandling = theType.substring(5, 6);
} else if (theType.substring(0, 7) === 'varchar') {
charExceptionHandling = theType.substring(8, 9);
}
if (functionSelected) {
$thisInput.removeAttr('min');
$thisInput.removeAttr('max');
// @todo: put back attributes if corresponding function is deselected
}
if ($thisInput.data('rulesadded') === null && !functionSelected) {
// call validate before adding rules
$($thisInput[0].form).validate();
// validate for date time
if (theType === 'datetime' || theType === 'time' || theType === 'date' || theType === 'timestamp') {
$thisInput.rules('add', {
validationFunctionForDateTime: {
param: theType,
depends: function () {
return checkForCheckbox(multiEdit);
}
}
});
}
// validation for integer type
if ($thisInput.data('type') === 'INT') {
validateIntField($thisInput, checkForCheckbox(multiEdit));
// validation for CHAR types
} else if ($thisInput.data('type') === 'CHAR') {
var maxlen = $thisInput.data('maxlength');
if (typeof maxlen !== 'undefined') {
if (maxlen <= 4) {
maxlen = charExceptionHandling;
}
$thisInput.rules('add', {
maxlength: {
param: maxlen,
depends: function () {
return checkForCheckbox(multiEdit);
}
}
});
}
// validate binary & blob types
} else if ($thisInput.data('type') === 'HEX') {
$thisInput.rules('add', {
validationFunctionForHex: {
param: true,
depends: function () {
return checkForCheckbox(multiEdit);
}
}
});
}
$thisInput.data('rulesadded', true);
} else if ($thisInput.data('rulesadded') === true && functionSelected) {
// remove any rules added
$thisInput.rules('remove');
// remove any error messages
$thisInput.removeClass('error').removeAttr('aria-invalid').siblings('.error').remove();
$thisInput.data('rulesadded', null);
}
}
/* End of fields validation*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('table/change.js', function () {
$(document).off('click', 'span.open_gis_editor');
$(document).off('click', 'input[name^=\'insert_ignore_\']');
$(document).off('click', 'input[name=\'gis_data[save]\']');
$(document).off('click', 'input.checkbox_null');
$('select[name="submit_type"]').off('change');
$(document).off('change', '#insert_rows');
});
/**
* Ajax handlers for Change Table page
*
* Actions Ajaxified here:
* Submit Data to be inserted into the table.
* Restart insertion with 'N' rows.
*/
AJAX.registerOnload('table/change.js', function () {
if ($('#insertForm').length) {
// validate the comment form when it is submitted
$('#insertForm').validate();
jQuery.validator.addMethod('validationFunctionForHex', function (value) {
return value.match(/^[a-f0-9]*$/i) !== null;
});
jQuery.validator.addMethod('validationFunctionForMd5', function (value, element, options) {
return !(value.substring(0, 3) === 'MD5' && typeof options.data('maxlength') !== 'undefined' && options.data('maxlength') < 32);
});
jQuery.validator.addMethod('validationFunctionForAesDesEncrypt', function (value, element, options) {
var funType = value.substring(0, 3);
if (funType !== 'AES' && funType !== 'DES') {
return false;
}
var dataType = options.data('type');
if (dataType === 'HEX' || dataType === 'CHAR') {
return true;
}
return false;
});
jQuery.validator.addMethod('validationFunctionForDateTime', function (value, element, options) {
var dtValue = value;
var theType = options;
if (theType === 'date') {
return isDate(dtValue);
} else if (theType === 'time') {
return isTime(dtValue);
} else if (theType === 'datetime' || theType === 'timestamp') {
var tmstmp = false;
dtValue = dtValue.trim();
if (dtValue === 'CURRENT_TIMESTAMP' || dtValue === 'current_timestamp()') {
return true;
}
if (theType === 'timestamp') {
tmstmp = true;
}
if (dtValue === '0000-00-00 00:00:00') {
return true;
}
var dv = dtValue.indexOf(' ');
if (dv === -1) {
// Only the date component, which is valid
return isDate(dtValue, tmstmp);
}
return isDate(dtValue.substring(0, dv), tmstmp) && isTime(dtValue.substring(dv + 1));
}
});
}
/*
* message extending script must be run
* after initiation of functions
*/
extendingValidatorMessages();
$.datepicker.initialized = false;
$(document).on('click', 'span.open_gis_editor', function (event) {
event.preventDefault();
var $span = $(this);
// Current value
var value = $span.parent('td').children('input[type=\'text\']').val();
// Field name
var field = $span.parents('tr').children('td').first().find('input[type=\'hidden\']').val();
// Column type
var type = $span.parents('tr').find('span.column_type').text();
// Names of input field and null checkbox
var inputName = $span.parent('td').children('input[type=\'text\']').attr('name');
openGISEditor();
if (!gisEditorLoaded) {
loadJSAndGISEditor(value, field, type, inputName);
} else {
loadGISEditor(value, field, type, inputName);
}
});
/**
* Forced validation check of fields
*/
$(document).on('click', 'input[name^=\'insert_ignore_\']', function () {
$('#insertForm').valid();
});
/**
* Uncheck the null checkbox as geometry data is placed on the input field
*/
$(document).on('click', 'input[name=\'gis_data[save]\']', function () {
var inputName = $('form#gis_data_editor_form').find('input[name=\'input_name\']').val();
var currentRow = $('input[name=\'' + inputName + '\']').parents('tr');
var $nullCheckbox = currentRow.find('.checkbox_null');
$nullCheckbox.prop('checked', false);
var rowId = currentRow.find('.open_gis_editor').data('row-id');
// Unchecks the Ignore checkbox for the current row
$('input[name=\'insert_ignore_' + rowId + '\']').prop('checked', false);
});
/**
* Handles all current checkboxes for Null; this only takes care of the
* checkboxes on currently displayed rows as the rows generated by
* "Continue insertion" are handled in the "Continue insertion" code
*
*/
$(document).on('click', 'input.checkbox_null', function () {
nullify(
// use hidden fields populated by /table/change
$(this).siblings('.nullify_code').val(), $(this).closest('tr').find('input:hidden').first().val(), $(this).siblings('.hashed_field').val(), $(this).siblings('.multi_edit').val());
});
/**
* Reset the auto_increment column to 0 when selecting any of the
* insert options in submit_type-dropdown. Only perform the reset
* when we are in edit-mode, and not in insert-mode(no previous value
* available).
*/
$('select[name="submit_type"]').on('change', function () {
var thisElemSubmitTypeVal = $(this).val();
var $table = $('table.insertRowTable');
var autoIncrementColumn = $table.find('input[name^="auto_increment"]');
autoIncrementColumn.each(function () {
var $thisElemAIField = $(this);
var thisElemName = $thisElemAIField.attr('name');
var prevValueField = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields_prev') + '"]');
var valueField = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields') + '"]');
var previousValue = $(prevValueField).val();
if (previousValue !== undefined) {
if (thisElemSubmitTypeVal === 'insert' || thisElemSubmitTypeVal === 'insertignore' || thisElemSubmitTypeVal === 'showinsert') {
$(valueField).val(null);
} else {
$(valueField).val(previousValue);
}
}
});
});
/**
* Handle ENTER key when press on Continue insert with field
*/
$('#insert_rows').on('keypress', function (e) {
var key = e.which;
if (key === 13) {
addNewContinueInsertionFields(e);
}
});
/**
* Continue Insertion form
*/
$(document).on('change', '#insert_rows', addNewContinueInsertionFields);
});
function addNewContinueInsertionFields(event) {
event.preventDefault();
/**
* @var columnCount Number of number of columns table has.
*/
var columnCount = $('table.insertRowTable').first().find('tr').has('input[name*=\'fields_name\']').length;
/**
* @var curr_rows Number of current insert rows already on page
*/
var currRows = $('table.insertRowTable').length;
/**
* @var target_rows Number of rows the user wants
*/
var targetRows = $('#insert_rows').val();
// remove all datepickers
$('input.datefield, input.datetimefield').each(function () {
$(this).datepicker('destroy');
});
if (currRows < targetRows) {
var tempIncrementIndex = function () {
var $thisElement = $(this);
/**
* Extract the index from the name attribute for all input/select fields and increment it
* name is of format funcs[multi_edit][10][<long random string of alphanum chars>]
*/
/**
* @var this_name String containing name of the input/select elements
*/
var thisName = $thisElement.attr('name');
/** split {@link thisName} at [10], so we have the parts that can be concatenated later */
var nameParts = thisName.split(/\[\d+\]/);
/** extract the [10] from {@link nameParts} */
var oldRowIndexString = thisName.match(/\[\d+\]/)[0];
/** extract 10 - had to split into two steps to accomodate double digits */
var oldRowIndex = parseInt(oldRowIndexString.match(/\d+/)[0], 10);
/** calculate next index i.e. 11 */
newRowIndex = oldRowIndex + 1;
/** generate the new name i.e. funcs[multi_edit][11][foobarbaz] */
var newName = nameParts[0] + '[' + newRowIndex + ']' + nameParts[1];
var hashedField = nameParts[1].match(/\[(.+)\]/)[1];
$thisElement.attr('name', newName);
/** If element is select[name*='funcs'], update id */
if ($thisElement.is('select[name*=\'funcs\']')) {
var thisId = $thisElement.attr('id');
var idParts = thisId.split(/_/);
var oldIdIndex = idParts[1];
var prevSelectedValue = $('#field_' + oldIdIndex + '_1').val();
var newIdIndex = parseInt(oldIdIndex) + columnCount;
var newId = 'field_' + newIdIndex + '_1';
$thisElement.attr('id', newId);
$thisElement.find('option').filter(function () {
return $(this).text() === prevSelectedValue;
}).attr('selected', 'selected');
// If salt field is there then update its id.
var nextSaltInput = $thisElement.parent().next('td').next('td').find('input[name*=\'salt\']');
if (nextSaltInput.length !== 0) {
nextSaltInput.attr('id', 'salt_' + newId);
}
}
// handle input text fields and textareas
if ($thisElement.is('.textfield') || $thisElement.is('.char') || $thisElement.is('textarea')) {
// do not remove the 'value' attribute for ENUM columns
// special handling for radio fields after updating ids to unique - see below
if ($thisElement.closest('tr').find('span.column_type').html() !== 'enum') {
$thisElement.val($thisElement.closest('tr').find('span.default_value').html());
}
$thisElement.off('change')
// Remove onchange attribute that was placed
// by /table/change; it refers to the wrong row index
.attr('onchange', null)
// Keep these values to be used when the element
// will change
.data('hashed_field', hashedField).data('new_row_index', newRowIndex).on('change', function () {
var $changedElement = $(this);
verificationsAfterFieldChange($changedElement.data('hashed_field'), $changedElement.data('new_row_index'), $changedElement.closest('tr').find('span.column_type').html());
});
}
if ($thisElement.is('.checkbox_null')) {
$thisElement
// this event was bound earlier by jQuery but
// to the original row, not the cloned one, so unbind()
.off('click')
// Keep these values to be used when the element
// will be clicked
.data('hashed_field', hashedField).data('new_row_index', newRowIndex).on('click', function () {
var $changedElement = $(this);
nullify($changedElement.siblings('.nullify_code').val(), $thisElement.closest('tr').find('input:hidden').first().val(), $changedElement.data('hashed_field'), '[multi_edit][' + $changedElement.data('new_row_index') + ']');
});
}
};
var tempReplaceAnchor = function () {
var $anchor = $(this);
var newValue = 'rownumber=' + newRowIndex;
// needs improvement in case something else inside
// the href contains this pattern
var newHref = $anchor.attr('href').replace(/rownumber=\d+/, newValue);
$anchor.attr('href', newHref);
};
var restoreValue = function () {
if ($(this).closest('tr').find('span.column_type').html() === 'enum') {
if ($(this).val() === $checkedValue) {
$(this).prop('checked', true);
} else {
$(this).prop('checked', false);
}
}
};
while (currRows < targetRows) {
/**
* @var $last_row Object referring to the last row
*/
var $lastRow = $('#insertForm').find('.insertRowTable').last();
// need to access this at more than one level
// (also needs improvement because it should be calculated
// just once per cloned row, not once per column)
var newRowIndex = 0;
var $checkedValue = $lastRow.find('input:checked').val();
// Clone the insert tables
$lastRow.clone(true, true).insertBefore('#actions_panel').find('input[name*=multi_edit],select[name*=multi_edit],textarea[name*=multi_edit]').each(tempIncrementIndex).end().find('.foreign_values_anchor').each(tempReplaceAnchor);
var $oldRow = $lastRow.find('.textfield');
$oldRow.each(restoreValue);
// set the value of enum field of new row to default
var $newRow = $('#insertForm').find('.insertRowTable').last();
$newRow.find('.textfield').each(function () {
if ($(this).closest('tr').find('span.column_type').html() === 'enum') {
if ($(this).val() === $(this).closest('tr').find('span.default_value').html()) {
$(this).prop('checked', true);
} else {
$(this).prop('checked', false);
}
}
});
// Insert/Clone the ignore checkboxes
if (currRows === 1) {
$('<input id="insert_ignore_1" type="checkbox" name="insert_ignore_1" checked="checked">').insertBefore($('table.insertRowTable').last()).after('<label for="insert_ignore_1">' + Messages.strIgnore + '</label>');
} else {
/**
* @var $last_checkbox Object reference to the last checkbox in #insertForm
*/
var $lastCheckbox = $('#insertForm').children('input:checkbox').last();
/** name of {@link $lastCheckbox} */
var lastCheckboxName = $lastCheckbox.attr('name');
/** index of {@link $lastCheckbox} */
var lastCheckboxIndex = parseInt(lastCheckboxName.match(/\d+/), 10);
/** name of new {@link $lastCheckbox} */
var newName = lastCheckboxName.replace(/\d+/, lastCheckboxIndex + 1);
$('<br><div class="clearfloat"></div>').insertBefore($('table.insertRowTable').last());
$lastCheckbox.clone().attr({
'id': newName,
'name': newName
}).prop('checked', true).insertBefore($('table.insertRowTable').last());
$('label[for^=insert_ignore]').last().clone().attr('for', newName).insertBefore($('table.insertRowTable').last());
$('<br>').insertBefore($('table.insertRowTable').last());
}
currRows++;
}
// recompute tabindex for text fields and other controls at footer;
// IMO it's not really important to handle the tabindex for
// function and Null
var tabIndex = 0;
$('.textfield, .char, textarea').each(function () {
tabIndex++;
$(this).attr('tabindex', tabIndex);
// update the IDs of textfields to ensure that they are unique
$(this).attr('id', 'field_' + tabIndex + '_3');
});
$('.control_at_footer').each(function () {
tabIndex++;
$(this).attr('tabindex', tabIndex);
});
} else if (currRows > targetRows) {
/**
* Displays alert if data loss possible on decrease
* of rows.
*/
var checkLock = jQuery.isEmptyObject(AJAX.lockedTargets);
if (checkLock || confirm(Messages.strConfirmRowChange) === true) {
while (currRows > targetRows) {
$('input[id^=insert_ignore]').last().nextUntil('fieldset').addBack().remove();
currRows--;
}
} else {
document.getElementById('insert_rows').value = currRows;
}
}
// Add all the required datepickers back
Functions.addDateTimePicker();
}
// eslint-disable-next-line no-unused-vars
function changeValueFieldType(elem, searchIndex) {
var fieldsValue = $('input#fieldID_' + searchIndex);
if (0 === fieldsValue.size()) {
return;
}
var type = $(elem).val();
if ('LIKE' === type || 'LIKE %...%' === type || 'NOT LIKE' === type || 'NOT LIKE %...%' === type) {
$('#fieldID_' + searchIndex).data('data-skip-validators', true);
return;
} else {
$('#fieldID_' + searchIndex).data('data-skip-validators', false);
}
if ('IN (...)' === type || 'NOT IN (...)' === type || 'BETWEEN' === type || 'NOT BETWEEN' === type) {
$('#fieldID_' + searchIndex).prop('multiple', true);
} else {
$('#fieldID_' + searchIndex).prop('multiple', false);
}
}

View file

@ -1,403 +0,0 @@
/* global ColumnType, DataTable, JQPlotChartFactory */ // js/chart.js
/* global codeMirrorEditor */ // js/functions.js
var chartData = {};
var tempChartTitle;
var currentChart = null;
var currentSettings = null;
var dateTimeCols = [];
var numericCols = [];
function extractDate(dateString) {
var matches;
var match;
var dateTimeRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/;
var dateRegExp = /[0-9]{4}-[0-9]{2}-[0-9]{2}/;
matches = dateTimeRegExp.exec(dateString);
if (matches !== null && matches.length > 0) {
match = matches[0];
return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2), match.substr(11, 2), match.substr(14, 2), match.substr(17, 2));
} else {
matches = dateRegExp.exec(dateString);
if (matches !== null && matches.length > 0) {
match = matches[0];
return new Date(match.substr(0, 4), parseInt(match.substr(5, 2), 10) - 1, match.substr(8, 2));
}
}
return null;
}
function queryChart(data, columnNames, settings) {
if ($('#querychart').length === 0) {
return;
}
var plotSettings = {
title: {
text: settings.title,
escapeHtml: true
},
grid: {
drawBorder: false,
shadow: false,
background: 'rgba(0,0,0,0)'
},
legend: {
show: true,
placement: 'outsideGrid',
location: 'e',
rendererOptions: {
numberColumns: 2
}
},
axes: {
xaxis: {
label: Functions.escapeHtml(settings.xaxisLabel)
},
yaxis: {
label: settings.yaxisLabel
}
},
stackSeries: settings.stackSeries
};
// create the chart
var factory = new JQPlotChartFactory();
var chart = factory.createChart(settings.type, 'querychart');
// create the data table and add columns
var dataTable = new DataTable();
if (settings.type === 'timeline') {
dataTable.addColumn(ColumnType.DATE, columnNames[settings.mainAxis]);
} else if (settings.type === 'scatter') {
dataTable.addColumn(ColumnType.NUMBER, columnNames[settings.mainAxis]);
} else {
dataTable.addColumn(ColumnType.STRING, columnNames[settings.mainAxis]);
}
var i;
var values = [];
if (settings.seriesColumn === null) {
$.each(settings.selectedSeries, function (index, element) {
dataTable.addColumn(ColumnType.NUMBER, columnNames[element]);
});
// set data to the data table
var columnsToExtract = [settings.mainAxis];
$.each(settings.selectedSeries, function (index, element) {
columnsToExtract.push(element);
});
var newRow;
var row;
var col;
for (i = 0; i < data.length; i++) {
row = data[i];
newRow = [];
for (var j = 0; j < columnsToExtract.length; j++) {
col = columnNames[columnsToExtract[j]];
if (j === 0) {
if (settings.type === 'timeline') {
// first column is date type
newRow.push(extractDate(row[col]));
} else if (settings.type === 'scatter') {
newRow.push(parseFloat(row[col]));
} else {
// first column is string type
newRow.push(row[col]);
}
} else {
// subsequent columns are of type, number
newRow.push(parseFloat(row[col]));
}
}
values.push(newRow);
}
dataTable.setData(values);
} else {
var seriesNames = {};
var seriesNumber = 1;
var seriesColumnName = columnNames[settings.seriesColumn];
for (i = 0; i < data.length; i++) {
if (!seriesNames[data[i][seriesColumnName]]) {
seriesNames[data[i][seriesColumnName]] = seriesNumber;
seriesNumber++;
}
}
$.each(seriesNames, function (seriesName) {
dataTable.addColumn(ColumnType.NUMBER, seriesName);
});
var valueMap = {};
var xValue;
var value;
var mainAxisName = columnNames[settings.mainAxis];
var valueColumnName = columnNames[settings.valueColumn];
for (i = 0; i < data.length; i++) {
xValue = data[i][mainAxisName];
value = valueMap[xValue];
if (!value) {
value = [xValue];
valueMap[xValue] = value;
}
seriesNumber = seriesNames[data[i][seriesColumnName]];
value[seriesNumber] = parseFloat(data[i][valueColumnName]);
}
$.each(valueMap, function (index, value) {
values.push(value);
});
dataTable.setData(values);
}
// draw the chart and return the chart object
chart.draw(dataTable, plotSettings);
return chart;
}
function drawChart() {
currentSettings.width = $('#resizer').width() - 20;
currentSettings.height = $('#resizer').height() - 20;
// TODO: a better way using .redraw() ?
if (currentChart !== null) {
currentChart.destroy();
}
var columnNames = [];
$('#chartXAxisSelect option').each(function () {
columnNames.push(Functions.escapeHtml($(this).text()));
});
try {
currentChart = queryChart(chartData, columnNames, currentSettings);
if (currentChart !== null) {
$('#saveChart').attr('href', currentChart.toImageString());
}
} catch (err) {
Functions.ajaxShowMessage(err.message, false);
}
}
function getSelectedSeries() {
var val = $('#chartSeriesSelect').val() || [];
var ret = [];
$.each(val, function (i, v) {
ret.push(parseInt(v, 10));
});
return ret;
}
function onXAxisChange() {
var $xAxisSelect = $('#chartXAxisSelect');
currentSettings.mainAxis = parseInt($xAxisSelect.val(), 10);
if (dateTimeCols.indexOf(currentSettings.mainAxis) !== -1) {
document.getElementById('timelineChartType').classList.remove('d-none');
} else {
document.getElementById('timelineChartType').classList.add('d-none');
if (currentSettings.type === 'timeline') {
$('#lineChartTypeRadio').prop('checked', true);
currentSettings.type = 'line';
}
}
if (numericCols.indexOf(currentSettings.mainAxis) !== -1) {
document.getElementById('scatterChartType').classList.remove('d-none');
} else {
document.getElementById('scatterChartType').classList.add('d-none');
if (currentSettings.type === 'scatter') {
$('#lineChartTypeRadio').prop('checked', true);
currentSettings.type = 'line';
}
}
var xAxisTitle = $xAxisSelect.children('option:selected').text();
$('#xAxisLabelInput').val(xAxisTitle);
currentSettings.xaxisLabel = xAxisTitle;
}
function onDataSeriesChange() {
var $seriesSelect = $('#chartSeriesSelect');
currentSettings.selectedSeries = getSelectedSeries();
var yAxisTitle;
if (currentSettings.selectedSeries.length === 1) {
document.getElementById('pieChartType').classList.remove('d-none');
yAxisTitle = $seriesSelect.children('option:selected').text();
} else {
document.getElementById('pieChartType').classList.add('d-none');
if (currentSettings.type === 'pie') {
$('#lineChartTypeRadio').prop('checked', true);
currentSettings.type = 'line';
}
yAxisTitle = Messages.strYValues;
}
$('#yAxisLabelInput').val(yAxisTitle);
currentSettings.yaxisLabel = yAxisTitle;
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('table/chart.js', function () {
$('input[name="chartType"]').off('click');
$('#barStackedCheckbox').off('click');
$('#seriesColumnCheckbox').off('click');
$('#chartTitleInput').off('focus').off('keyup').off('blur');
$('#chartXAxisSelect').off('change');
$('#chartSeriesSelect').off('change');
$('#chartSeriesColumnSelect').off('change');
$('#chartValueColumnSelect').off('change');
$('#xAxisLabelInput').off('keyup');
$('#yAxisLabelInput').off('keyup');
$('#resizer').off('resizestop');
$('#tblchartform').off('submit');
});
AJAX.registerOnload('table/chart.js', function () {
// handle manual resize
$('#resizer').on('resizestop', function () {
// make room so that the handle will still appear
$('#querychart').height($('#resizer').height() * 0.96);
$('#querychart').width($('#resizer').width() * 0.96);
if (currentChart !== null) {
currentChart.redraw({
resetAxes: true
});
}
});
// handle chart type changes
$('input[name="chartType"]').on('click', function () {
var type = currentSettings.type = $(this).val();
if (type === 'bar' || type === 'column' || type === 'area') {
document.getElementById('barStacked').classList.remove('d-none');
} else {
$('#barStackedCheckbox').prop('checked', false);
$.extend(true, currentSettings, {
stackSeries: false
});
document.getElementById('barStacked').classList.add('d-none');
}
drawChart();
});
// handle chosing alternative data format
$('#seriesColumnCheckbox').on('click', function () {
var $seriesColumn = $('#chartSeriesColumnSelect');
var $valueColumn = $('#chartValueColumnSelect');
var $chartSeries = $('#chartSeriesSelect');
if ($(this).is(':checked')) {
$seriesColumn.prop('disabled', false);
$valueColumn.prop('disabled', false);
$chartSeries.prop('disabled', true);
currentSettings.seriesColumn = parseInt($seriesColumn.val(), 10);
currentSettings.valueColumn = parseInt($valueColumn.val(), 10);
} else {
$seriesColumn.prop('disabled', true);
$valueColumn.prop('disabled', true);
$chartSeries.prop('disabled', false);
currentSettings.seriesColumn = null;
currentSettings.valueColumn = null;
}
drawChart();
});
// handle stacking for bar, column and area charts
$('#barStackedCheckbox').on('click', function () {
if ($(this).is(':checked')) {
$.extend(true, currentSettings, {
stackSeries: true
});
} else {
$.extend(true, currentSettings, {
stackSeries: false
});
}
drawChart();
});
// handle changes in chart title
$('#chartTitleInput').on('focus', function () {
tempChartTitle = $(this).val();
}).on('keyup', function () {
currentSettings.title = $('#chartTitleInput').val();
drawChart();
}).on('blur', function () {
if ($(this).val() !== tempChartTitle) {
drawChart();
}
});
// handle changing the x-axis
$('#chartXAxisSelect').on('change', function () {
onXAxisChange();
drawChart();
});
// handle changing the selected data series
$('#chartSeriesSelect').on('change', function () {
onDataSeriesChange();
drawChart();
});
// handle changing the series column
$('#chartSeriesColumnSelect').on('change', function () {
currentSettings.seriesColumn = parseInt($(this).val(), 10);
drawChart();
});
// handle changing the value column
$('#chartValueColumnSelect').on('change', function () {
currentSettings.valueColumn = parseInt($(this).val(), 10);
drawChart();
});
// handle manual changes to the chart x-axis labels
$('#xAxisLabelInput').on('keyup', function () {
currentSettings.xaxisLabel = $(this).val();
drawChart();
});
// handle manual changes to the chart y-axis labels
$('#yAxisLabelInput').on('keyup', function () {
currentSettings.yaxisLabel = $(this).val();
drawChart();
});
// handler for ajax form submission
$('#tblchartform').on('submit', function () {
var $form = $(this);
if (codeMirrorEditor) {
$form[0].elements.sql_query.value = codeMirrorEditor.getValue();
}
if (!Functions.checkSqlQuery($form[0])) {
return false;
}
var $msgbox = Functions.ajaxShowMessage();
Functions.prepareForAjaxRequest($form);
$.post($form.attr('action'), $form.serialize(), function (data) {
if (typeof data !== 'undefined' && data.success === true && typeof data.chartData !== 'undefined') {
chartData = JSON.parse(data.chartData);
drawChart();
Functions.ajaxRemoveMessage($msgbox);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}, 'json'); // end $.post()
return false;
});
// from jQuery UI
$('#resizer').resizable({
minHeight: 240,
minWidth: 300
}).width($('#div_view_options').width() - 50).trigger('resizestop');
currentSettings = {
type: 'line',
width: $('#resizer').width() - 20,
height: $('#resizer').height() - 20,
xaxisLabel: $('#xAxisLabelInput').val(),
yaxisLabel: $('#yAxisLabelInput').val(),
title: $('#chartTitleInput').val(),
stackSeries: false,
mainAxis: parseInt($('#chartXAxisSelect').val(), 10),
selectedSeries: getSelectedSeries(),
seriesColumn: null
};
var vals = $('input[name="dateTimeCols"]').val().split(' ');
$.each(vals, function (i, v) {
dateTimeCols.push(parseInt(v, 10));
});
vals = $('input[name="numericCols"]').val().split(' ');
$.each(vals, function (i, v) {
numericCols.push(parseInt(v, 10));
});
onXAxisChange();
onDataSeriesChange();
$('#tblchartform').trigger('submit');
});

View file

@ -1,40 +0,0 @@
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('table/find_replace.js', function () {
$('#find_replace_form').off('submit');
$('#toggle_find').off('click');
});
/**
* Bind events
*/
AJAX.registerOnload('table/find_replace.js', function () {
$('<div id="toggle_find_div"><a id="toggle_find"></a></div>').insertAfter('#find_replace_form').hide();
$('#toggle_find').html(Messages.strHideFindNReplaceCriteria).on('click', function () {
var $link = $(this);
$('#find_replace_form').slideToggle();
if ($link.text() === Messages.strHideFindNReplaceCriteria) {
$link.text(Messages.strShowFindNReplaceCriteria);
} else {
$link.text(Messages.strHideFindNReplaceCriteria);
}
return false;
});
$('#find_replace_form').on('submit', function (e) {
e.preventDefault();
var findReplaceForm = $('#find_replace_form');
Functions.prepareForAjaxRequest(findReplaceForm);
var $msgbox = Functions.ajaxShowMessage();
$.post(findReplaceForm.attr('action'), findReplaceForm.serialize(), function (data) {
Functions.ajaxRemoveMessage($msgbox);
if (data.success === true) {
$('#toggle_find_div').show();
$('#toggle_find').trigger('click');
$('#sqlqueryresultsouter').html(data.preview);
} else {
$('#sqlqueryresultsouter').html(data.error);
}
});
});
});

View file

@ -1,330 +0,0 @@
/**
* @fileoverview functions used for visualizing GIS data
*
* @requires jquery
*/
/* global drawOpenLayers PASSIVE_EVENT_LISTENERS */ // templates/table/gis_visualization/gis_visualization.twig
// Constants
var zoomFactor = 1.5;
var defaultX = 0;
var defaultY = 0;
var defaultScale = 1;
// Variables
var x = defaultX;
var y = defaultY;
var scale = defaultScale;
/** @type {SVGElement|undefined} */
var gisSvg;
/** @type {ol.Map|undefined} */
var map;
/**
* Zooms and pans the visualization.
*/
function zoomAndPan() {
var g = gisSvg.getElementById('groupPanel');
if (!g) {
return;
}
$('#groupPanel', gisSvg).attr('transform', 'translate(' + x + ', ' + y + ') scale(' + scale + ')');
$('circle.vector', gisSvg).attr('r', 3 / scale);
$('circle.vector', gisSvg).attr('stroke-width', 2 / scale);
$('polyline.vector', gisSvg).attr('stroke-width', 2 / scale);
$('path.vector', gisSvg).attr('stroke-width', 0.5 / scale);
}
/**
* Initially loads either SVG or OSM visualization based on the choice.
*/
function selectVisualization() {
if ($('#choice').prop('checked') !== true) {
$('#openlayersmap').hide();
} else {
$('#placeholder').hide();
}
}
/**
* Adds necessary styles to the div that contains the openStreetMap.
*/
function styleOSM() {
var $placeholder = $('#placeholder');
var cssObj = {
'border': '1px solid #aaa',
'width': $placeholder.width(),
'height': $placeholder.height(),
'float': 'right'
};
$('#openlayersmap').css(cssObj);
}
/**
* Store a reference to the gis svg element.
*/
function storeGisSvgRef() {
gisSvg = $('#placeholder').find('svg').get(0);
}
/**
* Adds controls for zooming and panning.
*/
function addZoomPanControllers() {
if (!gisSvg) {
return;
}
var themeImagePath = $('#themeImagePath').val();
$('#placeholder').append(
// pan arrows
'<img class="button" id="left_arrow" src="' + themeImagePath + 'west-mini.png">', '<img class="button" id="right_arrow" src="' + themeImagePath + 'east-mini.png">', '<img class="button" id="up_arrow" src="' + themeImagePath + 'north-mini.png">', '<img class="button" id="down_arrow" src="' + themeImagePath + 'south-mini.png">',
// zoom controls
'<img class="button" id="zoom_in" src="' + themeImagePath + 'zoom-plus-mini.png">', '<img class="button" id="zoom_world" src="' + themeImagePath + 'zoom-world-mini.png">', '<img class="button" id="zoom_out" src="' + themeImagePath + 'zoom-minus-mini.png">');
}
/**
* Resizes the GIS visualization to fit into the space available.
*/
function resizeGISVisualization() {
var $placeholder = $('#placeholder');
var oldWidth = $placeholder.width();
var visWidth = $('#div_view_options').width() - 48;
// Assign new value for width
$placeholder.width(visWidth);
$(gisSvg).attr('width', visWidth);
// Assign the offset created due to resizing to defaultX and center the svg.
defaultX = (visWidth - oldWidth) / 2;
x = defaultX;
y = defaultY;
scale = defaultScale;
}
/**
* Initialize the GIS visualization.
*/
function initGISVisualization() {
storeGisSvgRef();
// Loads either SVG or OSM visualization based on the choice
selectVisualization();
// Resizes the GIS visualization to fit into the space available
resizeGISVisualization();
if (typeof ol !== 'undefined') {
// Adds necessary styles to the div that contains the openStreetMap
styleOSM();
}
// Adds controllers for zooming and panning
addZoomPanControllers();
zoomAndPan();
}
function drawOpenLayerMap() {
$('#placeholder').hide();
$('#openlayersmap').show();
// Function doesn't work properly if #openlayersmap is hidden
if (typeof map !== 'object') {
// Draws openStreetMap with openLayers
map = drawOpenLayers();
}
}
function getRelativeCoords(e) {
var position = $('#placeholder').offset();
return {
x: e.pageX - position.left,
y: e.pageY - position.top
};
}
/**
* @param {WheelEvent} event
*/
function onGisMouseWheel(event) {
if (event.deltaY === 0) {
return;
}
event.preventDefault();
var relCoords = getRelativeCoords(event);
var factor = event.deltaY > 0 ? zoomFactor : 1 / zoomFactor;
// zoom
scale *= factor;
// zooming keeping the position under mouse pointer unmoved.
x = relCoords.x - (relCoords.x - x) * factor;
y = relCoords.y - (relCoords.y - y) * factor;
zoomAndPan();
}
/**
* Ajax handlers for GIS visualization page
*
* Actions Ajaxified here:
*
* Zooming in and zooming out on mouse wheel movement.
* Panning the visualization on dragging.
* Zooming in on double clicking.
* Zooming out on clicking the zoom out button.
* Panning on clicking the arrow buttons.
* Displaying tooltips for GIS objects.
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('table/gis_visualization.js', function () {
$(document).off('click', '#choice');
$(document).off('dragstart', 'svg');
$(document).off('mouseup', 'svg');
$(document).off('drag', 'svg');
$(document).off('dblclick', '#placeholder');
$(document).off('click', '#zoom_in');
$(document).off('click', '#zoom_world');
$(document).off('click', '#zoom_out');
$(document).off('click', '#left_arrow');
$(document).off('click', '#right_arrow');
$(document).off('click', '#up_arrow');
$(document).off('click', '#down_arrow');
$('.vector').off('mousemove').off('mouseout');
$('#placeholder').get(0).removeEventListener('wheel', onGisMouseWheel, PASSIVE_EVENT_LISTENERS ? {
passive: false
} : undefined);
if (map) {
// Removes ol.Map's resize listener from window
map.setTarget(null);
map = undefined;
}
});
AJAX.registerOnload('table/gis_visualization.js', function () {
// If we are in GIS visualization, initialize it
if ($('#gis_div').length > 0) {
initGISVisualization();
}
if ($('#choice').prop('checked') === true) {
drawOpenLayerMap();
}
if (typeof ol === 'undefined') {
$('#choice, #labelChoice').hide();
}
$(document).on('click', '#choice', function () {
if ($(this).prop('checked') === false) {
$('#placeholder').show();
$('#openlayersmap').hide();
} else {
drawOpenLayerMap();
}
});
$('#placeholder').get(0).addEventListener('wheel', onGisMouseWheel, PASSIVE_EVENT_LISTENERS ? {
passive: false
} : undefined);
var dragX = 0;
var dragY = 0;
$('svg').draggable({
helper: function () {
return $('<div>'); // Give a fake element to be used for dragging display
}
});
$(document).on('dragstart', 'svg', function (event, dd) {
$('#placeholder').addClass('placeholderDrag');
dragX = Math.round(dd.offset.left);
dragY = Math.round(dd.offset.top);
});
$(document).on('mouseup', 'svg', function () {
$('#placeholder').removeClass('placeholderDrag');
});
$(document).on('drag', 'svg', function (event, dd) {
var newX = Math.round(dd.offset.left);
x += newX - dragX;
dragX = newX;
var newY = Math.round(dd.offset.top);
y += newY - dragY;
dragY = newY;
zoomAndPan();
});
$(document).on('dblclick', '#placeholder', function (event) {
if (event.target.classList.contains('button')) {
return;
}
scale *= zoomFactor;
// zooming in keeping the position under mouse pointer unmoved.
var relCoords = getRelativeCoords(event);
x = relCoords.x - (relCoords.x - x) * zoomFactor;
y = relCoords.y - (relCoords.y - y) * zoomFactor;
zoomAndPan();
});
$(document).on('click', '#zoom_in', function (e) {
e.preventDefault();
// zoom in
scale *= zoomFactor;
var width = $(gisSvg).attr('width');
var height = $(gisSvg).attr('height');
// zooming in keeping the center unmoved.
x = width / 2 - (width / 2 - x) * zoomFactor;
y = height / 2 - (height / 2 - y) * zoomFactor;
zoomAndPan();
});
$(document).on('click', '#zoom_world', function (e) {
e.preventDefault();
scale = 1;
x = defaultX;
y = defaultY;
zoomAndPan();
});
$(document).on('click', '#zoom_out', function (e) {
e.preventDefault();
// zoom out
scale /= zoomFactor;
var width = $(gisSvg).attr('width');
var height = $(gisSvg).attr('height');
// zooming out keeping the center unmoved.
x = width / 2 - (width / 2 - x) / zoomFactor;
y = height / 2 - (height / 2 - y) / zoomFactor;
zoomAndPan();
});
$(document).on('click', '#left_arrow', function (e) {
e.preventDefault();
x += 100;
zoomAndPan();
});
$(document).on('click', '#right_arrow', function (e) {
e.preventDefault();
x -= 100;
zoomAndPan();
});
$(document).on('click', '#up_arrow', function (e) {
e.preventDefault();
y += 100;
zoomAndPan();
});
$(document).on('click', '#down_arrow', function (e) {
e.preventDefault();
y -= 100;
zoomAndPan();
});
/**
* Detect the mousemove event and show tooltips.
*/
$('.vector').on('mousemove', function (event) {
var contents = Functions.escapeHtml($(this).attr('name')).trim();
$('#tooltip').remove();
if (contents !== '') {
$('<div id="tooltip">' + contents + '</div>').css({
position: 'absolute',
top: event.pageY + 10,
left: event.pageX + 10,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#fee',
opacity: 0.90
}).appendTo('body').fadeIn(200);
}
});
/**
* Detect the mouseout event and hide tooltips.
*/
$('.vector').on('mouseout', function () {
$('#tooltip').remove();
});
});

View file

@ -1,308 +0,0 @@
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('table/operations.js', function () {
$(document).off('submit', '#copyTable.ajax');
$(document).off('submit', '#moveTableForm');
$(document).off('submit', '#tableOptionsForm');
$(document).off('submit', '#partitionsForm');
$(document).off('click', '#tbl_maintenance li a.maintain_action.ajax');
$(document).off('click', '#drop_tbl_anchor.ajax');
$(document).off('click', '#drop_view_anchor.ajax');
$(document).off('click', '#truncate_tbl_anchor.ajax');
$(document).off('click', '#delete_tbl_anchor.ajax');
});
/**
* Confirm and send POST request
*
* @param {JQuery} linkObject
* @param {'TRUNCATE'|'DELETE'} action
*
* @return {void}
*/
var confirmAndPost = function (linkObject, action) {
/**
* @var {String} question String containing the question to be asked for confirmation
*/
var question = '';
if (action === 'TRUNCATE') {
question += Messages.strTruncateTableStrongWarning + ' ';
} else if (action === 'DELETE') {
question += Messages.strDeleteTableStrongWarning + ' ';
}
question += Functions.sprintf(Messages.strDoYouReally, linkObject.data('query'));
question += Functions.getForeignKeyCheckboxLoader();
linkObject.confirm(question, linkObject.attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, linkObject.getPostData());
$.post(url, params, function (data) {
if ($('.sqlqueryresults').length !== 0) {
$('.sqlqueryresults').remove();
}
if ($('.result_query').length !== 0) {
$('.result_query').remove();
}
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
$('<div class="sqlqueryresults ajax"></div>').prependTo('#page_content');
$('.sqlqueryresults').html(data.sql_query);
Functions.highlightSql($('#page_content'));
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
}, Functions.loadForeignKeyCheckbox);
};
/**
* jQuery coding for 'Table operations'. Used on /table/operations
* Attach Ajax Event handlers for Table operations
*/
AJAX.registerOnload('table/operations.js', function () {
/**
* Ajax action for submitting the "Copy table"
*/
$(document).on('submit', '#copyTable.ajax', function (event) {
event.preventDefault();
var $form = $(this);
Functions.prepareForAjaxRequest($form);
var argsep = CommonParams.get('arg_separator');
$.post($form.attr('action'), $form.serialize() + argsep + 'submit_copy=Go', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
if ($form.find('input[name=\'switch_to_new\']').prop('checked')) {
CommonParams.set('db', $form.find('select[name=\'target_db\'],input[name=\'target_db\']').val());
CommonParams.set('table', $form.find('input[name=\'new_name\']').val());
CommonActions.refreshMain(false, function () {
Functions.ajaxShowMessage(data.message);
});
} else {
Functions.ajaxShowMessage(data.message);
}
// Refresh navigation when the table is copied
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end of copyTable ajax submit
/**
* Ajax action for submitting the "Move table"
*/
$(document).on('submit', '#moveTableForm', function (event) {
event.preventDefault();
var $form = $(this);
Functions.prepareForAjaxRequest($form);
var argsep = CommonParams.get('arg_separator');
$.post($form.attr('action'), $form.serialize() + argsep + 'submit_move=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
CommonParams.set('db', data.params.db);
CommonParams.set('table', data.params.table);
CommonActions.refreshMain('index.php?route=/table/sql', function () {
Functions.ajaxShowMessage(data.message);
});
// Refresh navigation when the table is copied
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
/**
* Ajax action for submitting the "Table options"
*/
$(document).on('submit', '#tableOptionsForm', function (event) {
event.preventDefault();
event.stopPropagation();
var $form = $(this);
var $tblNameField = $form.find('input[name=new_name]');
var $tblCollationField = $form.find('select[name=tbl_collation]');
var collationOrigValue = $('select[name="tbl_collation"] option[selected]').val();
var $changeAllColumnCollationsCheckBox = $('#checkbox_change_all_collations');
var question = Messages.strChangeAllColumnCollationsWarning;
if ($tblNameField.val() !== $tblNameField[0].defaultValue) {
// reload page and navigation if the table has been renamed
Functions.prepareForAjaxRequest($form);
if ($tblCollationField.val() !== collationOrigValue && $changeAllColumnCollationsCheckBox.is(':checked')) {
$form.confirm(question, $form.attr('action'), function () {
submitOptionsForm();
});
} else {
submitOptionsForm();
}
} else {
if ($tblCollationField.val() !== collationOrigValue && $changeAllColumnCollationsCheckBox.is(':checked')) {
$form.confirm(question, $form.attr('action'), function () {
$form.removeClass('ajax').trigger('submit').addClass('ajax');
});
} else {
$form.removeClass('ajax').trigger('submit').addClass('ajax');
}
}
function submitOptionsForm() {
$.post($form.attr('action'), $form.serialize(), function (data) {
if (typeof data !== 'undefined' && data.success === true) {
CommonParams.set('table', data.params.table);
CommonActions.refreshMain(false, function () {
$('#page_content').html(data.message);
Functions.highlightSql($('#page_content'));
});
// Refresh navigation when the table is renamed
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
}
});
/**
* Ajax events for actions in the "Table maintenance"
*/
$(document).on('click', '#tbl_maintenance li a.maintain_action.ajax', function (event) {
event.preventDefault();
var $link = $(this);
if ($('.sqlqueryresults').length !== 0) {
$('.sqlqueryresults').remove();
}
if ($('.result_query').length !== 0) {
$('.result_query').remove();
}
// variables which stores the common attributes
var params = $.param({
'ajax_request': 1,
'server': CommonParams.get('server')
});
var postData = $link.getPostData();
if (postData) {
params += CommonParams.get('arg_separator') + postData;
}
$.post($link.attr('href'), params, function (data) {
function scrollToTop() {
$('html, body').animate({
scrollTop: 0
});
}
var $tempDiv;
if (typeof data !== 'undefined' && data.success === true && data.sql_query !== undefined) {
Functions.ajaxShowMessage(data.message);
$('<div class=\'sqlqueryresults ajax\'></div>').prependTo('#page_content');
$('.sqlqueryresults').html(data.sql_query);
Functions.highlightSql($('#page_content'));
scrollToTop();
} else if (typeof data !== 'undefined' && data.success === true) {
$tempDiv = $('<div id=\'temp_div\'></div>');
$tempDiv.html(data.message);
var $success = $tempDiv.find('.result_query .alert-success');
Functions.ajaxShowMessage($success);
$('<div class=\'sqlqueryresults ajax\'></div>').prependTo('#page_content');
$('.sqlqueryresults').html(data.message);
Functions.highlightSql($('#page_content'));
$('.sqlqueryresults').children('fieldset,br').remove();
scrollToTop();
} else {
$tempDiv = $('<div id=\'temp_div\'></div>');
$tempDiv.html(data.error);
var $error;
if ($tempDiv.find('.error code').length !== 0) {
$error = $tempDiv.find('.error code').addClass('error');
} else {
$error = $tempDiv;
}
Functions.ajaxShowMessage($error, false);
}
}); // end $.post()
}); // end of table maintenance ajax click
/**
* Ajax action for submitting the "Partition Maintenance"
* Also, asks for confirmation when DROP partition is submitted
*/
$(document).on('submit', '#partitionsForm', function (event) {
event.preventDefault();
var $form = $(this);
function submitPartitionMaintenance() {
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
Functions.ajaxShowMessage(Messages.strProcessingRequest);
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
}
if ($('#partitionOperationRadioDrop').is(':checked')) {
$form.confirm(Messages.strDropPartitionWarning, $form.attr('action'), function () {
submitPartitionMaintenance();
});
} else if ($('#partitionOperationRadioTruncate').is(':checked')) {
$form.confirm(Messages.strTruncatePartitionWarning, $form.attr('action'), function () {
submitPartitionMaintenance();
});
} else {
submitPartitionMaintenance();
}
});
$(document).on('click', '#drop_tbl_anchor.ajax', function (event) {
event.preventDefault();
var $link = $(this);
/**
* @var {String} question String containing the question to be asked for confirmation
*/
var question = Messages.strDropTableStrongWarning + ' ';
question += Functions.sprintf(Messages.strDoYouReally, $link[0].getAttribute('data-query'));
question += Functions.getForeignKeyCheckboxLoader();
$(this).confirm(question, $(this).attr('href'), function (url) {
var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $link.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxRemoveMessage($msgbox);
// Table deleted successfully, refresh both the frames
Navigation.reload();
CommonParams.set('table', '');
CommonActions.refreshMain(CommonParams.get('opendb_url'), function () {
Functions.ajaxShowMessage(data.message);
});
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
}, Functions.loadForeignKeyCheckbox);
}); // end of Drop Table Ajax action
$(document).on('click', '#drop_view_anchor.ajax', function (event) {
event.preventDefault();
var $link = $(this);
/**
* @var {String} question String containing the question to be asked for confirmation
*/
var question = Messages.strDropTableStrongWarning + ' ';
question += Functions.sprintf(Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(CommonParams.get('table') + '`'));
$(this).confirm(question, $(this).attr('href'), function (url) {
var $msgbox = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $link.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxRemoveMessage($msgbox);
// Table deleted successfully, refresh both the frames
Navigation.reload();
CommonParams.set('table', '');
CommonActions.refreshMain(CommonParams.get('opendb_url'), function () {
Functions.ajaxShowMessage(data.message);
});
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
}); // end of Drop View Ajax action
$(document).on('click', '#truncate_tbl_anchor.ajax', function (event) {
event.preventDefault();
confirmAndPost($(this), 'TRUNCATE');
});
$(document).on('click', '#delete_tbl_anchor.ajax', function (event) {
event.preventDefault();
confirmAndPost($(this), 'DELETE');
});
}); // end $(document).ready for 'Table operations'

View file

@ -1,208 +0,0 @@
/**
* for table relation
*/
var TableRelation = {};
TableRelation.showHideClauses = function ($thisDropdown) {
if ($thisDropdown.val() === '') {
$thisDropdown.parent().nextAll('span').hide();
} else {
if ($thisDropdown.is('select[name^="destination_foreign_column"]')) {
$thisDropdown.parent().nextAll('span').show();
}
}
};
/**
* Sets dropdown options to values
* @param $dropdown
* @param values
* @param selectedValue
* @return {void}
*/
TableRelation.setDropdownValues = function ($dropdown, values, selectedValue) {
$dropdown.empty();
var optionsAsString = '';
// add an empty string to the beginning for empty selection
values.unshift('');
$.each(values, function () {
optionsAsString += '<option value=\'' + Functions.escapeHtml(this) + '\'' + (selectedValue === Functions.escapeHtml(this) ? ' selected=\'selected\'' : '') + '>' + Functions.escapeHtml(this) + '</option>';
});
$dropdown.append($(optionsAsString));
};
/**
* Retrieves and populates dropdowns to the left based on the selected value
*
* @param $dropdown the dropdown whose value got changed
* @return {void}
*/
TableRelation.getDropdownValues = function ($dropdown) {
var foreignDb = null;
var foreignTable = null;
var $databaseDd;
var $tableDd;
var $columnDd;
var foreign = '';
// if the changed dropdown is for foreign key constraints
if ($dropdown.is('select[name^="destination_foreign"]')) {
$databaseDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_db"]');
$tableDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_table"]');
$columnDd = $dropdown.parent().parent().parent().find('select[name^="destination_foreign_column"]');
foreign = '_foreign';
} else {
// internal relations
$databaseDd = $dropdown.parent().find('select[name^="destination_db"]');
$tableDd = $dropdown.parent().find('select[name^="destination_table"]');
$columnDd = $dropdown.parent().find('select[name^="destination_column"]');
}
// if the changed dropdown is a database selector
if ($dropdown.is('select[name^="destination' + foreign + '_db"]')) {
foreignDb = $dropdown.val();
// if no database is selected empty table and column dropdowns
if (foreignDb === '') {
TableRelation.setDropdownValues($tableDd, []);
TableRelation.setDropdownValues($columnDd, []);
return;
}
} else {
// if a table selector
foreignDb = $databaseDd.val();
foreignTable = $dropdown.val();
// if no table is selected empty the column dropdown
if (foreignTable === '') {
TableRelation.setDropdownValues($columnDd, []);
return;
}
}
var $msgbox = Functions.ajaxShowMessage();
var $form = $dropdown.parents('form');
var $db = $form.find('input[name="db"]').val();
var $table = $form.find('input[name="table"]').val();
var argsep = CommonParams.get('arg_separator');
var params = 'getDropdownValues=true' + argsep + 'ajax_request=true' + argsep + 'db=' + encodeURIComponent($db) + argsep + 'table=' + encodeURIComponent($table) + argsep + 'foreign=' + (foreign !== '') + argsep + 'foreignDb=' + encodeURIComponent(foreignDb) + (foreignTable !== null ? argsep + 'foreignTable=' + encodeURIComponent(foreignTable) : '');
var $server = $form.find('input[name="server"]');
if ($server.length > 0) {
params += argsep + 'server=' + $form.find('input[name="server"]').val();
}
$.ajax({
type: 'POST',
url: 'index.php?route=/table/relation',
data: params,
dataType: 'json',
success: function (data) {
Functions.ajaxRemoveMessage($msgbox);
if (typeof data !== 'undefined' && data.success) {
// if the changed dropdown is a database selector
if (foreignTable === null) {
// set values for table and column dropdowns
TableRelation.setDropdownValues($tableDd, data.tables);
TableRelation.setDropdownValues($columnDd, []);
} else {
// if a table selector
// set values for the column dropdown
var primary = null;
if (typeof data.primary !== 'undefined' && 1 === data.primary.length) {
primary = data.primary[0];
}
TableRelation.setDropdownValues($columnDd.first(), data.columns, primary);
TableRelation.setDropdownValues($columnDd.slice(1), data.columns);
}
} else {
Functions.ajaxShowMessage(data.error, false);
}
}
});
};
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('table/relation.js', function () {
$('body').off('change', 'select[name^="destination_db"], ' + 'select[name^="destination_table"], ' + 'select[name^="destination_foreign_db"], ' + 'select[name^="destination_foreign_table"]');
$('body').off('click', 'a.add_foreign_key_field');
$('body').off('click', 'a.add_foreign_key');
$('a.drop_foreign_key_anchor.ajax').off('click');
});
AJAX.registerOnload('table/relation.js', function () {
/**
* Ajax event handler to fetch table/column dropdown values.
*/
$('body').on('change', 'select[name^="destination_db"], ' + 'select[name^="destination_table"], ' + 'select[name^="destination_foreign_db"], ' + 'select[name^="destination_foreign_table"]', function () {
TableRelation.getDropdownValues($(this));
});
/**
* Ajax event handler to add a column to a foreign key constraint.
*/
$('body').on('click', 'a.add_foreign_key_field', function (event) {
event.preventDefault();
event.stopPropagation();
// Add field.
$(this).prev('span').clone(true, true).insertBefore($(this)).find('select').val('');
// Add foreign field.
var $sourceElem = $('select[name^="destination_foreign_column[' + $(this).attr('data-index') + ']"]').last().parent();
$sourceElem.clone(true, true).insertAfter($sourceElem).find('select').val('');
});
/**
* Ajax event handler to add a foreign key constraint.
*/
$('body').on('click', 'a.add_foreign_key', function (event) {
event.preventDefault();
event.stopPropagation();
var $prevRow = $(this).closest('tr').prev('tr');
var $newRow = $prevRow.clone(true, true);
// Update serial number.
var currIndex = $newRow.find('a.add_foreign_key_field').attr('data-index');
var newIndex = parseInt(currIndex) + 1;
$newRow.find('a.add_foreign_key_field').attr('data-index', newIndex);
// Update form parameter names.
$newRow.find('select[name^="foreign_key_fields_name"]').not($newRow.find('select[name^="foreign_key_fields_name"]').first()).find('select[name^="destination_foreign_column"]').not($newRow.find('select[name^="foreign_key_fields_name"]').not($newRow.find('select[name^="foreign_key_fields_name"]').first()).find('select[name^="destination_foreign_column"]').first()).each(function () {
$(this).parent().remove();
});
$newRow.find('input, select').each(function () {
$(this).attr('name', $(this).attr('name').replace(/\d/, newIndex));
});
$newRow.find('input[type="text"]').each(function () {
$(this).val('');
});
// Finally add the row.
$newRow.insertAfter($prevRow);
});
/**
* Ajax Event handler for 'Drop Foreign key'
*/
$('a.drop_foreign_key_anchor.ajax').on('click', function (event) {
event.preventDefault();
var $anchor = $(this);
// Object containing reference to the current field's row
var $currRow = $anchor.parents('tr');
var dropQuery = Functions.escapeHtml($currRow.children('td').children('.drop_foreign_key_msg').val());
var question = Functions.sprintf(Messages.strDoYouReally, dropQuery);
$anchor.confirm(question, $anchor.attr('href'), function (url) {
var $msg = Functions.ajaxShowMessage(Messages.strDroppingForeignKey, false);
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
$.post(url, params, function (data) {
if (data.success === true) {
Functions.ajaxRemoveMessage($msg);
CommonActions.refreshMain(false, function () {
// Do nothing
});
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
});
}); // end Drop Foreign key
var windowWidth = $(window).width();
$('.jsresponsive').css('max-width', windowWidth - 35 + 'px');
});

View file

@ -1,299 +0,0 @@
/**
* @fileoverview JavaScript functions used on /table/search
*
* @requires jQuery
* @requires js/functions.js
*/
/* global changeValueFieldType, verifyAfterSearchFieldChange */ // js/table/change.js
/* global openGISEditor, gisEditorLoaded, loadJSAndGISEditor, loadGISEditor */ // js/gis_data_editor.js
var TableSelect = {};
/**
* Checks if given data-type is numeric or date.
*
* @param {string} dataType Column data-type
*
* @return {boolean | string}
*/
TableSelect.checkIfDataTypeNumericOrDate = function (dataType) {
// To test for numeric data-types.
var numericRegExp = new RegExp('TINYINT|SMALLINT|MEDIUMINT|INT|BIGINT|DECIMAL|FLOAT|DOUBLE|REAL', 'i');
// To test for date data-types.
var dateRegExp = new RegExp('DATETIME|DATE|TIMESTAMP|TIME|YEAR', 'i');
// Return matched data-type
if (numericRegExp.test(dataType)) {
return numericRegExp.exec(dataType)[0];
}
if (dateRegExp.test(dataType)) {
return dateRegExp.exec(dataType)[0];
}
return false;
};
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('table/select.js', function () {
$('#togglesearchformlink').off('click');
$(document).off('submit', '#tbl_search_form.ajax');
$('select.geom_func').off('change');
$(document).off('click', 'span.open_search_gis_editor');
$('body').off('change', 'select[name*="criteriaColumnOperators"]'); // Fix for bug #13778, changed 'click' to 'change'
});
AJAX.registerOnload('table/select.js', function () {
/**
* Prepare a div containing a link, otherwise it's incorrectly displayed
* after a couple of clicks
*/
$('<div id="togglesearchformdiv"><a id="togglesearchformlink"></a></div>').insertAfter('#tbl_search_form')
// don't show it until we have results on-screen
.hide();
$('#togglesearchformlink').html(Messages.strShowSearchCriteria).on('click', function () {
var $link = $(this);
$('#tbl_search_form').slideToggle();
if ($link.text() === Messages.strHideSearchCriteria) {
$link.text(Messages.strShowSearchCriteria);
} else {
$link.text(Messages.strHideSearchCriteria);
}
// avoid default click action
return false;
});
var tableRows = $('#fieldset_table_qbe select.column-operator');
$.each(tableRows, function (index, item) {
$(item).on('change', function () {
changeValueFieldType(this, index);
verifyAfterSearchFieldChange(index, '#tbl_search_form');
});
});
/**
* Ajax event handler for Table search
*/
$(document).on('submit', '#tbl_search_form.ajax', function (event) {
var unaryFunctions = ['IS NULL', 'IS NOT NULL', '= \'\'', '!= \'\''];
var geomUnaryFunctions = ['IsEmpty', 'IsSimple', 'IsRing', 'IsClosed'];
// jQuery object to reuse
var $searchForm = $(this);
event.preventDefault();
// empty previous search results while we are waiting for new results
$('#sqlqueryresultsouter').empty();
var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false);
Functions.prepareForAjaxRequest($searchForm);
var values = {};
$searchForm.find(':input').each(function () {
var $input = $(this);
if ($input.attr('type') === 'checkbox' || $input.attr('type') === 'radio') {
if ($input.is(':checked')) {
values[this.name] = $input.val();
}
} else {
values[this.name] = $input.val();
}
});
var columnCount = $('select[name="columnsToDisplay[]"] option').length;
// Submit values only for the columns that have unary column operator or a search criteria
for (var a = 0; a < columnCount; a++) {
if ($.inArray(values['criteriaColumnOperators[' + a + ']'], unaryFunctions) >= 0) {
continue;
}
if (values['geom_func[' + a + ']'] && $.inArray(values['geom_func[' + a + ']'], geomUnaryFunctions) >= 0) {
continue;
}
if (values['criteriaValues[' + a + ']'] === '' || values['criteriaValues[' + a + ']'] === null) {
delete values['criteriaValues[' + a + ']'];
delete values['criteriaColumnOperators[' + a + ']'];
delete values['criteriaColumnNames[' + a + ']'];
delete values['criteriaColumnTypes[' + a + ']'];
delete values['criteriaColumnCollations[' + a + ']'];
}
}
// If all columns are selected, use a single parameter to indicate that
if (values['columnsToDisplay[]'] !== null) {
if (values['columnsToDisplay[]'].length === columnCount) {
delete values['columnsToDisplay[]'];
values.displayAllColumns = true;
}
} else {
values.displayAllColumns = true;
}
$.post($searchForm.attr('action'), values, function (data) {
Functions.ajaxRemoveMessage($msgbox);
if (typeof data !== 'undefined' && data.success === true) {
if (typeof data.sql_query !== 'undefined') {
// zero rows
$('#sqlqueryresultsouter').html(data.sql_query);
} else {
// results found
$('#sqlqueryresultsouter').html(data.message);
$('.sqlqueryresults').trigger('makegrid');
}
$('#tbl_search_form')
// workaround for bug #3168569 - Issue on toggling the "Hide search criteria" in chrome.
.slideToggle().hide();
$('#togglesearchformlink')
// always start with the Show message
.text(Messages.strShowSearchCriteria);
$('#togglesearchformdiv')
// now it's time to show the div containing the link
.show();
$('html, body').animate({
scrollTop: 0
}, 'fast');
} else {
$('#sqlqueryresultsouter').html(data.error);
}
Functions.highlightSql($('#sqlqueryresultsouter'));
}); // end $.post()
});
// Following section is related to the 'function based search' for geometry data types.
// Initially hide all the open_gis_editor spans
$('span.open_search_gis_editor').hide();
$('select.geom_func').on('change', function () {
var $geomFuncSelector = $(this);
var binaryFunctions = ['Contains', 'Crosses', 'Disjoint', 'Equals', 'Intersects', 'Overlaps', 'Touches', 'Within', 'MBRContains', 'MBRDisjoint', 'MBREquals', 'MBRIntersects', 'MBROverlaps', 'MBRTouches', 'MBRWithin', 'ST_Contains', 'ST_Crosses', 'ST_Disjoint', 'ST_Equals', 'ST_Intersects', 'ST_Overlaps', 'ST_Touches', 'ST_Within'];
var tempArray = ['Envelope', 'EndPoint', 'StartPoint', 'ExteriorRing', 'Centroid', 'PointOnSurface'];
var outputGeomFunctions = binaryFunctions.concat(tempArray);
// If the chosen function takes two geometry objects as parameters
var $operator = $geomFuncSelector.parents('tr').find('td').eq(4).find('select');
if ($.inArray($geomFuncSelector.val(), binaryFunctions) >= 0) {
$operator.prop('readonly', true);
} else {
$operator.prop('readonly', false);
}
// if the chosen function's output is a geometry, enable GIS editor
var $editorSpan = $geomFuncSelector.parents('tr').find('span.open_search_gis_editor');
if ($.inArray($geomFuncSelector.val(), outputGeomFunctions) >= 0) {
$editorSpan.show();
} else {
$editorSpan.hide();
}
});
$(document).on('click', 'span.open_search_gis_editor', function (event) {
event.preventDefault();
var $span = $(this);
// Current value
var value = $span.parent('td').children('input[type=\'text\']').val();
// Field name
var field = 'Parameter';
// Column type
var geomFunc = $span.parents('tr').find('.geom_func').val();
var type;
if (geomFunc === 'Envelope') {
type = 'polygon';
} else if (geomFunc === 'ExteriorRing') {
type = 'linestring';
} else {
type = 'point';
}
// Names of input field and null checkbox
var inputName = $span.parent('td').children('input[type=\'text\']').attr('name');
// Token
openGISEditor();
if (!gisEditorLoaded) {
loadJSAndGISEditor(value, field, type, inputName);
} else {
loadGISEditor(value, field, type, inputName);
}
});
/**
* Ajax event handler for Range-Search.
*/
$('body').on('change', 'select[name*="criteriaColumnOperators"]', function () {
// Fix for bug #13778, changed 'click' to 'change'
var $sourceSelect = $(this);
// Get the column name.
var columnName = $(this).closest('tr').find('th').first().text();
// Get the data-type of column excluding size.
var dataType = $(this).closest('tr').find('td[data-type]').attr('data-type');
dataType = TableSelect.checkIfDataTypeNumericOrDate(dataType);
// Get the operator.
var operator = $(this).val();
if ((operator === 'BETWEEN' || operator === 'NOT BETWEEN') && dataType) {
var $msgbox = Functions.ajaxShowMessage();
$.ajax({
url: 'index.php?route=/table/search',
type: 'POST',
data: {
'server': CommonParams.get('server'),
'ajax_request': 1,
'db': $('input[name="db"]').val(),
'table': $('input[name="table"]').val(),
'column': columnName,
'range_search': 1
},
success: function (response) {
Functions.ajaxRemoveMessage($msgbox);
if (response.success) {
// Get the column min value.
var min = response.column_data.min ? '(' + Messages.strColumnMin + ' ' + response.column_data.min + ')' : '';
// Get the column max value.
var max = response.column_data.max ? '(' + Messages.strColumnMax + ' ' + response.column_data.max + ')' : '';
$('#rangeSearchModal').modal('show');
$('#rangeSearchLegend').first().html(operator);
$('#rangeSearchMin').first().text(min);
$('#rangeSearchMax').first().text(max);
// Reset input values on reuse
$('#min_value').first().val('');
$('#max_value').first().val('');
// Add datepicker wherever required.
Functions.addDatepicker($('#min_value'), dataType);
Functions.addDatepicker($('#max_value'), dataType);
$('#rangeSearchModalGo').on('click', function () {
var minValue = $('#min_value').val();
var maxValue = $('#max_value').val();
var finalValue = '';
if (minValue.length && maxValue.length) {
finalValue = minValue + ', ' + maxValue;
}
var $targetField = $sourceSelect.closest('tr').find('[name*="criteriaValues"]');
// If target field is a select list.
if ($targetField.is('select')) {
$targetField.val(finalValue);
var $options = $targetField.find('option');
var $closestMin = null;
var $closestMax = null;
// Find closest min and max value.
$options.each(function () {
if ($closestMin === null || Math.abs($(this).val() - minValue) < Math.abs($closestMin.val() - minValue)) {
$closestMin = $(this);
}
if ($closestMax === null || Math.abs($(this).val() - maxValue) < Math.abs($closestMax.val() - maxValue)) {
$closestMax = $(this);
}
});
$closestMin.attr('selected', 'selected');
$closestMax.attr('selected', 'selected');
} else {
$targetField.val(finalValue);
}
$('#rangeSearchModal').modal('hide');
});
} else {
Functions.ajaxShowMessage(response.error);
}
},
error: function () {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest);
}
});
}
});
var windowWidth = $(window).width();
$('.jsresponsive').css('max-width', windowWidth - 69 + 'px');
});

View file

@ -1,416 +0,0 @@
/**
* @fileoverview functions used on the table structure page
* @name Table Structure
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
// eslint-disable-next-line no-unused-vars
/* global primaryIndexes:writable, indexes:writable, fulltextIndexes:writable, spatialIndexes:writable */ // js/functions.js
/* global sprintf */ // js/vendor/sprintf.js
/**
* AJAX scripts for /table/structure
*
* Actions ajaxified here:
* Drop Column
* Add Primary Key
* Drop Primary Key/Index
*
*/
/**
* Reload fields table
*/
function reloadFieldForm() {
$.post($('#fieldsForm').attr('action'), $('#fieldsForm').serialize() + CommonParams.get('arg_separator') + 'ajax_request=true', function (formData) {
var $tempDiv = $('<div id=\'temp_div\'><div>').append(formData.message);
$('#fieldsForm').replaceWith($tempDiv.find('#fieldsForm'));
$('#addColumns').replaceWith($tempDiv.find('#addColumns'));
$('#move_columns_dialog').find('ul').replaceWith($tempDiv.find('#move_columns_dialog ul'));
});
$('#page_content').show();
}
function checkFirst() {
if ($('select[name=after_field] option:selected').data('pos') === 'first') {
$('input[name=field_where]').val('first');
} else {
$('input[name=field_where]').val('after');
}
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('table/structure.js', function () {
$(document).off('click', 'a.drop_column_anchor.ajax');
$(document).off('click', 'a.add_key.ajax');
$(document).off('click', '#move_columns_anchor');
$(document).off('submit', '.append_fields_form.ajax');
$('body').off('click', '#fieldsForm button.mult_submit');
$(document).off('click', 'a[id^=partition_action].ajax');
$(document).off('click', '#remove_partitioning.ajax');
});
AJAX.registerOnload('table/structure.js', function () {
// Re-initialize variables.
primaryIndexes = [];
indexes = [];
fulltextIndexes = [];
spatialIndexes = [];
/**
*Ajax action for submitting the "Column Change" and "Add Column" form
*/
$('.append_fields_form.ajax').off();
$(document).on('submit', '.append_fields_form.ajax', function (event) {
event.preventDefault();
/**
* @var form object referring to the export form
*/
var $form = $(this);
var fieldCnt = $form.find('input[name=orig_num_fields]').val();
function submitForm() {
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
$.post($form.attr('action'), $form.serialize() + CommonParams.get('arg_separator') + 'do_save_data=1', function (data) {
if ($('.sqlqueryresults').length !== 0) {
$('.sqlqueryresults').remove();
} else if ($('.error:not(.tab)').length !== 0) {
$('.error:not(.tab)').remove();
}
if (typeof data.success !== 'undefined' && data.success === true) {
$('#page_content').empty().append(data.message).show();
Functions.highlightSql($('#page_content'));
$('.result_query .alert-primary').remove();
if (typeof data.structure_refresh_route !== 'string') {
// Do not reload the form when the code below freshly filled it
reloadFieldForm();
}
$form.remove();
Functions.ajaxRemoveMessage($msg);
Navigation.reload();
if (typeof data.structure_refresh_route === 'string') {
// Fetch the table structure right after adding a new column
$.get(data.structure_refresh_route, function (data) {
if (typeof data.success !== 'undefined' && data.success === true) {
$('#page_content').append(data.message).show();
}
});
} else {
CommonActions.refreshMain('index.php?route=/table/structure');
}
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}
function checkIfConfirmRequired($form) {
var i = 0;
var id;
var elm;
var val;
var nameOrig;
var elmOrig;
var valOrig;
var checkRequired = false;
for (i = 0; i < fieldCnt; i++) {
id = '#field_' + i + '_5';
elm = $(id);
val = elm.val();
nameOrig = 'input[name=field_collation_orig\\[' + i + '\\]]';
elmOrig = $form.find(nameOrig);
valOrig = elmOrig.val();
if (val && valOrig && val !== valOrig) {
checkRequired = true;
break;
}
}
return checkRequired;
}
/*
* First validate the form; if there is a problem, avoid submitting it
*
* Functions.checkTableEditForm() needs a pure element and not a jQuery object,
* this is why we pass $form[0] as a parameter (the jQuery object
* is actually an array of DOM elements)
*/
if (Functions.checkTableEditForm($form[0], fieldCnt)) {
// OK, form passed validation step
Functions.prepareForAjaxRequest($form);
if (Functions.checkReservedWordColumns($form)) {
// User wants to submit the form
// If Collation is changed, Warn and Confirm
if (checkIfConfirmRequired($form)) {
var question = sprintf(Messages.strChangeColumnCollation, 'https://wiki.phpmyadmin.net/pma/Garbled_data');
$form.confirm(question, $form.attr('action'), function () {
submitForm();
});
} else {
submitForm();
}
}
}
}); // end change table button "do_save_data"
/**
* Attach Event Handler for 'Drop Column'
*/
$(document).on('click', 'a.drop_column_anchor.ajax', function (event) {
event.preventDefault();
/**
* @var currTableName String containing the name of the current table
*/
var currTableName = $(this).closest('form').find('input[name=table]').val();
/**
* @var currRow Object reference to the currently selected row (i.e. field in the table)
*/
var $currRow = $(this).parents('tr');
/**
* @var currColumnName String containing name of the field referred to by {@link curr_row}
*/
var currColumnName = $currRow.children('th').children('label').text().trim();
currColumnName = Functions.escapeHtml(currColumnName);
/**
* @var $afterFieldItem Corresponding entry in the 'After' field.
*/
var $afterFieldItem = $('select[name=\'after_field\'] option[value=\'' + currColumnName + '\']');
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Functions.sprintf(Messages.strDoYouReally, 'ALTER TABLE `' + currTableName + '` DROP `' + currColumnName + '`;');
var $thisAnchor = $(this);
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
var $msg = Functions.ajaxShowMessage(Messages.strDroppingColumn, false);
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
params += CommonParams.get('arg_separator') + 'ajax_page_request=1';
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxRemoveMessage($msg);
if ($('.result_query').length) {
$('.result_query').remove();
}
if (data.sql_query) {
$('<div class="result_query"></div>').html(data.sql_query).prependTo('#structure_content');
Functions.highlightSql($('#page_content'));
}
// Adjust the row numbers
for (var $row = $currRow.next(); $row.length > 0; $row = $row.next()) {
var newVal = parseInt($row.find('td').eq(1).text(), 10) - 1;
$row.find('td').eq(1).text(newVal);
}
$afterFieldItem.remove();
$currRow.hide('medium').remove();
// Remove the dropped column from select menu for 'after field'
$('select[name=after_field]').find('[value="' + currColumnName + '"]').remove();
// by default select the (new) last option to add new column
// (in case last column is dropped)
$('select[name=after_field] option').last().attr('selected', 'selected');
// refresh table stats
if (data.tableStat) {
$('#tablestatistics').html(data.tableStat);
}
// refresh the list of indexes (comes from /sql)
$('.index_info').replaceWith(data.indexes_list);
Navigation.reload();
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
});
}); // end of Drop Column Anchor action
/**
* Ajax Event handler for adding keys
*/
$(document).on('click', 'a.add_key.ajax', function (event) {
event.preventDefault();
var $this = $(this);
var currTableName = $this.closest('form').find('input[name=table]').val();
var currColumnName = $this.parents('tr').children('th').children('label').text().trim();
var addClause = '';
if ($this.is('.add_primary_key_anchor')) {
addClause = 'ADD PRIMARY KEY';
} else if ($this.is('.add_index_anchor')) {
addClause = 'ADD INDEX';
} else if ($this.is('.add_unique_anchor')) {
addClause = 'ADD UNIQUE';
} else if ($this.is('.add_spatial_anchor')) {
addClause = 'ADD SPATIAL';
} else if ($this.is('.add_fulltext_anchor')) {
addClause = 'ADD FULLTEXT';
}
var question = Functions.sprintf(Messages.strDoYouReally, 'ALTER TABLE `' + Functions.escapeHtml(currTableName) + '` ' + addClause + '(`' + Functions.escapeHtml(currColumnName) + '`);');
var $thisAnchor = $(this);
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
Functions.ajaxShowMessage();
AJAX.source = $this;
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
params += CommonParams.get('arg_separator') + 'ajax_page_request=1';
$.post(url, params, AJAX.responseHandler);
});
}); // end Add key
/**
* Inline move columns
**/
$(document).on('click', '#move_columns_anchor', function (e) {
e.preventDefault();
var buttonOptionsError = {};
buttonOptionsError[Messages.strOK] = function () {
$(this).dialog('close').remove();
};
var columns = [];
$('#tablestructure').find('tbody tr').each(function () {
var colName = $(this).find('input:checkbox').eq(0).val();
var hiddenInput = $('<input>').prop({
name: 'move_columns[]',
type: 'hidden'
}).val(colName);
columns[columns.length] = $('<li></li>').addClass('placeholderDrag').text(colName).append(hiddenInput);
});
var colList = $('#move_columns_dialog').find('ul').find('li').remove().end();
for (var i in columns) {
colList.append(columns[i]);
}
colList.sortable({
axis: 'y',
containment: $('#move_columns_dialog').find('div'),
tolerance: 'pointer'
}).disableSelection();
var $form = $('#move_columns_dialog').find('form');
$form.data('serialized-unmoved', $form.serialize());
const designerModalPreviewModal = document.getElementById('designerModalPreviewModal');
designerModalPreviewModal.addEventListener('shown.bs.modal', () => {
const modalBody = designerModalPreviewModal.querySelector('.modal-body');
const $form = $('#move_column_form');
const formUrl = $form.attr('action');
const sep = CommonParams.get('arg_separator');
const formData = $form.serialize() + sep + 'preview_sql=1' + sep + 'ajax_request=1';
$.post({
url: formUrl,
data: formData,
success: response => {
if (!response.success) {
modalBody.innerHTML = '<div class="alert alert-danger" role="alert">' + Messages.strErrorProcessingRequest + '</div>';
return;
}
modalBody.innerHTML = response.sql_data;
Functions.highlightSql($('#designerModalPreviewModal'));
},
error: () => {
modalBody.innerHTML = '<div class="alert alert-danger" role="alert">' + Messages.strErrorProcessingRequest + '</div>';
}
});
});
designerModalPreviewModal.addEventListener('hidden.bs.modal', () => {
designerModalPreviewModal.querySelector('.modal-body').innerHTML = '<div class="spinner-border" role="status">' + '<span class="visually-hidden">' + Messages.strLoading + '</span></div>';
});
$('#moveColumnsModal').modal('show');
$('#designerModalGoButton').off('click'); // Unregister previous modals
$('#designerModalGoButton').on('click', function () {
event.preventDefault();
var $msgbox = Functions.ajaxShowMessage();
var $this = $('#moveColumnsModal');
var $form = $this.find('form');
var serialized = $form.serialize();
// check if any columns were moved at all
$('#moveColumnsModal').modal('hide');
if (serialized === $form.data('serialized-unmoved')) {
Functions.ajaxRemoveMessage($msgbox);
return;
}
$.post($form.prop('action'), serialized + CommonParams.get('arg_separator') + 'ajax_request=true', function (data) {
if (data.success === false) {
Functions.ajaxRemoveMessage($msgbox);
var errorModal = $('#moveColumnsErrorModal');
errorModal.modal('show');
errorModal.find('.modal-body').first().html(data.error);
} else {
// sort the fields table
var $fieldsTable = $('table#tablestructure tbody');
// remove all existing rows and remember them
var $rows = $fieldsTable.find('tr').remove();
// loop through the correct order
for (var i in data.columns) {
var theColumn = data.columns[i];
var $theRow = $rows.find('input:checkbox[value=\'' + theColumn + '\']').closest('tr');
// append the row for this column to the table
$fieldsTable.append($theRow);
}
var $firstrow = $fieldsTable.find('tr').eq(0);
// Adjust the row numbers and colors
for (var $row = $firstrow; $row.length > 0; $row = $row.next()) {
$row.find('td').eq(1).text($row.index() + 1).end().removeClass('odd even').addClass($row.index() % 2 === 0 ? 'odd' : 'even');
}
Functions.ajaxShowMessage(data.message);
}
});
});
});
/**
* Handles multi submits in table structure page such as change, browse, drop, primary etc.
*/
$('body').on('click', '#fieldsForm button.mult_submit', function (e) {
e.preventDefault();
var $form = $(this).parents('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post(this.formAction, submitData, AJAX.responseHandler);
});
/**
* Handles clicks on Action links in partition table
*/
$(document).on('click', 'a[id^=partition_action].ajax', function (e) {
e.preventDefault();
var $link = $(this);
function submitPartitionAction(url) {
var params = 'ajax_request=true&ajax_page_request=true&' + $link.getPostData();
Functions.ajaxShowMessage();
AJAX.source = $link;
$.post(url, params, AJAX.responseHandler);
}
if ($link.is('#partition_action_DROP')) {
$link.confirm(Messages.strDropPartitionWarning, $link.attr('href'), function (url) {
submitPartitionAction(url);
});
} else if ($link.is('#partition_action_TRUNCATE')) {
$link.confirm(Messages.strTruncatePartitionWarning, $link.attr('href'), function (url) {
submitPartitionAction(url);
});
} else {
submitPartitionAction($link.attr('href'));
}
});
/**
* Handles remove partitioning
*/
$(document).on('click', '#remove_partitioning.ajax', function (e) {
e.preventDefault();
var $link = $(this);
var question = Messages.strRemovePartitioningWarning;
$link.confirm(question, $link.attr('href'), function (url) {
var params = Functions.getJsConfirmCommonParam({
'ajax_request': true,
'ajax_page_request': true
}, $link.getPostData());
Functions.ajaxShowMessage();
AJAX.source = $link;
$.post(url, params, AJAX.responseHandler);
});
});
$(document).on('change', 'select[name=after_field]', function () {
checkFirst();
});
});

View file

@ -1,123 +0,0 @@
/**
* Unbind all event handlers before tearing down the page
*/
AJAX.registerTeardown('table/tracking.js', function () {
$('body').off('click', '#versionsForm.ajax button[name="submit_mult"], #versionsForm.ajax input[name="submit_mult"]');
$('body').off('click', 'a.delete_version_anchor.ajax');
$('body').off('click', 'a.delete_entry_anchor.ajax');
});
/**
* Bind event handlers
*/
AJAX.registerOnload('table/tracking.js', function () {
$('#versions tr').first().find('th').append($('<div class="sorticon"></div>'));
$('#versions').tablesorter({
sortList: [[1, 0]],
headers: {
0: {
sorter: false
},
1: {
sorter: 'integer'
},
5: {
sorter: false
},
6: {
sorter: false
}
}
});
if ($('#ddl_versions tbody tr').length > 0) {
$('#ddl_versions tr').first().find('th').append($('<div class="sorticon"></div>'));
$('#ddl_versions').tablesorter({
sortList: [[0, 0]],
headers: {
0: {
sorter: 'integer'
},
3: {
sorter: false
},
4: {
sorter: false
}
}
});
}
if ($('#dml_versions tbody tr').length > 0) {
$('#dml_versions tr').first().find('th').append($('<div class="sorticon"></div>'));
$('#dml_versions').tablesorter({
sortList: [[0, 0]],
headers: {
0: {
sorter: 'integer'
},
3: {
sorter: false
},
4: {
sorter: false
}
}
});
}
/**
* Handles multi submit for tracking versions
*/
$('body').on('click', '#versionsForm.ajax button[name="submit_mult"], #versionsForm.ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
if ($button.val() === 'delete_version') {
var question = Messages.strDeleteTrackingVersionMultiple;
$button.confirm(question, $form.attr('action'), function (url) {
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post(url, submitData, AJAX.responseHandler);
});
} else {
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
}
});
/**
* Ajax Event handler for 'Delete version'
*/
$('body').on('click', 'a.delete_version_anchor.ajax', function (e) {
e.preventDefault();
var $anchor = $(this);
var question = Messages.strDeleteTrackingVersion;
$anchor.confirm(question, $anchor.attr('href'), function (url) {
Functions.ajaxShowMessage();
AJAX.source = $anchor;
var argSep = CommonParams.get('arg_separator');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
params += argSep + 'ajax_page_request=1';
$.post(url, params, AJAX.responseHandler);
});
});
/**
* Ajax Event handler for 'Delete tracking report entry'
*/
$('body').on('click', 'a.delete_entry_anchor.ajax', function (e) {
e.preventDefault();
var $anchor = $(this);
var question = Messages.strDeletingTrackingEntry;
$anchor.confirm(question, $anchor.attr('href'), function (url) {
Functions.ajaxShowMessage();
AJAX.source = $anchor;
var argSep = CommonParams.get('arg_separator');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
params += argSep + 'ajax_page_request=1';
$.post(url, params, AJAX.responseHandler);
});
});
});

View file

@ -1,590 +0,0 @@
// TODO: change the axis
/**
* @fileoverview JavaScript functions used on /table/search
*
* @requires jQuery
* @requires js/functions.js
**/
/* global changeValueFieldType, verifyAfterSearchFieldChange */ // js/table/change.js
/**
* Display Help/Info
* @return {false}
**/
function displayHelp() {
var modal = $('#helpModal');
modal.modal('show');
modal.find('.modal-body').first().html(Messages.strDisplayHelp);
$('#helpModalLabel').first().html(Messages.strHelpTitle);
return false;
}
/**
* Extend the array object for max function
* @param {number[]} array
* @return {int}
**/
Array.max = function (array) {
return Math.max.apply(Math, array);
};
/**
* Extend the array object for min function
* @param {number[]} array
* @return {int}
**/
Array.min = function (array) {
return Math.min.apply(Math, array);
};
/**
* Checks if a string contains only numeric value
* @param {string} n (to be checked)
* @return {bool}
**/
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
/**
** Checks if an object is empty
* @param {object} obj (to be checked)
* @return {bool}
**/
function isEmpty(obj) {
var name;
for (name in obj) {
return false;
}
return true;
}
/**
* Converts a date/time into timestamp
* @param {string} val Date
* @param {string} type Field type(datetime/timestamp/time/date)
* @return {any} A value
**/
function getTimeStamp(val, type) {
if (type.toString().search(/datetime/i) !== -1 || type.toString().search(/timestamp/i) !== -1) {
return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', val);
} else if (type.toString().search(/time/i) !== -1) {
return $.datepicker.parseDateTime('yy-mm-dd', 'HH:mm:ss', '1970-01-01 ' + val);
} else if (type.toString().search(/date/i) !== -1) {
return $.datepicker.parseDate('yy-mm-dd', val);
}
}
/**
* Classifies the field type into numeric,timeseries or text
* @param {object} field field type (as in database structure)
* @return {'text'|'numeric'|'time'}
**/
function getType(field) {
if (field.toString().search(/int/i) !== -1 || field.toString().search(/decimal/i) !== -1 || field.toString().search(/year/i) !== -1) {
return 'numeric';
} else if (field.toString().search(/time/i) !== -1 || field.toString().search(/date/i) !== -1) {
return 'time';
} else {
return 'text';
}
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('table/zoom_plot_jqplot.js', function () {
$('#tableid_0').off('change');
$('#tableid_1').off('change');
$('#tableid_2').off('change');
$('#tableid_3').off('change');
$('#inputFormSubmitId').off('click');
$('#togglesearchformlink').off('click');
$(document).off('keydown', '#dataDisplay :input');
$('button.button-reset').off('click');
$('div#resizer').off('resizestop');
$('div#querychart').off('jqplotDataClick');
});
AJAX.registerOnload('table/zoom_plot_jqplot.js', function () {
var currentChart = null;
var searchedDataKey = null;
var xLabel = $('#tableid_0').val();
var yLabel = $('#tableid_1').val();
// will be updated via Ajax
var xType = $('#types_0').val();
var yType = $('#types_1').val();
var dataLabel = $('#dataLabel').val();
// Get query result
var searchedData;
try {
searchedData = JSON.parse($('#querydata').html());
} catch (err) {
searchedData = null;
}
// adding event listener on select after AJAX request
var comparisonOperatorOnChange = function () {
var tableRows = $('#inputSection select.column-operator');
$.each(tableRows, function (index, item) {
$(item).on('change', function () {
changeValueFieldType(this, index);
verifyAfterSearchFieldChange(index, '#zoom_search_form');
});
});
};
/**
** Input form submit on field change
**/
// first column choice corresponds to the X axis
$('#tableid_0').on('change', function () {
// AJAX request for field type, collation, operators, and value field
$.post('index.php?route=/table/zoom-search', {
'ajax_request': true,
'change_tbl_info': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'field': $('#tableid_0').val(),
'it': 0
}, function (data) {
$('#tableFieldsId').find('tr').eq(1).find('td').eq(0).html(data.field_type);
$('#tableFieldsId').find('tr').eq(1).find('td').eq(1).html(data.field_collation);
$('#tableFieldsId').find('tr').eq(1).find('td').eq(2).html(data.field_operators);
$('#tableFieldsId').find('tr').eq(1).find('td').eq(3).html(data.field_value);
xLabel = $('#tableid_0').val();
$('#types_0').val(data.field_type);
xType = data.field_type;
$('#collations_0').val(data.field_collations);
comparisonOperatorOnChange();
Functions.addDateTimePicker();
});
});
// second column choice corresponds to the Y axis
$('#tableid_1').on('change', function () {
// AJAX request for field type, collation, operators, and value field
$.post('index.php?route=/table/zoom-search', {
'ajax_request': true,
'change_tbl_info': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'field': $('#tableid_1').val(),
'it': 1
}, function (data) {
$('#tableFieldsId').find('tr').eq(2).find('td').eq(0).html(data.field_type);
$('#tableFieldsId').find('tr').eq(2).find('td').eq(1).html(data.field_collation);
$('#tableFieldsId').find('tr').eq(2).find('td').eq(2).html(data.field_operators);
$('#tableFieldsId').find('tr').eq(2).find('td').eq(3).html(data.field_value);
yLabel = $('#tableid_1').val();
$('#types_1').val(data.field_type);
yType = data.field_type;
$('#collations_1').val(data.field_collations);
comparisonOperatorOnChange();
Functions.addDateTimePicker();
});
});
$('#tableid_2').on('change', function () {
// AJAX request for field type, collation, operators, and value field
$.post('index.php?route=/table/zoom-search', {
'ajax_request': true,
'change_tbl_info': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'field': $('#tableid_2').val(),
'it': 2
}, function (data) {
$('#tableFieldsId').find('tr').eq(4).find('td').eq(0).html(data.field_type);
$('#tableFieldsId').find('tr').eq(4).find('td').eq(1).html(data.field_collation);
$('#tableFieldsId').find('tr').eq(4).find('td').eq(2).html(data.field_operators);
$('#tableFieldsId').find('tr').eq(4).find('td').eq(3).html(data.field_value);
$('#types_2').val(data.field_type);
$('#collations_2').val(data.field_collations);
comparisonOperatorOnChange();
Functions.addDateTimePicker();
});
});
$('#tableid_3').on('change', function () {
// AJAX request for field type, collation, operators, and value field
$.post('index.php?route=/table/zoom-search', {
'ajax_request': true,
'change_tbl_info': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'field': $('#tableid_3').val(),
'it': 3
}, function (data) {
$('#tableFieldsId').find('tr').eq(5).find('td').eq(0).html(data.field_type);
$('#tableFieldsId').find('tr').eq(5).find('td').eq(1).html(data.field_collation);
$('#tableFieldsId').find('tr').eq(5).find('td').eq(2).html(data.field_operators);
$('#tableFieldsId').find('tr').eq(5).find('td').eq(3).html(data.field_value);
$('#types_3').val(data.field_type);
$('#collations_3').val(data.field_collations);
comparisonOperatorOnChange();
Functions.addDateTimePicker();
});
});
/**
* Input form validation
**/
$('#inputFormSubmitId').on('click', function () {
if ($('#tableid_0').get(0).selectedIndex === 0 || $('#tableid_1').get(0).selectedIndex === 0) {
Functions.ajaxShowMessage(Messages.strInputNull);
} else if (xLabel === yLabel) {
Functions.ajaxShowMessage(Messages.strSameInputs);
}
});
/**
** Prepare a div containing a link, otherwise it's incorrectly displayed
** after a couple of clicks
**/
$('<div id="togglesearchformdiv"><a id="togglesearchformlink"></a></div>').insertAfter('#zoom_search_form')
// don't show it until we have results on-screen
.hide();
$('#togglesearchformlink').html(Messages.strShowSearchCriteria).on('click', function () {
var $link = $(this);
$('#zoom_search_form').slideToggle();
if ($link.text() === Messages.strHideSearchCriteria) {
$link.text(Messages.strShowSearchCriteria);
} else {
$link.text(Messages.strHideSearchCriteria);
}
// avoid default click action
return false;
});
/**
* Handle saving of a row in the editor
*/
var dataPointSave = function () {
// Find changed values by comparing form values with selectedRow Object
var newValues = {}; // Stores the values changed from original
var sqlTypes = {};
var it = 0;
var xChange = false;
var yChange = false;
var key;
var tempGetVal = function () {
return $(this).val();
};
for (key in selectedRow) {
var oldVal = selectedRow[key];
var newVal = $('#edit_fields_null_id_' + it).prop('checked') ? null : $('#edit_fieldID_' + it).val();
if (newVal instanceof Array) {
// when the column is of type SET
newVal = $('#edit_fieldID_' + it).map(tempGetVal).get().join(',');
}
if (oldVal !== newVal) {
selectedRow[key] = newVal;
newValues[key] = newVal;
if (key === xLabel) {
xChange = true;
searchedData[searchedDataKey][xLabel] = newVal;
} else if (key === yLabel) {
yChange = true;
searchedData[searchedDataKey][yLabel] = newVal;
}
}
var $input = $('#edit_fieldID_' + it);
if ($input.hasClass('bit')) {
sqlTypes[key] = 'bit';
} else {
sqlTypes[key] = null;
}
it++;
} // End data update
// Update the chart series and replot
if (xChange || yChange) {
// Logic similar to plot generation, replot only if xAxis changes or yAxis changes.
// Code includes a lot of checks so as to replot only when necessary
if (xChange) {
xCord[searchedDataKey] = selectedRow[xLabel];
// [searchedDataKey][0] contains the x value
if (xType === 'numeric') {
series[0][searchedDataKey][0] = selectedRow[xLabel];
} else if (xType === 'time') {
series[0][searchedDataKey][0] = getTimeStamp(selectedRow[xLabel], $('#types_0').val());
} else {
series[0][searchedDataKey][0] = '';
// TODO: text values
}
currentChart.series[0].data = series[0];
// TODO: axis changing
currentChart.replot();
}
if (yChange) {
yCord[searchedDataKey] = selectedRow[yLabel];
// [searchedDataKey][1] contains the y value
if (yType === 'numeric') {
series[0][searchedDataKey][1] = selectedRow[yLabel];
} else if (yType === 'time') {
series[0][searchedDataKey][1] = getTimeStamp(selectedRow[yLabel], $('#types_1').val());
} else {
series[0][searchedDataKey][1] = '';
// TODO: text values
}
currentChart.series[0].data = series[0];
// TODO: axis changing
currentChart.replot();
}
} // End plot update
// Generate SQL query for update
if (!isEmpty(newValues)) {
var sqlQuery = 'UPDATE `' + CommonParams.get('table') + '` SET ';
for (key in newValues) {
sqlQuery += '`' + key + '`=';
var value = newValues[key];
// null
if (value === null) {
sqlQuery += 'NULL, ';
// empty
} else if (value.trim() === '') {
sqlQuery += '\'\', ';
// other
} else {
// type explicitly identified
if (sqlTypes[key] !== null) {
if (sqlTypes[key] === 'bit') {
sqlQuery += 'b\'' + value + '\', ';
}
// type not explicitly identified
} else {
if (!isNumeric(value)) {
sqlQuery += '\'' + value + '\', ';
} else {
sqlQuery += value + ', ';
}
}
}
}
// remove two extraneous characters ', '
sqlQuery = sqlQuery.substring(0, sqlQuery.length - 2);
sqlQuery += ' WHERE ' + Sql.urlDecode(searchedData[searchedDataKey].where_clause);
$.post('index.php?route=/sql', {
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'ajax_request': true,
'sql_query': sqlQuery,
'inline_edit': false
}, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
$('#sqlqueryresultsouter').html(data.sql_query);
Functions.highlightSql($('#sqlqueryresultsouter'));
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // End $.post
} // End database update
};
$('#dataPointSaveButton').on('click', function () {
dataPointSave();
});
$('#dataPointModalLabel').first().html(Messages.strDataPointContent);
/**
* Attach Ajax event handlers for input fields
* in the dialog. Used to submit the Ajax
* request when the ENTER key is pressed.
*/
$(document).on('keydown', '#dataDisplay :input', function (e) {
if (e.which === 13) {
// 13 is the ENTER key
e.preventDefault();
if (typeof dataPointSave === 'function') {
dataPointSave();
}
}
});
/*
* Generate plot using jqplot
*/
if (searchedData !== null) {
$('#zoom_search_form').slideToggle().hide();
$('#togglesearchformlink').text(Messages.strShowSearchCriteria);
$('#togglesearchformdiv').show();
var selectedRow;
var series = [];
var xCord = [];
var yCord = [];
var xVal;
var yVal;
var format;
var options = {
series: [
// for a scatter plot
{
showLine: false
}],
grid: {
drawBorder: false,
shadow: false,
background: 'rgba(0,0,0,0)'
},
axes: {
xaxis: {
label: $('#tableid_0').val(),
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
},
yaxis: {
label: $('#tableid_1').val(),
labelRenderer: $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'y',
yvalues: 2,
// hide the first y value
formatString: '<span class="hide">%s</span>%s'
},
cursor: {
show: true,
zoom: true,
showTooltip: false
}
};
// If data label is not set, do not show tooltips
if (dataLabel === '') {
options.highlighter.show = false;
}
// Classify types as either numeric,time,text
xType = getType(xType);
yType = getType(yType);
// could have multiple series but we'll have just one
series[0] = [];
if (xType === 'time') {
var originalXType = $('#types_0').val();
if (originalXType === 'date') {
format = '%Y-%m-%d';
}
// TODO: does not seem to work
// else if (originalXType === 'time') {
// format = '%H:%M';
// } else {
// format = '%Y-%m-%d %H:%M';
// }
$.extend(options.axes.xaxis, {
renderer: $.jqplot.DateAxisRenderer,
tickOptions: {
formatString: format
}
});
}
if (yType === 'time') {
var originalYType = $('#types_1').val();
if (originalYType === 'date') {
format = '%Y-%m-%d';
}
$.extend(options.axes.yaxis, {
renderer: $.jqplot.DateAxisRenderer,
tickOptions: {
formatString: format
}
});
}
$.each(searchedData, function (key, value) {
if (xType === 'numeric') {
xVal = parseFloat(value[xLabel]);
}
if (xType === 'time') {
xVal = getTimeStamp(value[xLabel], originalXType);
}
if (yType === 'numeric') {
yVal = parseFloat(value[yLabel]);
}
if (yType === 'time') {
yVal = getTimeStamp(value[yLabel], originalYType);
}
series[0].push([xVal, yVal,
// extra Y values
value[dataLabel],
// for highlighter
// (may set an undefined value)
value.where_clause,
// for click on point
key,
// key from searchedData
value.where_clause_sign]);
});
// under IE 8, the initial display is mangled; after a manual
// resizing, it's ok
// under IE 9, everything is fine
currentChart = $.jqplot('querychart', series, options);
currentChart.resetZoom();
$('button.button-reset').on('click', function (event) {
event.preventDefault();
currentChart.resetZoom();
});
$('div#resizer').resizable();
$('div#resizer').on('resizestop', function () {
// make room so that the handle will still appear
$('div#querychart').height($('div#resizer').height() * 0.96);
$('div#querychart').width($('div#resizer').width() * 0.96);
currentChart.replot({
resetAxes: true
});
});
$('div#querychart').on('jqplotDataClick', function (event, seriesIndex, pointIndex, data) {
searchedDataKey = data[4]; // key from searchedData (global)
var fieldId = 0;
var postParams = {
'ajax_request': true,
'get_data_row': true,
'server': CommonParams.get('server'),
'db': CommonParams.get('db'),
'table': CommonParams.get('table'),
'where_clause': data[3],
'where_clause_sign': data[5]
};
$.post('index.php?route=/table/zoom-search', postParams, function (data) {
// Row is contained in data.row_info,
// now fill the displayResultForm with row values
var key;
for (key in data.row_info) {
var $field = $('#edit_fieldID_' + fieldId);
var $fieldNull = $('#edit_fields_null_id_' + fieldId);
if (data.row_info[key] === null) {
$fieldNull.prop('checked', true);
$field.val('');
} else {
$fieldNull.prop('checked', false);
if ($field.attr('multiple')) {
// when the column is of type SET
$field.val(data.row_info[key].split(','));
} else {
$field.val(data.row_info[key]);
}
}
fieldId++;
}
selectedRow = data.row_info;
});
$('#dataPointModal').modal('show');
});
}
$('#help_dialog').on('click', function () {
displayHelp();
});
});

View file

@ -1,27 +0,0 @@
/**
* Image upload transformations plugin js
*
* @package PhpMyAdmin
*/
AJAX.registerOnload('transformations/image_upload.js', function () {
// Change thumbnail when image file is selected
// through file upload dialog
$('input.image-upload').on('change', function () {
if (this.files && this.files[0]) {
var reader = new FileReader();
var $input = $(this);
reader.onload = function (e) {
$input.prevAll('img').attr('src', e.target.result);
};
reader.readAsDataURL(this.files[0]);
}
});
});
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('transformations/image_upload.js', function () {
$('input.image-upload').off('change');
});

View file

@ -1,17 +0,0 @@
/**
* JSON syntax highlighting transformation plugin
*/
AJAX.registerOnload('transformations/json.js', function () {
var $elm = $('#page_content').find('code.json');
$elm.each(function () {
var $json = $(this);
var $pre = $json.find('pre');
/* We only care about visible elements to avoid double processing */
if ($pre.is(':visible')) {
var $highlight = $('<div class="json-highlight cm-s-default"></div>');
$json.append($highlight);
CodeMirror.runMode($json.text(), 'application/json', $highlight[0]);
$pre.hide();
}
});
});

View file

@ -1,16 +0,0 @@
/**
* JSON syntax highlighting transformation plugin
*
* @package PhpMyAdmin
*/
AJAX.registerOnload('transformations/json_editor.js', function () {
$('textarea.transform_json_editor').each(function () {
CodeMirror.fromTextArea(this, {
lineNumbers: true,
matchBrackets: true,
indentUnit: 4,
mode: 'application/json',
lineWrapping: true
});
});
});

View file

@ -1,10 +0,0 @@
/**
* SQL syntax highlighting transformation plugin js
*
* @package PhpMyAdmin
*/
AJAX.registerOnload('transformations/sql_editor.js', function () {
$('textarea.transform_sql_editor').each(function () {
Functions.getSqlEditor($(this), {}, 'both');
});
});

View file

@ -1,17 +0,0 @@
/**
* XML syntax highlighting transformation plugin
*/
AJAX.registerOnload('transformations/xml.js', function () {
var $elm = $('#page_content').find('code.xml');
$elm.each(function () {
var $json = $(this);
var $pre = $json.find('pre');
/* We only care about visible elements to avoid double processing */
if ($pre.is(':visible')) {
var $highlight = $('<div class="xml-highlight cm-s-default"></div>');
$json.append($highlight);
CodeMirror.runMode($json.text(), 'application/xml', $highlight[0]);
$pre.hide();
}
});
});

View file

@ -1,15 +0,0 @@
/**
* XML editor plugin
*
* @package PhpMyAdmin
*/
AJAX.registerOnload('transformations/xml_editor.js', function () {
$('textarea.transform_xml_editor').each(function () {
CodeMirror.fromTextArea(this, {
lineNumbers: true,
indentUnit: 4,
mode: 'application/xml',
lineWrapping: true
});
});
});

View file

@ -1,77 +0,0 @@
/* global u2f */ // js/vendor/u2f-api-polyfill.js
AJAX.registerOnload('u2f.js', function () {
var $inputReg = $('#u2f_registration_response');
if ($inputReg.length > 0) {
var $formReg = $inputReg.parents('form');
$formReg.find('input[type=submit]').hide();
setTimeout(function () {
// A magic JS function that talks to the USB device. This function will keep polling for the USB device until it finds one.
var request = JSON.parse($inputReg.attr('data-request'));
u2f.register(request.appId, [request], JSON.parse($inputReg.attr('data-signatures')), function (data) {
// Handle returning error data
if (data.errorCode && data.errorCode !== 0) {
switch (data.errorCode) {
case 5:
Functions.ajaxShowMessage(Messages.strU2FTimeout, false, 'error');
break;
case 4:
Functions.ajaxShowMessage(Messages.strU2FErrorRegister, false, 'error');
break;
case 3:
Functions.ajaxShowMessage(Messages.strU2FInvalidClient, false, 'error');
break;
case 2:
Functions.ajaxShowMessage(Messages.strU2FBadRequest, false, 'error');
break;
default:
Functions.ajaxShowMessage(Messages.strU2FUnknown, false, 'error');
break;
}
return;
}
// Fill and submit form.
$inputReg.val(JSON.stringify(data));
$formReg.trigger('submit');
});
}, 1000);
}
var $inputAuth = $('#u2f_authentication_response');
if ($inputAuth.length > 0) {
var $formAuth = $inputAuth.parents('form');
$formAuth.find('input[type=submit]').hide();
setTimeout(function () {
// Magic JavaScript talking to your HID
// appid, challenge, authenticateRequests
var request = JSON.parse($inputAuth.attr('data-request'));
u2f.sign(request[0].appId, request[0].challenge, request, function (data) {
// Handle returning error data
if (data.errorCode && data.errorCode !== 0) {
switch (data.errorCode) {
case 5:
Functions.ajaxShowMessage(Messages.strU2FTimeout, false, 'error');
break;
case 4:
Functions.ajaxShowMessage(Messages.strU2FErrorAuthenticate, false, 'error');
break;
case 3:
Functions.ajaxShowMessage(Messages.strU2FInvalidClient, false, 'error');
break;
case 2:
Functions.ajaxShowMessage(Messages.strU2FBadRequest, false, 'error');
break;
default:
Functions.ajaxShowMessage(Messages.strU2FUnknown, false, 'error');
break;
}
return;
}
// Fill and submit form.
$inputAuth.val(JSON.stringify(data));
$formAuth.trigger('submit');
});
}, 1000);
}
});

View file

@ -1,119 +0,0 @@
/**
* @param {ArrayBuffer} buffer
*
* @return {string}
*/
const arrayBufferToBase64 = buffer => {
const bytes = new Uint8Array(buffer);
let string = '';
for (const byte of bytes) {
string += String.fromCharCode(byte);
}
return window.btoa(string);
};
/**
* @param {string} string
*
* @return {Uint8Array}
*/
const base64ToUint8Array = string => {
return Uint8Array.from(window.atob(string), char => char.charCodeAt(0));
};
/**
* @param {JQuery<HTMLElement>} $input
*
* @return {void}
*/
const handleCreation = $input => {
const $form = $input.parents('form');
$form.find('input[type=submit]').hide();
const creationOptionsJson = $input.attr('data-creation-options');
const creationOptions = JSON.parse(creationOptionsJson);
const publicKey = creationOptions;
publicKey.challenge = base64ToUint8Array(creationOptions.challenge);
publicKey.user.id = base64ToUint8Array(creationOptions.user.id);
if (creationOptions.excludeCredentials) {
const excludedCredentials = [];
for (let value of creationOptions.excludeCredentials) {
let excludedCredential = value;
excludedCredential.id = base64ToUint8Array(value.id);
excludedCredentials.push(excludedCredential);
}
publicKey.excludeCredentials = excludedCredentials;
}
// eslint-disable-next-line compat/compat
navigator.credentials.create({
publicKey: publicKey
}).then(credential => {
const credentialJson = JSON.stringify({
id: credential.id,
rawId: arrayBufferToBase64(credential.rawId),
type: credential.type,
response: {
clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON),
attestationObject: arrayBufferToBase64(credential.response.attestationObject)
}
});
$input.val(credentialJson);
$form.trigger('submit');
}).catch(error => Functions.ajaxShowMessage(error, false, 'error'));
};
/**
* @param {JQuery<HTMLElement>} $input
*
* @return {void}
*/
const handleRequest = $input => {
const $form = $input.parents('form');
$form.find('input[type=submit]').hide();
const requestOptionsJson = $input.attr('data-request-options');
const requestOptions = JSON.parse(requestOptionsJson);
const publicKey = requestOptions;
publicKey.challenge = base64ToUint8Array(requestOptions.challenge);
if (requestOptions.allowCredentials) {
const allowedCredentials = [];
for (let value of requestOptions.allowCredentials) {
let allowedCredential = value;
allowedCredential.id = base64ToUint8Array(value.id);
allowedCredentials.push(allowedCredential);
}
publicKey.allowCredentials = allowedCredentials;
}
// eslint-disable-next-line compat/compat
navigator.credentials.get({
publicKey: publicKey
}).then(credential => {
const credentialJson = JSON.stringify({
id: credential.id,
rawId: arrayBufferToBase64(credential.rawId),
type: credential.type,
response: {
authenticatorData: arrayBufferToBase64(credential.response.authenticatorData),
clientDataJSON: arrayBufferToBase64(credential.response.clientDataJSON),
signature: arrayBufferToBase64(credential.response.signature),
userHandle: arrayBufferToBase64(credential.response.userHandle)
}
});
$input.val(credentialJson);
$form.trigger('submit');
}).catch(error => Functions.ajaxShowMessage(error, false, 'error'));
};
AJAX.registerOnload('webauthn.js', function () {
if (!navigator.credentials || !navigator.credentials.create || !navigator.credentials.get || !window.PublicKeyCredential) {
Functions.ajaxShowMessage(Messages.webAuthnNotSupported, false, 'error');
return;
}
const $creationInput = $('#webauthn_creation_response');
if ($creationInput.length > 0) {
handleCreation($creationInput);
}
const $requestInput = $('#webauthn_request_response');
if ($requestInput.length > 0) {
handleRequest($requestInput);
}
});

View file

@ -1,67 +0,0 @@
<?php
declare(strict_types=1);
use PhpMyAdmin\Common;
use PhpMyAdmin\Controllers\JavaScriptMessagesController;
use PhpMyAdmin\OutputBuffering;
/** @psalm-suppress InvalidGlobal */
global $containerBuilder;
if (! defined('ROOT_PATH')) {
// phpcs:disable PSR1.Files.SideEffects
define('ROOT_PATH', dirname(__DIR__) . DIRECTORY_SEPARATOR);
// phpcs:enable
}
if (PHP_VERSION_ID < 70205) {
die('<p>PHP 7.2.5+ is required.</p><p>Currently installed version is: ' . PHP_VERSION . '</p>');
}
// phpcs:disable PSR1.Files.SideEffects
define('PHPMYADMIN', true);
// phpcs:enable
require_once ROOT_PATH . 'libraries/constants.php';
/**
* Activate autoloader
*/
if (! @is_readable(AUTOLOAD_FILE)) {
die(
'<p>File <samp>' . AUTOLOAD_FILE . '</samp> missing or not readable.</p>'
. '<p>Most likely you did not run Composer to '
. '<a href="https://docs.phpmyadmin.net/en/latest/setup.html#installing-from-git">'
. 'install library files</a>.</p>'
);
}
require AUTOLOAD_FILE;
chdir('..');
// Send correct type.
header('Content-Type: text/javascript; charset=UTF-8');
// Cache output in client - the nocache query parameter makes sure that this file is reloaded when config changes.
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 3600) . ' GMT');
$isMinimumCommon = true;
// phpcs:disable PSR1.Files.SideEffects
define('PMA_PATH_TO_BASEDIR', '../');
define('PMA_NO_SESSION', true);
// phpcs:enable
Common::run();
$buffer = OutputBuffering::getInstance();
$buffer->start();
register_shutdown_function(static function (): void {
echo OutputBuffering::getInstance()->getContents();
});
/** @var JavaScriptMessagesController $controller */
$controller = $containerBuilder->get(JavaScriptMessagesController::class);
$controller();

View file

@ -1,924 +0,0 @@
/**
* This object handles ajax requests for pages. It also
* handles the reloading of the main menu and scripts.
*
* @test-module AJAX
*/
var AJAX = {
/**
* @var {boolean} active Whether we are busy
*/
active: false,
/**
* @var {object} source The object whose event initialized the request
*/
source: null,
/**
* @var {object} xhr A reference to the ajax request that is currently running
*/
xhr: null,
/**
* @var {object} lockedTargets, list of locked targets
*/
lockedTargets: {},
// eslint-disable-next-line valid-jsdoc
/**
* @var {Function} callback Callback to execute after a successful request
* Used by CommonActions from common.js
*/
callback: function () {},
/**
* @var {boolean} debug Makes noise in your Firebug console
*/
debug: false,
/**
* @var {object} $msgbox A reference to a jQuery object that links to a message
* box that is generated by Functions.ajaxShowMessage()
*/
$msgbox: null,
/**
* Given the filename of a script, returns a hash to be
* used to refer to all the events registered for the file
*
* @param {string} key key The filename for which to get the event name
*
* @return {number}
*/
hash: function (key) {
var newKey = key;
/* https://burtleburtle.net/bob/hash/doobs.html#one */
newKey += '';
var len = newKey.length;
var hash = 0;
var i = 0;
for (; i < len; ++i) {
hash += newKey.charCodeAt(i);
hash += (hash << 10);
hash ^= (hash >> 6);
}
hash += (hash << 3);
hash ^= (hash >> 11);
hash += (hash << 15);
return Math.abs(hash);
},
/**
* Registers an onload event for a file
*
* @param {string} file The filename for which to register the event
* @param {Function} func The function to execute when the page is ready
*
* @return {self} For chaining
*/
registerOnload: function (file, func) {
var eventName = 'onload_' + AJAX.hash(file);
$(document).on(eventName, func);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file
);
}
return this;
},
/**
* Registers a teardown event for a file. This is useful to execute functions
* that unbind events for page elements that are about to be removed.
*
* @param {string} file The filename for which to register the event
* @param {Function} func The function to execute when
* the page is about to be torn down
*
* @return {self} For chaining
*/
registerTeardown: function (file, func) {
var eventName = 'teardown_' + AJAX.hash(file);
$(document).on(eventName, func);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Registered event ' + eventName + ' for file ' + file
);
}
return this;
},
/**
* Called when a page has finished loading, once for every
* file that registered to the onload event of that file.
*
* @param {string} file The filename for which to fire the event
*
* @return {void}
*/
fireOnload: function (file) {
var eventName = 'onload_' + AJAX.hash(file);
$(document).trigger(eventName);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file
);
}
},
/**
* Called just before a page is torn down, once for every
* file that registered to the teardown event of that file.
*
* @param {string} file The filename for which to fire the event
*
* @return {void}
*/
fireTeardown: function (file) {
var eventName = 'teardown_' + AJAX.hash(file);
$(document).triggerHandler(eventName);
if (this.debug) {
// eslint-disable-next-line no-console
console.log(
// no need to translate
'Fired event ' + eventName + ' for file ' + file
);
}
},
/**
* function to handle lock page mechanism
*
* @param event the event object
*
* @return {void}
*/
lockPageHandler: function (event) {
// don't consider checkbox event
if (typeof event.target !== 'undefined') {
if (event.target.type === 'checkbox') {
return;
}
}
var newHash = null;
var oldHash = null;
var lockId;
// CodeMirror lock
if (event.data.value === 3) {
newHash = event.data.content;
oldHash = true;
lockId = 'cm';
} else {
// Don't lock on enter.
if (0 === event.charCode) {
return;
}
lockId = $(this).data('lock-id');
if (typeof lockId === 'undefined') {
return;
}
/*
* @todo Fix Code mirror does not give correct full value (query)
* in textarea, it returns only the change in content.
*/
if (event.data.value === 1) {
newHash = AJAX.hash($(this).val());
} else {
newHash = AJAX.hash($(this).is(':checked'));
}
oldHash = $(this).data('val-hash');
}
// Set lock if old value !== new value
// otherwise release lock
if (oldHash !== newHash) {
AJAX.lockedTargets[lockId] = true;
} else {
delete AJAX.lockedTargets[lockId];
}
// Show lock icon if locked targets is not empty.
// otherwise remove lock icon
if (!jQuery.isEmptyObject(AJAX.lockedTargets)) {
$('#lock_page_icon').html(Functions.getImage('s_lock', Messages.strLockToolTip).toString());
} else {
$('#lock_page_icon').html('');
}
},
/**
* resets the lock
*
* @return {void}
*/
resetLock: function () {
AJAX.lockedTargets = {};
$('#lock_page_icon').html('');
},
handleMenu: {
replace: function (content) {
$('#floating_menubar').html(content)
// Remove duplicate wrapper
// TODO: don't send it in the response
.children().first().remove();
$('#topmenu').menuResizer(Functions.mainMenuResizerCallback);
}
},
/**
* Event handler for clicks on links and form submissions
*
* @param {KeyboardEvent} event Event data
*
* @return {boolean | void}
*/
requestHandler: function (event) {
// In some cases we don't want to handle the request here and either
// leave the browser deal with it natively (e.g: file download)
// or leave an existing ajax event handler present elsewhere deal with it
var href = $(this).attr('href');
if (typeof event !== 'undefined' && (event.shiftKey || event.ctrlKey || event.metaKey)) {
return true;
} else if ($(this).attr('target')) {
return true;
} else if ($(this).hasClass('ajax') || $(this).hasClass('disableAjax')) {
// reset the lockedTargets object, as specified AJAX operation has finished
AJAX.resetLock();
return true;
} else if (href && href.match(/^#/)) {
return true;
} else if (href && href.match(/^mailto/)) {
return true;
} else if ($(this).hasClass('ui-datepicker-next') ||
$(this).hasClass('ui-datepicker-prev')
) {
return true;
}
if (typeof event !== 'undefined') {
event.preventDefault();
event.stopImmediatePropagation();
}
// triggers a confirm dialog if:
// the user has performed some operations on loaded page
// the user clicks on some link, (won't trigger for buttons)
// the click event is not triggered by script
if (typeof event !== 'undefined' && event.type === 'click' &&
event.isTrigger !== true &&
!jQuery.isEmptyObject(AJAX.lockedTargets) &&
confirm(Messages.strConfirmNavigation) === false
) {
return false;
}
AJAX.resetLock();
var isLink = !! href || false;
var previousLinkAborted = false;
if (AJAX.active === true) {
// Cancel the old request if abortable, when the user requests
// something else. Otherwise silently bail out, as there is already
// a request well in progress.
if (AJAX.xhr) {
// In case of a link request, attempt aborting
AJAX.xhr.abort();
if (AJAX.xhr.status === 0 && AJAX.xhr.statusText === 'abort') {
// If aborted
AJAX.$msgbox = Functions.ajaxShowMessage(Messages.strAbortedRequest);
AJAX.active = false;
AJAX.xhr = null;
previousLinkAborted = true;
} else {
// If can't abort
return false;
}
} else {
// In case submitting a form, don't attempt aborting
return false;
}
}
AJAX.source = $(this);
$('html, body').animate({ scrollTop: 0 }, 'fast');
var url = isLink ? href : $(this).attr('action');
var argsep = CommonParams.get('arg_separator');
var params = 'ajax_request=true' + argsep + 'ajax_page_request=true';
var dataPost = AJAX.source.getPostData();
if (! isLink) {
params += argsep + $(this).serialize();
} else if (dataPost) {
params += argsep + dataPost;
isLink = false;
}
if (AJAX.debug) {
// eslint-disable-next-line no-console
console.log('Loading: ' + url); // no need to translate
}
if (isLink) {
AJAX.active = true;
AJAX.$msgbox = Functions.ajaxShowMessage();
// Save reference for the new link request
AJAX.xhr = $.get(url, params, AJAX.responseHandler);
var state = {
url : href
};
if (previousLinkAborted) {
// hack: there is already an aborted entry on stack
// so just modify the aborted one
history.replaceState(state, null, href);
} else {
history.pushState(state, null, href);
}
} else {
/**
* Manually fire the onsubmit event for the form, if any.
* The event was saved in the jQuery data object by an onload
* handler defined below. Workaround for bug #3583316
*/
var onsubmit = $(this).data('onsubmit');
// Submit the request if there is no onsubmit handler
// or if it returns a value that evaluates to true
if (typeof onsubmit !== 'function' || onsubmit.apply(this, [event])) {
AJAX.active = true;
AJAX.$msgbox = Functions.ajaxShowMessage();
if ($(this).attr('id') === 'login_form') {
$.post(url, params, AJAX.loginResponseHandler);
} else {
$.post(url, params, AJAX.responseHandler);
}
}
}
},
/**
* Response handler to handle login request from login modal after session expiration
*
* To refer to self use 'AJAX', instead of 'this' as this function
* is called in the jQuery context.
*
* @param {object} data Event data
*
* @return {void}
*/
loginResponseHandler: function (data) {
if (typeof data === 'undefined' || data === null) {
return;
}
Functions.ajaxRemoveMessage(AJAX.$msgbox);
CommonParams.set('token', data.new_token);
AJAX.scriptHandler.load([]);
if (data.displayMessage) {
$('#page_content').prepend(data.displayMessage);
Functions.highlightSql($('#page_content'));
}
$('#pma_errors').remove();
var msg = '';
if (data.errSubmitMsg) {
msg = data.errSubmitMsg;
}
if (data.errors) {
$('<div></div>', { id : 'pma_errors', class : 'clearfloat d-print-none' })
.insertAfter('#selflink')
.append(data.errors);
// bind for php error reporting forms (bottom)
$('#pma_ignore_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors(false);
});
// In case of 'sendErrorReport'='always'
// submit the hidden error reporting form.
if (data.sendErrorAlways === '1' &&
data.stopErrorReportLoop !== '1'
) {
$('#pma_report_errors_form').trigger('submit');
Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false);
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
} else if (data.promptPhpErrors) {
// otherwise just prompt user if it is set so.
msg = msg + Messages.phpErrorsFound;
// scroll to bottom where all the errors are displayed.
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
}
}
Functions.ajaxShowMessage(msg, false);
// bind for php error reporting forms (popup)
$('#pma_ignore_errors_popup').on('click', function () {
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_popup').on('click', function () {
Functions.ignorePhpErrors(false);
});
if (typeof data.success !== 'undefined' && data.success) {
// reload page if user trying to login has changed
if (CommonParams.get('user') !== data.params.user) {
window.location = 'index.php';
Functions.ajaxShowMessage(Messages.strLoading, false);
AJAX.active = false;
AJAX.xhr = null;
return;
}
// remove the login modal if the login is successful otherwise show error.
if (typeof data.logged_in !== 'undefined' && data.logged_in === 1) {
if ($('#modalOverlay').length) {
$('#modalOverlay').remove();
}
$('fieldset.disabled_for_expiration').removeAttr('disabled').removeClass('disabled_for_expiration');
AJAX.fireTeardown('functions.js');
AJAX.fireOnload('functions.js');
}
if (typeof data.new_token !== 'undefined') {
$('input[name=token]').val(data.new_token);
}
} else if (typeof data.logged_in !== 'undefined' && data.logged_in === 0) {
$('#modalOverlay').replaceWith(data.error);
} else {
Functions.ajaxShowMessage(data.error, false);
AJAX.active = false;
AJAX.xhr = null;
Functions.handleRedirectAndReload(data);
if (data.fieldWithError) {
$(':input.error').removeClass('error');
$('#' + data.fieldWithError).addClass('error');
}
}
},
/**
* Called after the request that was initiated by this.requestHandler()
* has completed successfully or with a caught error. For completely
* failed requests or requests with uncaught errors, see the .ajaxError
* handler at the bottom of this file.
*
* To refer to self use 'AJAX', instead of 'this' as this function
* is called in the jQuery context.
*
* @param {object} data Event data
*
* @return {void}
*/
responseHandler: function (data) {
if (typeof data === 'undefined' || data === null) {
return;
}
// Can be a string when an error occurred and only HTML was returned.
if (typeof data === 'string') {
Functions.ajaxRemoveMessage(AJAX.$msgbox);
Functions.ajaxShowMessage($(data).text(), false, 'error');
AJAX.active = false;
AJAX.xhr = null;
return;
}
if (typeof data.success !== 'undefined' && data.success) {
$('html, body').animate({ scrollTop: 0 }, 'fast');
Functions.ajaxRemoveMessage(AJAX.$msgbox);
if (data.redirect) {
Functions.ajaxShowMessage(data.redirect, false);
AJAX.active = false;
AJAX.xhr = null;
return;
}
AJAX.scriptHandler.reset(function () {
if (data.reloadNavigation) {
Navigation.reload();
}
if (data.title) {
$('title').replaceWith(data.title);
}
if (data.menu) {
var state = {
url : data.selflink,
menu : data.menu
};
history.replaceState(state, null);
AJAX.handleMenu.replace(data.menu);
}
if (data.disableNaviSettings) {
Navigation.disableSettings();
} else {
Navigation.ensureSettings(data.selflink);
}
// Remove all containers that may have
// been added outside of #page_content
$('body').children()
.not('div.modal')
.not('#pma_navigation')
.not('#floating_menubar')
.not('#page_nav_icons')
.not('#page_content')
.not('#selflink')
.not('#pma_header')
.not('#pma_footer')
.not('#pma_demo')
.not('#pma_console_container')
.not('#prefs_autoload')
.remove();
// Replace #page_content with new content
if (data.message && data.message.length > 0) {
$('#page_content').replaceWith(
'<div id=\'page_content\'>' + data.message + '</div>'
);
Functions.highlightSql($('#page_content'));
Functions.checkNumberOfFields();
}
if (data.selflink) {
var source = data.selflink.split('?')[0];
// Check for faulty links
var $selflinkReplace = {
'index.php?route=/import': 'index.php?route=/table/sql',
'index.php?route=/table/chart': 'index.php?route=/sql',
'index.php?route=/table/gis-visualization': 'index.php?route=/sql'
};
if ($selflinkReplace[source]) {
var replacement = $selflinkReplace[source];
data.selflink = data.selflink.replace(source, replacement);
}
$('#selflink').find('> a').attr('href', data.selflink);
}
if (data.params) {
CommonParams.setAll(data.params);
}
if (data.scripts) {
AJAX.scriptHandler.load(data.scripts);
}
if (data.displayMessage) {
$('#page_content').prepend(data.displayMessage);
Functions.highlightSql($('#page_content'));
}
$('#pma_errors').remove();
var msg = '';
if (data.errSubmitMsg) {
msg = data.errSubmitMsg;
}
if (data.errors) {
$('<div></div>', { id : 'pma_errors', class : 'clearfloat d-print-none' })
.insertAfter('#selflink')
.append(data.errors);
// bind for php error reporting forms (bottom)
$('#pma_ignore_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_bottom').on('click', function (e) {
e.preventDefault();
Functions.ignorePhpErrors(false);
});
// In case of 'sendErrorReport'='always'
// submit the hidden error reporting form.
if (data.sendErrorAlways === '1' &&
data.stopErrorReportLoop !== '1'
) {
$('#pma_report_errors_form').trigger('submit');
Functions.ajaxShowMessage(Messages.phpErrorsBeingSubmitted, false);
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
} else if (data.promptPhpErrors) {
// otherwise just prompt user if it is set so.
msg = msg + Messages.phpErrorsFound;
// scroll to bottom where all the errors are displayed.
$('html, body').animate({ scrollTop:$(document).height() }, 'slow');
}
}
Functions.ajaxShowMessage(msg, false);
// bind for php error reporting forms (popup)
$('#pma_ignore_errors_popup').on('click', function () {
Functions.ignorePhpErrors();
});
$('#pma_ignore_all_errors_popup').on('click', function () {
Functions.ignorePhpErrors(false);
});
if (typeof AJAX.callback === 'function') {
AJAX.callback.call();
}
AJAX.callback = function () {};
});
} else {
Functions.ajaxShowMessage(data.error, false);
Functions.ajaxRemoveMessage(AJAX.$msgbox);
var $ajaxError = $('<div></div>');
$ajaxError.attr({ 'id': 'ajaxError' });
$('#page_content').append($ajaxError);
$ajaxError.html(data.error);
$('html, body').animate({ scrollTop: $(document).height() }, 200);
AJAX.active = false;
AJAX.xhr = null;
Functions.handleRedirectAndReload(data);
if (data.fieldWithError) {
$(':input.error').removeClass('error');
$('#' + data.fieldWithError).addClass('error');
}
}
},
/**
* This object is in charge of downloading scripts,
* keeping track of what's downloaded and firing
* the onload event for them when the page is ready.
*/
scriptHandler: {
/**
* @var {string[]} scripts The list of files already downloaded
*/
scripts: [],
/**
* @var {string} scriptsVersion version of phpMyAdmin from which the
* scripts have been loaded
*/
scriptsVersion: null,
/**
* @var {string[]} scriptsToBeLoaded The list of files that
* need to be downloaded
*/
scriptsToBeLoaded: [],
/**
* @var {string[]} scriptsToBeFired The list of files for which
* to fire the onload and unload events
*/
scriptsToBeFired: [],
scriptsCompleted: false,
/**
* Records that a file has been downloaded
*
* @param {string} file The filename
* @param {string} fire Whether this file will be registering
* onload/teardown events
*
* @return {self} For chaining
*/
add: function (file, fire) {
this.scripts.push(file);
if (fire) {
// Record whether to fire any events for the file
// This is necessary to correctly tear down the initial page
this.scriptsToBeFired.push(file);
}
return this;
},
/**
* Download a list of js files in one request
*
* @param {string[]} files An array of filenames and flags
* @param {Function} callback
*
* @return {void}
*/
load: function (files, callback) {
var self = this;
var i;
// Clear loaded scripts if they are from another version of phpMyAdmin.
// Depends on common params being set before loading scripts in responseHandler
if (self.scriptsVersion === null) {
self.scriptsVersion = CommonParams.get('version');
} else if (self.scriptsVersion !== CommonParams.get('version')) {
self.scripts = [];
self.scriptsVersion = CommonParams.get('version');
}
self.scriptsCompleted = false;
self.scriptsToBeFired = [];
// We need to first complete list of files to load
// as next loop will directly fire requests to load them
// and that triggers removal of them from
// self.scriptsToBeLoaded
for (i in files) {
self.scriptsToBeLoaded.push(files[i].name);
if (files[i].fire) {
self.scriptsToBeFired.push(files[i].name);
}
}
for (i in files) {
var script = files[i].name;
// Only for scripts that we don't already have
if ($.inArray(script, self.scripts) === -1) {
this.add(script);
this.appendScript(script, callback);
} else {
self.done(script, callback);
}
}
// Trigger callback if there is nothing else to load
self.done(null, callback);
},
/**
* Called whenever all files are loaded
*
* @param {string} script
* @param {Function?} callback
*
* @return {void}
*/
done: function (script, callback) {
if ($.inArray(script, this.scriptsToBeFired)) {
AJAX.fireOnload(script);
}
if ($.inArray(script, this.scriptsToBeLoaded)) {
this.scriptsToBeLoaded.splice($.inArray(script, this.scriptsToBeLoaded), 1);
}
if (script === null) {
this.scriptsCompleted = true;
}
/* We need to wait for last signal (with null) or last script load */
AJAX.active = (this.scriptsToBeLoaded.length > 0) || ! this.scriptsCompleted;
/* Run callback on last script */
if (! AJAX.active && typeof callback === 'function') {
callback();
}
},
/**
* Appends a script element to the head to load the scripts
*
* @param {string} name
* @param {Function} callback
*
* @return {void}
*/
appendScript: function (name, callback) {
var head = document.head || document.getElementsByTagName('head')[0];
var script = document.createElement('script');
var self = this;
script.type = 'text/javascript';
var file = name.indexOf('vendor/') !== -1 ? name : 'dist/' + name;
script.src = 'js/' + file + '?' + 'v=' + encodeURIComponent(CommonParams.get('version'));
script.async = false;
script.onload = function () {
self.done(name, callback);
};
head.appendChild(script);
},
/**
* Fires all the teardown event handlers for the current page
* and rebinds all forms and links to the request handler
*
* @param {Function} callback The callback to call after resetting
*
* @return {void}
*/
reset: function (callback) {
for (var i in this.scriptsToBeFired) {
AJAX.fireTeardown(this.scriptsToBeFired[i]);
}
this.scriptsToBeFired = [];
/**
* Re-attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).off('click', 'a').on('click', 'a', AJAX.requestHandler);
$(document).off('submit', 'form').on('submit', 'form', AJAX.requestHandler);
callback();
}
}
};
/**
* Here we register a function that will remove the onsubmit event from all
* forms that will be handled by the generic page loader. We then save this
* event handler in the "jQuery data", so that we can fire it up later in
* AJAX.requestHandler().
*
* See bug #3583316
*/
AJAX.registerOnload('functions.js', function () {
// Registering the onload event for functions.js
// ensures that it will be fired for all pages
$('form').not('.ajax').not('.disableAjax').each(function () {
if ($(this).attr('onsubmit')) {
$(this).data('onsubmit', this.onsubmit).attr('onsubmit', '');
}
});
var $pageContent = $('#page_content');
/**
* Workaround for passing submit button name,value on ajax form submit
* by appending hidden element with submit button name and value.
*/
$pageContent.on('click', 'form input[type=submit]', function () {
var buttonName = $(this).attr('name');
if (typeof buttonName === 'undefined') {
return;
}
$(this).closest('form').append($('<input>', {
'type' : 'hidden',
'name' : buttonName,
'value': $(this).val()
}));
});
/**
* Attach event listener to events when user modify visible
* Input,Textarea and select fields to make changes in forms
*/
$pageContent.on(
'keyup change',
'form.lock-page textarea, ' +
'form.lock-page input[type="text"], ' +
'form.lock-page input[type="number"], ' +
'form.lock-page select',
{ value:1 },
AJAX.lockPageHandler
);
$pageContent.on(
'change',
'form.lock-page input[type="checkbox"], ' +
'form.lock-page input[type="radio"]',
{ value:2 },
AJAX.lockPageHandler
);
/**
* Reset lock when lock-page form reset event is fired
* Note: reset does not bubble in all browser so attach to
* form directly.
*/
$('form.lock-page').on('reset', function () {
AJAX.resetLock();
});
});
/**
* Page load event handler
*/
$(function () {
var menuContent = $('<div></div>')
.append($('#server-breadcrumb').clone())
.append($('#topmenucontainer').clone())
.html();
// set initial state reload
var initState = ('state' in window.history && window.history.state !== null);
var initURL = $('#selflink').find('> a').attr('href') || location.href;
var state = {
url : initURL,
menu : menuContent
};
history.replaceState(state, null);
$(window).on('popstate', function (event) {
var initPop = (! initState && location.href === initURL);
initState = true;
// check if popstate fired on first page itself
if (initPop) {
return;
}
var state = event.originalEvent.state;
if (state && state.menu) {
AJAX.$msgbox = Functions.ajaxShowMessage();
var params = 'ajax_request=true' + CommonParams.get('arg_separator') + 'ajax_page_request=true';
var url = state.url || location.href;
$.get(url, params, AJAX.responseHandler);
// TODO: Check if sometimes menu is not retrieved from server,
// Not sure but it seems menu was missing only for printview which
// been removed lately, so if it's right some dead menu checks/fallbacks
// may need to be removed from this file and Header.php
// AJAX.handleMenu.replace(event.originalEvent.state.menu);
}
});
});
/**
* Attach a generic event handler to clicks
* on pages and submissions of forms
*/
$(document).on('click', 'a', AJAX.requestHandler);
$(document).on('submit', 'form', AJAX.requestHandler);
/**
* Gracefully handle fatal server errors
* (e.g: 500 - Internal server error)
*/
$(document).on('ajaxError', function (event, request) {
if (AJAX.debug) {
// eslint-disable-next-line no-console
console.log('AJAX error: status=' + request.status + ', text=' + request.statusText);
}
// Don't handle aborted requests
if (request.status !== 0 || request.statusText !== 'abort') {
var details = '';
var state = request.state();
if (request.status !== 0) {
details += '<div>' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorCode, request.status)) + '</div>';
}
details += '<div>' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorText, request.statusText + ' (' + state + ')')) + '</div>';
if (state === 'rejected' || state === 'timeout') {
details += '<div>' + Functions.escapeHtml(Messages.strErrorConnection) + '</div>';
}
Functions.ajaxShowMessage(
'<div class="alert alert-danger" role="alert">' +
Messages.strErrorProcessingRequest +
details +
'</div>',
false
);
AJAX.active = false;
AJAX.xhr = null;
}
});

View file

@ -1,681 +0,0 @@
/**
* Chart type enumerations
*/
var ChartType = {
LINE : 'line',
SPLINE : 'spline',
AREA : 'area',
BAR : 'bar',
COLUMN : 'column',
PIE : 'pie',
TIMELINE: 'timeline',
SCATTER: 'scatter'
};
/**
* Column type enumeration
*/
var ColumnType = {
STRING : 'string',
NUMBER : 'number',
BOOLEAN : 'boolean',
DATE : 'date'
};
/**
* Abstract chart factory which defines the contract for chart factories
*/
var ChartFactory = function () {
};
ChartFactory.prototype = {
createChart : function () {
throw new Error('createChart must be implemented by a subclass');
}
};
/**
* Abstract chart which defines the contract for charts
*
* @param elementId
* id of the div element the chart is drawn in
*/
var Chart = function (elementId) {
this.elementId = elementId;
};
Chart.prototype = {
draw : function () {
throw new Error('draw must be implemented by a subclass');
},
redraw : function () {
throw new Error('redraw must be implemented by a subclass');
},
destroy : function () {
throw new Error('destroy must be implemented by a subclass');
},
toImageString : function () {
throw new Error('toImageString must be implemented by a subclass');
}
};
/**
* Abstract representation of charts that operates on DataTable where,<br>
* <ul>
* <li>First column provides index to the data.</li>
* <li>Each subsequent columns are of type
* <code>ColumnType.NUMBER<code> and represents a data series.</li>
* </ul>
* Line chart, area chart, bar chart, column chart are typical examples.
*
* @param elementId
* id of the div element the chart is drawn in
*/
var BaseChart = function (elementId) {
Chart.call(this, elementId);
};
BaseChart.prototype = new Chart();
BaseChart.prototype.constructor = BaseChart;
BaseChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length < 2) {
throw new Error('Minimum of two columns are required for this chart');
}
for (var i = 1; i < columns.length; i++) {
if (columns[i].type !== ColumnType.NUMBER) {
throw new Error('Column ' + (i + 1) + ' should be of type \'Number\'');
}
}
return true;
};
/**
* Abstract pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var PieChart = function (elementId) {
BaseChart.call(this, elementId);
};
PieChart.prototype = new BaseChart();
PieChart.prototype.constructor = PieChart;
PieChart.prototype.validateColumns = function (dataTable) {
var columns = dataTable.getColumns();
if (columns.length > 2) {
throw new Error('Pie charts can draw only one series');
}
return BaseChart.prototype.validateColumns.call(this, dataTable);
};
/**
* Abstract timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var TimelineChart = function (elementId) {
BaseChart.call(this, elementId);
};
TimelineChart.prototype = new BaseChart();
TimelineChart.prototype.constructor = TimelineChart;
TimelineChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.DATE) {
throw new Error('First column of timeline chart need to be a date column');
}
}
return result;
};
/**
* Abstract scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var ScatterChart = function (elementId) {
BaseChart.call(this, elementId);
};
ScatterChart.prototype = new BaseChart();
ScatterChart.prototype.constructor = ScatterChart;
ScatterChart.prototype.validateColumns = function (dataTable) {
var result = BaseChart.prototype.validateColumns.call(this, dataTable);
if (result) {
var columns = dataTable.getColumns();
if (columns[0].type !== ColumnType.NUMBER) {
throw new Error('First column of scatter chart need to be a numeric column');
}
}
return result;
};
/**
* The data table contains column information and data for the chart.
*/
// eslint-disable-next-line no-unused-vars
var DataTable = function () {
var columns = [];
var data = null;
this.addColumn = function (type, name) {
columns.push({
'type' : type,
'name' : name
});
};
this.getColumns = function () {
return columns;
};
this.setData = function (rows) {
data = rows;
fillMissingValues();
};
this.getData = function () {
return data;
};
var fillMissingValues = function () {
if (columns.length === 0) {
throw new Error('Set columns first');
}
var row;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row.length > columns.length) {
row.splice(columns.length - 1, row.length - columns.length);
} else if (row.length < columns.length) {
for (var j = row.length; j < columns.length; j++) {
row.push(null);
}
}
}
};
};
/** *****************************************************************************
* JQPlot specific code
******************************************************************************/
/**
* Abstract JQplot chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotChart = function (elementId) {
Chart.call(this, elementId);
this.plot = null;
this.validator = null;
};
JQPlotChart.prototype = new Chart();
JQPlotChart.prototype.constructor = JQPlotChart;
JQPlotChart.prototype.draw = function (data, options) {
if (this.validator.validateColumns(data)) {
this.plot = $.jqplot(this.elementId, this.prepareData(data), this
.populateOptions(data, options));
}
};
JQPlotChart.prototype.destroy = function () {
if (this.plot !== null) {
this.plot.destroy();
}
};
JQPlotChart.prototype.redraw = function (options) {
if (this.plot !== null) {
this.plot.replot(options);
}
};
JQPlotChart.prototype.toImageString = function () {
if (this.plot !== null) {
return $('#' + this.elementId).jqplotToImageStr({});
}
};
JQPlotChart.prototype.populateOptions = function () {
throw new Error('populateOptions must be implemented by a subclass');
};
JQPlotChart.prototype.prepareData = function () {
throw new Error('prepareData must be implemented by a subclass');
};
/**
* JQPlot line chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotLineChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = BaseChart.prototype;
};
JQPlotLineChart.prototype = new JQPlotChart();
JQPlotLineChart.prototype.constructor = JQPlotLineChart;
JQPlotLineChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
xaxis : {
label : columns[0].name,
renderer : $.jqplot.CategoryAxisRenderer,
ticks : []
},
yaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'y',
formatString:'%d'
},
series : []
};
$.extend(true, optional, options);
if (optional.series.length === 0) {
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label : columns[i].name.toString()
});
}
}
if (optional.axes.xaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var j = 0; j < data.length; j++) {
optional.axes.xaxis.ticks.push(data[j][0].toString());
}
}
return optional;
};
JQPlotLineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push(row[j]);
}
}
return retData;
};
/**
* JQPlot spline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotSplineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotSplineChart.prototype = new JQPlotLineChart();
JQPlotSplineChart.prototype.constructor = JQPlotSplineChart;
JQPlotSplineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
rendererOptions : {
smooth : true
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot scatter chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotScatterChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = ScatterChart.prototype;
};
JQPlotScatterChart.prototype = new JQPlotChart();
JQPlotScatterChart.prototype.constructor = JQPlotScatterChart;
JQPlotScatterChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
xaxis : {
label : columns[0].name
},
yaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString:'%d, %d'
},
series : []
};
for (var i = 1; i < columns.length; i++) {
optional.series.push({
label : columns[i].name.toString()
});
}
var compulsory = {
seriesDefaults : {
showLine: false,
markerOptions: {
size: 7,
style: 'x'
}
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotScatterChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
if (row[0]) {
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
retRow.push([row[0], row[j]]);
}
}
}
return retData;
};
/**
* JQPlot timeline chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotTimelineChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
this.validator = TimelineChart.prototype;
};
JQPlotTimelineChart.prototype = new JQPlotLineChart();
JQPlotTimelineChart.prototype.constructor = JQPlotTimelineChart;
JQPlotTimelineChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
axes : {
xaxis : {
tickOptions : {
formatString: '%b %#d, %y'
}
}
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable, options);
var compulsory = {
axes : {
xaxis : {
renderer : $.jqplot.DateAxisRenderer
}
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
JQPlotTimelineChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var d;
var retData = [];
var retRow;
for (var i = 0; i < data.length; i++) {
row = data[i];
d = row[0];
for (var j = 1; j < row.length; j++) {
retRow = retData[j - 1];
if (retRow === undefined) {
retRow = [];
retData[j - 1] = retRow;
}
// See https://github.com/phpmyadmin/phpmyadmin/issues/14395 for the block
if (d !== null && typeof d === 'object') {
retRow.push([d.getTime(), row[j]]);
} else if (typeof d === 'string') {
d = new Date(d);
retRow.push([d.getTime(), row[j]]);
}
}
}
return retData;
};
/**
* JQPlot area chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotAreaChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotAreaChart.prototype = new JQPlotLineChart();
JQPlotAreaChart.prototype.constructor = JQPlotAreaChart;
JQPlotAreaChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults : {
fillToZero : true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
fill : true
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot column chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotColumnChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotColumnChart.prototype = new JQPlotLineChart();
JQPlotColumnChart.prototype.constructor = JQPlotColumnChart;
JQPlotColumnChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
seriesDefaults : {
fillToZero : true
}
};
var opt = JQPlotLineChart.prototype.populateOptions.call(this, dataTable,
options);
var compulsory = {
seriesDefaults : {
renderer : $.jqplot.BarRenderer
}
};
$.extend(true, optional, opt, compulsory);
return optional;
};
/**
* JQPlot bar chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotBarChart = function (elementId) {
JQPlotLineChart.call(this, elementId);
};
JQPlotBarChart.prototype = new JQPlotLineChart();
JQPlotBarChart.prototype.constructor = JQPlotBarChart;
JQPlotBarChart.prototype.populateOptions = function (dataTable, options) {
var columns = dataTable.getColumns();
var optional = {
axes : {
yaxis : {
label : columns[0].name,
labelRenderer : $.jqplot.CanvasAxisLabelRenderer,
renderer : $.jqplot.CategoryAxisRenderer,
ticks : []
},
xaxis : {
label : (columns.length === 2 ? columns[1].name : 'Values'),
labelRenderer : $.jqplot.CanvasAxisLabelRenderer
}
},
highlighter: {
show: true,
tooltipAxes: 'x',
formatString:'%d'
},
series : [],
seriesDefaults : {
fillToZero : true
}
};
var compulsory = {
seriesDefaults : {
renderer : $.jqplot.BarRenderer,
rendererOptions : {
barDirection : 'horizontal'
}
}
};
$.extend(true, optional, options, compulsory);
if (optional.axes.yaxis.ticks.length === 0) {
var data = dataTable.getData();
for (var i = 0; i < data.length; i++) {
optional.axes.yaxis.ticks.push(data[i][0].toString());
}
}
if (optional.series.length === 0) {
for (var j = 1; j < columns.length; j++) {
optional.series.push({
label : columns[j].name.toString()
});
}
}
return optional;
};
/**
* JQPlot pie chart
*
* @param elementId
* id of the div element the chart is drawn in
*/
var JQPlotPieChart = function (elementId) {
JQPlotChart.call(this, elementId);
this.validator = PieChart.prototype;
};
JQPlotPieChart.prototype = new JQPlotChart();
JQPlotPieChart.prototype.constructor = JQPlotPieChart;
JQPlotPieChart.prototype.populateOptions = function (dataTable, options) {
var optional = {
highlighter: {
show: true,
tooltipAxes: 'xy',
formatString:'%s, %d',
useAxesFormatters: false
},
legend: {
renderer: $.jqplot.EnhancedPieLegendRenderer,
},
};
var compulsory = {
seriesDefaults : {
shadow: false,
renderer : $.jqplot.PieRenderer,
rendererOptions: { sliceMargin: 1, showDataLabels: true }
}
};
$.extend(true, optional, options, compulsory);
return optional;
};
JQPlotPieChart.prototype.prepareData = function (dataTable) {
var data = dataTable.getData();
var row;
var retData = [];
for (var i = 0; i < data.length; i++) {
row = data[i];
retData.push([row[0], row[1]]);
}
return [retData];
};
/**
* Chart factory that returns JQPlotCharts
*/
var JQPlotChartFactory = function () {
};
JQPlotChartFactory.prototype = new ChartFactory();
JQPlotChartFactory.prototype.createChart = function (type, elementId) {
var chart = null;
switch (type) {
case ChartType.LINE:
chart = new JQPlotLineChart(elementId);
break;
case ChartType.SPLINE:
chart = new JQPlotSplineChart(elementId);
break;
case ChartType.TIMELINE:
chart = new JQPlotTimelineChart(elementId);
break;
case ChartType.AREA:
chart = new JQPlotAreaChart(elementId);
break;
case ChartType.BAR:
chart = new JQPlotBarChart(elementId);
break;
case ChartType.COLUMN:
chart = new JQPlotColumnChart(elementId);
break;
case ChartType.PIE:
chart = new JQPlotPieChart(elementId);
break;
case ChartType.SCATTER:
chart = new JQPlotScatterChart(elementId);
break;
}
return chart;
};

View file

@ -1,40 +0,0 @@
CodeMirror.sqlLint = function (text, updateLinting, options, cm) {
// Skipping check if text box is empty.
if (text.trim() === '') {
updateLinting(cm, []);
return;
}
function handleResponse (response) {
var found = [];
for (var idx in response) {
found.push({
// eslint-disable-next-line new-cap
from: CodeMirror.Pos(
response[idx].fromLine, response[idx].fromColumn
),
// eslint-disable-next-line new-cap
to: CodeMirror.Pos(
response[idx].toLine, response[idx].toColumn
),
messageHTML: response[idx].message,
severity : response[idx].severity
});
}
updateLinting(cm, found);
}
$.ajax({
method: 'POST',
url: 'index.php?route=/lint',
dataType: 'json',
data: {
'sql_query': text,
'server': CommonParams.get('server'),
'options': options.lintOptions,
'no_history': true,
},
success: handleResponse
});
};

View file

@ -1,173 +0,0 @@
$(function () {
Functions.checkNumberOfFields();
});
/**
* Holds common parameters such as server, db, table, etc
*
* The content for this is normally loaded from Header.php or
* Response.php and executed by ajax.js
*
* @test-module CommonParams
*/
var CommonParams = (function () {
/**
* @var {Object} params An associative array of key value pairs
* @access private
*/
var params = {};
// The returned object is the public part of the module
return {
/**
* Saves all the key value pair that
* are provided in the input array
*
* @param obj hash The input array
*
* @return {void}
*/
setAll: function (obj) {
var updateNavigation = false;
for (var i in obj) {
if (params[i] !== undefined && params[i] !== obj[i]) {
if (i === 'db' || i === 'table') {
updateNavigation = true;
}
}
params[i] = obj[i];
}
if (updateNavigation &&
$('#pma_navigation_tree').hasClass('synced')
) {
Navigation.showCurrent();
}
},
/**
* Retrieves a value given its key
* Returns empty string for undefined values
*
* @param {string} name The key
*
* @return {string}
*/
get: function (name) {
return params[name];
},
/**
* Saves a single key value pair
*
* @param {string} name The key
* @param {string} value The value
*
* @return {CommonParams} For chainability
*/
set: function (name, value) {
var updateNavigation = false;
if (name === 'db' || name === 'table' &&
params[name] !== value
) {
updateNavigation = true;
}
params[name] = value;
if (updateNavigation &&
$('#pma_navigation_tree').hasClass('synced')
) {
Navigation.showCurrent();
}
return this;
},
/**
* Returns the url query string using the saved parameters
*
* @param {string} separator New separator
*
* @return {string}
*/
getUrlQuery: function (separator) {
var sep = (typeof separator !== 'undefined') ? separator : '?';
var common = this.get('common_query');
var argsep = CommonParams.get('arg_separator');
if (typeof common === 'string' && common.length > 0) {
// If the last char is the separator, do not add it
// Else add it
common = common.substr(common.length - 1, common.length) === argsep ? common : common + argsep;
}
return Functions.sprintf(
'%s%sserver=%s' + argsep + 'db=%s' + argsep + 'table=%s',
sep,
common,
encodeURIComponent(this.get('server')),
encodeURIComponent(this.get('db')),
encodeURIComponent(this.get('table'))
);
}
};
}());
/**
* Holds common parameters such as server, db, table, etc
*
* The content for this is normally loaded from Header.php or
* Response.php and executed by ajax.js
*/
// eslint-disable-next-line no-unused-vars
var CommonActions = {
/**
* Saves the database name when it's changed
* and reloads the query window, if necessary
*
* @param {string} newDb new_db The name of the new database
*
* @return {void}
*/
setDb: function (newDb) {
if (newDb !== CommonParams.get('db')) {
CommonParams.setAll({ 'db': newDb, 'table': '' });
}
},
/**
* Opens a database in the main part of the page
*
* @param {string} newDb The name of the new database
*
* @return {void}
*/
openDb: function (newDb) {
CommonParams
.set('db', newDb)
.set('table', '');
this.refreshMain(
CommonParams.get('opendb_url')
);
},
/**
* Refreshes the main frame
*
* @param {any} url Undefined to refresh to the same page
* String to go to a different page, e.g: 'index.php'
* @param {function | undefined} callback
*
* @return {void}
*/
refreshMain: function (url, callback = undefined) {
var newUrl = url;
if (! newUrl) {
newUrl = $('#selflink').find('a').attr('href') || window.location.pathname;
newUrl = newUrl.substring(0, newUrl.indexOf('?'));
}
if (newUrl.indexOf('?') !== -1) {
newUrl += CommonParams.getUrlQuery(CommonParams.get('arg_separator'));
} else {
newUrl += CommonParams.getUrlQuery('?');
}
$('<a></a>', { href: newUrl })
.appendTo('body')
.trigger('click')
.remove();
if (typeof callback !== 'undefined') {
AJAX.callback = callback;
}
}
};

View file

@ -1,860 +0,0 @@
/**
* Functions used in configuration forms and on user preferences pages
*/
/* exported PASSIVE_EVENT_LISTENERS */
var configInlineParams;
var configScriptLoaded;
/**
* checks whether browser supports web storage
*
* @param {'localStorage' | 'sessionStorage'} type the type of storage i.e. localStorage or sessionStorage
* @param {boolean} warn Wether to show a warning on error
*
* @return {boolean}
*/
function isStorageSupported (type, warn = false) {
try {
window[type].setItem('PMATest', 'test');
// Check whether key-value pair was set successfully
if (window[type].getItem('PMATest') === 'test') {
// Supported, remove test variable from storage
window[type].removeItem('PMATest');
return true;
}
} catch (error) {
// Not supported
if (warn) {
Functions.ajaxShowMessage(Messages.strNoLocalStorage, false);
}
}
return false;
}
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('config.js', function () {
$('.optbox input[id], .optbox select[id], .optbox textarea[id]').off('change').off('keyup');
$('.optbox input[type=button][name=submit_reset]').off('click');
$('div.tab-content').off();
$('#import_local_storage, #export_local_storage').off('click');
$('form.prefs-form').off('change').off('submit');
$(document).off('click', 'div.click-hide-message');
$('#prefs_autoload').find('a').off('click');
});
AJAX.registerOnload('config.js', function () {
var $topmenuUpt = $('#user_prefs_tabs');
$topmenuUpt.find('a.active').attr('rel', 'samepage');
$topmenuUpt.find('a:not(.active)').attr('rel', 'newpage');
});
// default values for fields
var defaultValues = {};
/**
* Returns field type
*
* @param {Element} field
*
* @return {string}
*/
function getFieldType (field) {
var $field = $(field);
var tagName = $field.prop('tagName');
if (tagName === 'INPUT') {
return $field.attr('type');
} else if (tagName === 'SELECT') {
return 'select';
} else if (tagName === 'TEXTAREA') {
return 'text';
}
return '';
}
/**
* Enables or disables the "restore default value" button
*
* @param {Element} field
* @param {boolean} display
*
* @return {void}
*/
function setRestoreDefaultBtn (field, display) {
var $el = $(field).closest('td').find('.restore-default img');
$el[display ? 'show' : 'hide']();
}
/**
* Marks field depending on its value (system default or custom)
*
* @param {Element | JQuery<Element>} field
*
* @return {void}
*/
function markField (field) {
var $field = $(field);
var type = getFieldType($field);
var isDefault = checkFieldDefault($field, type);
// checkboxes uses parent <span> for marking
var $fieldMarker = (type === 'checkbox') ? $field.parent() : $field;
setRestoreDefaultBtn($field, !isDefault);
$fieldMarker[isDefault ? 'removeClass' : 'addClass']('custom');
}
/**
* Sets field value
*
* value must be of type:
* o undefined (omitted) - restore default value (form default, not PMA default)
* o String - if field_type is 'text'
* o boolean - if field_type is 'checkbox'
* o Array of values - if field_type is 'select'
*
* @param {Element} field
* @param {string} fieldType see {@link #getFieldType}
* @param {string | boolean} value
*/
function setFieldValue (field, fieldType, value) {
var $field = $(field);
switch (fieldType) {
case 'text':
case 'number':
$field.val(value);
break;
case 'checkbox':
$field.prop('checked', value);
break;
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
for (i = 0; i < imax; i++) {
options[i].selected = (value.indexOf(options[i].value) !== -1);
}
break;
}
markField($field);
}
/**
* Gets field value
*
* Will return one of:
* o String - if type is 'text'
* o boolean - if type is 'checkbox'
* o Array of values - if type is 'select'
*
* @param {Element} field
* @param {string} fieldType returned by {@link #getFieldType}
*
* @return {boolean | string | string[] | null}
*/
function getFieldValue (field, fieldType) {
var $field = $(field);
switch (fieldType) {
case 'text':
case 'number':
return $field.prop('value');
case 'checkbox':
return $field.prop('checked');
case 'select':
var options = $field.prop('options');
var i;
var imax = options.length;
var items = [];
for (i = 0; i < imax; i++) {
if (options[i].selected) {
items.push(options[i].value);
}
}
return items;
}
return null;
}
/**
* Returns values for all fields in fieldsets
*
* @return {object}
*/
// eslint-disable-next-line no-unused-vars
function getAllValues () {
var $elements = $('fieldset input, fieldset select, fieldset textarea');
var values = {};
var type;
var value;
for (var i = 0; i < $elements.length; i++) {
type = getFieldType($elements[i]);
value = getFieldValue($elements[i], type);
if (typeof value !== 'undefined') {
// we only have single selects, fatten array
if (type === 'select') {
value = value[0];
}
values[$elements[i].name] = value;
}
}
return values;
}
/**
* Checks whether field has its default value
*
* @param {Element} field
* @param {string} type
*
* @return {boolean}
*/
function checkFieldDefault (field, type) {
var $field = $(field);
var fieldId = $field.attr('id');
if (typeof defaultValues[fieldId] === 'undefined') {
return true;
}
var isDefault = true;
var currentValue = getFieldValue($field, type);
if (type !== 'select') {
isDefault = currentValue === defaultValues[fieldId];
} else {
// compare arrays, will work for our representation of select values
if (currentValue.length !== defaultValues[fieldId].length) {
isDefault = false;
} else {
for (var i = 0; i < currentValue.length; i++) {
if (currentValue[i] !== defaultValues[fieldId][i]) {
isDefault = false;
break;
}
}
}
}
return isDefault;
}
/**
* Returns element's id prefix
* @param {Element} element
*
* @return {string}
*/
// eslint-disable-next-line no-unused-vars
function getIdPrefix (element) {
return $(element).attr('id').replace(/[^-]+$/, '');
}
// ------------------------------------------------------------------
// Form validation and field operations
//
// form validator assignments
var validate = {};
// form validator list
var validators = {
// regexp: numeric value
regExpNumeric: /^[0-9]+$/,
// regexp: extract parts from PCRE expression
regExpPcreExtract: /(.)(.*)\1(.*)?/,
/**
* Validates positive number
*
* @param {boolean} isKeyUp
*
* @return {boolean}
*/
validatePositiveNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = this.value !== '0' && validators.regExpNumeric.test(this.value);
return result ? true : Messages.error_nan_p;
},
/**
* Validates non-negative number
*
* @param {boolean} isKeyUp
*
* @return {boolean}
*/
validateNonNegativeNumber: function (isKeyUp) {
if (isKeyUp && this.value === '') {
return true;
}
var result = validators.regExpNumeric.test(this.value);
return result ? true : Messages.error_nan_nneg;
},
/**
* Validates port number
*
* @return {true|string}
*/
validatePortNumber: function () {
if (this.value === '') {
return true;
}
var result = validators.regExpNumeric.test(this.value) && this.value !== '0';
return result && this.value <= 65535 ? true : Messages.error_incorrect_port;
},
/**
* Validates value according to given regular expression
*
* @param {boolean} isKeyUp
* @param {string} regexp
*
* @return {true|string}
*/
validateByRegex: function (isKeyUp, regexp) {
if (isKeyUp && this.value === '') {
return true;
}
// convert PCRE regexp
var parts = regexp.match(validators.regExpPcreExtract);
var valid = this.value.match(new RegExp(parts[2], parts[3])) !== null;
return valid ? true : Messages.error_invalid_value;
},
/**
* Validates upper bound for numeric inputs
*
* @param {boolean} isKeyUp
* @param {number} maxValue
*
* @return {true|string}
*/
validateUpperBound: function (isKeyUp, maxValue) {
var val = parseInt(this.value, 10);
if (isNaN(val)) {
return true;
}
return val <= maxValue ? true : Functions.sprintf(Messages.error_value_lte, maxValue);
},
// field validators
field: {
},
// fieldset validators
fieldset: {
}
};
/**
* Registers validator for given field
*
* @param {string} id field id
* @param {string} type validator (key in validators object)
* @param {boolean} onKeyUp whether fire on key up
* @param {Array} params validation function parameters
*/
// eslint-disable-next-line no-unused-vars
function registerFieldValidator (id, type, onKeyUp, params) {
if (typeof validators[type] === 'undefined') {
return;
}
if (typeof validate[id] === 'undefined') {
validate[id] = [];
}
if (validate[id].length === 0) {
validate[id].push([type, params, onKeyUp]);
}
}
/**
* Returns validation functions associated with form field
*
* @param {String} fieldId form field id
* @param {boolean} onKeyUpOnly see registerFieldValidator
*
* @return {any[]} of [function, parameters to be passed to function]
*/
function getFieldValidators (fieldId, onKeyUpOnly) {
// look for field bound validator
var name = fieldId && fieldId.match(/[^-]+$/)[0];
if (typeof validators.field[name] !== 'undefined') {
return [[validators.field[name], null]];
}
// look for registered validators
var functions = [];
if (typeof validate[fieldId] !== 'undefined') {
// validate[field_id]: array of [type, params, onKeyUp]
for (var i = 0, imax = validate[fieldId].length; i < imax; i++) {
if (onKeyUpOnly && !validate[fieldId][i][2]) {
continue;
}
functions.push([validators[validate[fieldId][i][0]], validate[fieldId][i][1]]);
}
}
return functions;
}
/**
* Displays errors for given form fields
*
* WARNING: created DOM elements must be identical with the ones made by
* PhpMyAdmin\Config\FormDisplayTemplate::displayInput()!
*
* @param {object} errorList list of errors in the form {field id: error array}
*/
function displayErrors (errorList) {
var tempIsEmpty = function (item) {
return item !== '';
};
for (var fieldId in errorList) {
var errors = errorList[fieldId];
var $field = $('#' + fieldId);
var isFieldset = $field.attr('tagName') === 'FIELDSET';
var $errorCnt;
if (isFieldset) {
$errorCnt = $field.find('dl.errors');
} else {
$errorCnt = $field.siblings('.inline_errors');
}
// remove empty errors (used to clear error list)
errors = $.grep(errors, tempIsEmpty);
// CSS error class
if (!isFieldset) {
// checkboxes uses parent <span> for marking
var $fieldMarker = ($field.attr('type') === 'checkbox') ? $field.parent() : $field;
$fieldMarker[errors.length ? 'addClass' : 'removeClass']('field-error');
}
if (errors.length) {
// if error container doesn't exist, create it
if ($errorCnt.length === 0) {
if (isFieldset) {
$errorCnt = $('<dl class="errors"></dl>');
$field.find('table').before($errorCnt);
} else {
$errorCnt = $('<dl class="inline_errors"></dl>');
$field.closest('td').append($errorCnt);
}
}
var html = '';
for (var i = 0, imax = errors.length; i < imax; i++) {
html += '<dd>' + errors[i] + '</dd>';
}
$errorCnt.html(html);
} else if ($errorCnt !== null) {
// remove useless error container
$errorCnt.remove();
}
}
}
/**
* Validates fields and fieldsets and call displayError function as required
*/
function setDisplayError () {
var elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]');
// run all field validators
var errors = {};
for (var i = 0; i < elements.length; i++) {
validateField(elements[i], false, errors);
}
// run all fieldset validators
$('fieldset.optbox').each(function () {
validateFieldset(this, false, errors);
});
displayErrors(errors);
}
/**
* Validates fieldset and puts errors in 'errors' object
*
* @param {Element} fieldset
* @param {boolean} isKeyUp
* @param {object} errors
*/
function validateFieldset (fieldset, isKeyUp, errors) {
var $fieldset = $(fieldset);
if ($fieldset.length && typeof validators.fieldset[$fieldset.attr('id')] !== 'undefined') {
var fieldsetErrors = validators.fieldset[$fieldset.attr('id')].apply($fieldset[0], [isKeyUp]);
for (var fieldId in fieldsetErrors) {
if (typeof errors[fieldId] === 'undefined') {
errors[fieldId] = [];
}
if (typeof fieldsetErrors[fieldId] === 'string') {
fieldsetErrors[fieldId] = [fieldsetErrors[fieldId]];
}
$.merge(errors[fieldId], fieldsetErrors[fieldId]);
}
}
}
/**
* Validates form field and puts errors in 'errors' object
*
* @param {Element} field
* @param {boolean} isKeyUp
* @param {object} errors
*/
function validateField (field, isKeyUp, errors) {
var args;
var result;
var $field = $(field);
var fieldId = $field.attr('id');
errors[fieldId] = [];
var functions = getFieldValidators(fieldId, isKeyUp);
for (var i = 0; i < functions.length; i++) {
if (typeof functions[i][1] !== 'undefined' && functions[i][1] !== null) {
args = functions[i][1].slice(0);
} else {
args = [];
}
args.unshift(isKeyUp);
result = functions[i][0].apply($field[0], args);
if (result !== true) {
if (typeof result === 'string') {
result = [result];
}
$.merge(errors[fieldId], result);
}
}
}
/**
* Validates form field and parent fieldset
*
* @param {Element} field
* @param {boolean} isKeyUp
*/
function validateFieldAndFieldset (field, isKeyUp) {
var $field = $(field);
var errors = {};
validateField($field, isKeyUp, errors);
validateFieldset($field.closest('fieldset.optbox'), isKeyUp, errors);
displayErrors(errors);
}
function loadInlineConfig () {
if (!Array.isArray(configInlineParams)) {
return;
}
for (var i = 0; i < configInlineParams.length; ++i) {
if (typeof configInlineParams[i] === 'function') {
configInlineParams[i]();
}
}
}
function setupValidation () {
validate = {};
configScriptLoaded = true;
if (configScriptLoaded && typeof configInlineParams !== 'undefined') {
loadInlineConfig();
}
// register validators and mark custom values
var $elements = $('.optbox input[id], .optbox select[id], .optbox textarea[id]');
$elements.each(function () {
markField(this);
var $el = $(this);
$el.on('change', function () {
validateFieldAndFieldset(this, false);
markField(this);
});
var tagName = $el.attr('tagName');
// text fields can be validated after each change
if (tagName === 'INPUT' && $el.attr('type') === 'text') {
$el.on('keyup', function () {
validateFieldAndFieldset($el, true);
markField($el);
});
}
// disable textarea spellcheck
if (tagName === 'TEXTAREA') {
$el.attr('spellcheck', false);
}
});
// check whether we've refreshed a page and browser remembered modified
// form values
var $checkPageRefresh = $('#check_page_refresh');
if ($checkPageRefresh.length === 0 || $checkPageRefresh.val() === '1') {
// run all field validators
var errors = {};
for (var i = 0; i < $elements.length; i++) {
validateField($elements[i], false, errors);
}
// run all fieldset validators
$('fieldset.optbox').each(function () {
validateFieldset(this, false, errors);
});
displayErrors(errors);
} else if ($checkPageRefresh) {
$checkPageRefresh.val('1');
}
}
AJAX.registerOnload('config.js', function () {
setupValidation();
});
//
// END: Form validation and field operations
// ------------------------------------------------------------------
function adjustPrefsNotification () {
var $prefsAutoLoad = $('#prefs_autoload');
var $tableNameControl = $('#table_name_col_no');
var $prefsAutoShowing = ($prefsAutoLoad.css('display') !== 'none');
if ($prefsAutoShowing && $tableNameControl.length) {
$tableNameControl.css('top', '55px');
}
}
AJAX.registerOnload('config.js', function () {
adjustPrefsNotification();
});
// ------------------------------------------------------------------
// Form reset buttons
//
AJAX.registerOnload('config.js', function () {
$('.optbox input[type=button][name=submit_reset]').on('click', function () {
var fields = $(this).closest('fieldset').find('input, select, textarea');
for (var i = 0, imax = fields.length; i < imax; i++) {
setFieldValue(fields[i], getFieldType(fields[i]), defaultValues[fields[i].id]);
}
setDisplayError();
});
});
//
// END: Form reset buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// "Restore default" and "set value" buttons
//
/**
* Restores field's default value
*
* @param {string} fieldId
*
* @return {void}
*/
function restoreField (fieldId) {
var $field = $('#' + fieldId);
if ($field.length === 0 || defaultValues[fieldId] === undefined) {
return;
}
setFieldValue($field, getFieldType($field), defaultValues[fieldId]);
}
function setupRestoreField () {
$('div.tab-content')
.on('mouseenter', '.restore-default, .set-value', function () {
$(this).css('opacity', 1);
})
.on('mouseleave', '.restore-default, .set-value', function () {
$(this).css('opacity', 0.25);
})
.on('click', '.restore-default, .set-value', function (e) {
e.preventDefault();
var href = $(this).attr('href');
var fieldSel;
if ($(this).hasClass('restore-default')) {
fieldSel = href;
restoreField(fieldSel.substr(1));
} else {
fieldSel = href.match(/^[^=]+/)[0];
var value = href.match(/=(.+)$/)[1];
setFieldValue($(fieldSel), 'text', value);
}
$(fieldSel).trigger('change');
})
.find('.restore-default, .set-value')
// inline-block for IE so opacity inheritance works
.css({ display: 'inline-block', opacity: 0.25 });
}
AJAX.registerOnload('config.js', function () {
setupRestoreField();
});
//
// END: "Restore default" and "set value" buttons
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// User preferences import/export
//
AJAX.registerOnload('config.js', function () {
offerPrefsAutoimport();
var $radios = $('#import_local_storage, #export_local_storage');
if (!$radios.length) {
return;
}
// enable JavaScript dependent fields
$radios
.prop('disabled', false)
.add('#export_text_file, #import_text_file')
.on('click', function () {
var enableId = $(this).attr('id');
var disableId;
if (enableId.match(/local_storage$/)) {
disableId = enableId.replace(/local_storage$/, 'text_file');
} else {
disableId = enableId.replace(/text_file$/, 'local_storage');
}
$('#opts_' + disableId).addClass('disabled').find('input').prop('disabled', true);
$('#opts_' + enableId).removeClass('disabled').find('input').prop('disabled', false);
});
// detect localStorage state
var lsSupported = isStorageSupported('localStorage', true);
var lsExists = lsSupported ? (window.localStorage.config || false) : false;
$('div.localStorage-' + (lsSupported ? 'un' : '') + 'supported').hide();
$('div.localStorage-' + (lsExists ? 'empty' : 'exists')).hide();
if (lsExists) {
updatePrefsDate();
}
$('form.prefs-form').on('change', function () {
var $form = $(this);
var disabled = false;
if (!lsSupported) {
disabled = $form.find('input[type=radio][value$=local_storage]').prop('checked');
} else if (!lsExists && $form.attr('name') === 'prefs_import' &&
$('#import_local_storage')[0].checked
) {
disabled = true;
}
$form.find('input[type=submit]').prop('disabled', disabled);
}).on('submit', function (e) {
var $form = $(this);
if ($form.attr('name') === 'prefs_export' && $('#export_local_storage')[0].checked) {
e.preventDefault();
// use AJAX to read JSON settings and save them
savePrefsToLocalStorage($form);
} else if ($form.attr('name') === 'prefs_import' && $('#import_local_storage')[0].checked) {
// set 'json' input and submit form
$form.find('input[name=json]').val(window.localStorage.config);
}
});
$(document).on('click', 'div.click-hide-message', function () {
$(this).hide();
$(this).parent('.card-body').css('height', '');
$(this).parent('.card-body').find('.prefs-form').show();
});
});
/**
* Saves user preferences to localStorage
*
* @param {Element} form
*/
function savePrefsToLocalStorage (form) {
var $form = $(form);
var submit = $form.find('input[type=submit]');
submit.prop('disabled', true);
$.ajax({
url: 'index.php?route=/preferences/manage',
cache: false,
type: 'POST',
data: {
'ajax_request': true,
'server': CommonParams.get('server'),
'submit_get_json': true
},
success: function (data) {
if (typeof data !== 'undefined' && data.success === true) {
window.localStorage.config = data.prefs;
window.localStorage.configMtime = data.mtime;
window.localStorage.configMtimeLocal = (new Date()).toUTCString();
updatePrefsDate();
$('div.localStorage-empty').hide();
$('div.localStorage-exists').show();
var group = $form.parent('.card-body');
group.css('height', group.height() + 'px');
$form.hide('fast');
$form.prev('.click-hide-message').show('fast');
} else {
Functions.ajaxShowMessage(data.error);
}
},
complete: function () {
submit.prop('disabled', false);
}
});
}
/**
* Updates preferences timestamp in Import form
*/
function updatePrefsDate () {
var d = new Date(window.localStorage.configMtimeLocal);
var msg = Messages.strSavedOn.replace(
'@DATE@',
Functions.formatDateTime(d)
);
$('#opts_import_local_storage').find('div.localStorage-exists').html(msg);
}
/**
* Prepares message which informs that localStorage preferences are available and can be imported or deleted
*/
function offerPrefsAutoimport () {
var hasConfig = (isStorageSupported('localStorage')) && (window.localStorage.config || false);
var $cnt = $('#prefs_autoload');
if (!$cnt.length || !hasConfig) {
return;
}
$cnt.find('a').on('click', function (e) {
e.preventDefault();
var $a = $(this);
if ($a.attr('href') === '#no') {
$cnt.remove();
$.post('index.php', {
'server': CommonParams.get('server'),
'prefs_autoload': 'hide'
}, null, 'html');
return;
} else if ($a.attr('href') === '#delete') {
$cnt.remove();
localStorage.clear();
$.post('index.php', {
'server': CommonParams.get('server'),
'prefs_autoload': 'hide'
}, null, 'html');
return;
}
$cnt.find('input[name=json]').val(window.localStorage.config);
$cnt.find('form').trigger('submit');
});
$cnt.show();
}
/**
* @type {boolean} Support for passive event listener option
*/
var PASSIVE_EVENT_LISTENERS = (function () {
var passive = false;
try {
var options = Object.defineProperty({}, 'passive', {
get: function () {
return (passive = true);
},
});
window.addEventListener('_', null, options);
window.removeEventListener('_', null, options);
} catch (error) {
// passive not supported
}
return passive;
}());

File diff suppressed because it is too large Load diff

View file

@ -1,13 +0,0 @@
/**
* Conditionally included if framing is not allowed
*/
if (self === top) {
var styleElement = document.getElementById('cfs-style');
// check if styleElement has already been removed
// to avoid frequently reported js error
if (typeof(styleElement) !== 'undefined' && styleElement !== null) {
styleElement.parentNode.removeChild(styleElement);
}
} else {
top.location = self.location;
}

View file

@ -1,239 +0,0 @@
/**
* @fileoverview events handling from central columns page
* @name Central columns
*
* @requires jQuery
*/
/**
* AJAX scripts for /database/central-columns
*
* Actions ajaxified here:
* Inline Edit and save of a result row
* Delete a row
* Multiple edit and delete option
*
*/
AJAX.registerTeardown('database/central_columns.js', function () {
$('.edit').off('click');
$('.edit_save_form').off('click');
$('.edit_cancel_form').off('click');
$('.del_row').off('click');
$(document).off('keyup', '.filter_rows');
$('.edit_cancel_form').off('click');
$('#table-select').off('change');
$('#column-select').off('change');
$('#add_col_div').find('>a').off('click');
$('#add_new').off('submit');
$('#multi_edit_central_columns').off('submit');
$('select.default_type').off('change');
$('button[name=\'delete_central_columns\']').off('click');
$('button[name=\'edit_central_columns\']').off('click');
});
AJAX.registerOnload('database/central_columns.js', function () {
$('#tableslistcontainer input,#tableslistcontainer select,#tableslistcontainer .default_value,#tableslistcontainer .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
$('#tableslistcontainer').find('.checkall_box').show();
if ($('#table_columns').find('tbody tr').length > 0) {
$('#table_columns').tablesorter({
headers: {
0: { sorter: false },
1: { sorter: false }, // hidden column
4: { sorter: 'integer' }
}
});
}
$('#tableslistcontainer').find('button[name="delete_central_columns"]').on('click', function (event) {
event.preventDefault();
var multiDeleteColumns = $('.checkall:checkbox:checked').serialize();
if (multiDeleteColumns === '') {
Functions.ajaxShowMessage(Messages.strRadioUnchecked);
return false;
}
Functions.ajaxShowMessage();
$('#del_col_name').val(multiDeleteColumns);
$('#del_form').trigger('submit');
});
$('#tableslistcontainer').find('button[name="edit_central_columns"]').on('click', function (event) {
event.preventDefault();
var editColumnList = $('.checkall:checkbox:checked').serialize();
if (editColumnList === '') {
Functions.ajaxShowMessage(Messages.strRadioUnchecked);
return false;
}
var argsep = CommonParams.get('arg_separator');
var editColumnData = editColumnList + '' + argsep + 'edit_central_columns_page=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(CommonParams.get('db')) + argsep + 'server=' + CommonParams.get('server');
Functions.ajaxShowMessage();
AJAX.source = $(this);
$.post('index.php?route=/database/central-columns', editColumnData, AJAX.responseHandler);
});
$('#multi_edit_central_columns').on('submit', function (event) {
event.preventDefault();
event.stopPropagation();
var argsep = CommonParams.get('arg_separator');
var multiColumnEditData = $('#multi_edit_central_columns').serialize() + argsep + 'multi_edit_central_column_save=true' + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'db=' + encodeURIComponent(CommonParams.get('db')) + argsep + 'server=' + CommonParams.get('server');
Functions.ajaxShowMessage();
AJAX.source = $(this);
$.post('index.php?route=/database/central-columns', multiColumnEditData, AJAX.responseHandler);
});
$('#add_new').find('td').each(function () {
if ($(this).attr('name') !== 'undefined') {
$(this).find('input,select').first().attr('name', $(this).attr('name'));
}
});
$('#field_0_0').attr('required','required');
$('#add_new input[type="text"], #add_new input[type="number"], #add_new select')
.css({
'width' : '10em',
'box-sizing' : 'border-box'
});
window.scrollTo(0, 0);
$(document).on('keyup', '.filter_rows', function () {
// get the column names
var cols = $('th.column_heading').map(function () {
return $(this).text().trim();
}).get();
$.uiTableFilter($('#table_columns'), $(this).val(), cols, null, 'td span');
});
$('.edit').on('click', function () {
var rownum = $(this).parent().data('rownum');
$('#save_' + rownum).show();
$(this).hide();
$('#f_' + rownum + ' td span').hide();
$('#f_' + rownum + ' input, #f_' + rownum + ' select, #f_' + rownum + ' .open_enum_editor').show();
var attributeVal = $('#f_' + rownum + ' td[name=col_attribute] span').html();
$('#f_' + rownum + ' select[name=field_attribute\\[' + rownum + '\\] ] option[value="' + attributeVal + '"]').attr('selected','selected');
if ($('#f_' + rownum + ' .default_type').val() === 'USER_DEFINED') {
$('#f_' + rownum + ' .default_type').siblings('.default_value').show();
} else {
$('#f_' + rownum + ' .default_type').siblings('.default_value').hide();
}
});
$('.del_row').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var $td = $(this);
var question = Messages.strDeleteCentralColumnWarning;
$td.confirm(question, null, function () {
var rownum = $td.data('rownum');
$('#del_col_name').val('selected_fld%5B%5D=' + $('#checkbox_row_' + rownum).val());
$('#del_form').trigger('submit');
});
});
$('.edit_cancel_form').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var rownum = $(this).data('rownum');
$('#save_' + rownum).hide();
$('#edit_' + rownum).show();
$('#f_' + rownum + ' td span').show();
$('#f_' + rownum + ' input, #f_' + rownum + ' select,#f_' + rownum + ' .default_value, #f_' + rownum + ' .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
});
$('.edit_save_form').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
var rownum = $(this).data('rownum');
$('#f_' + rownum + ' td').each(function () {
if ($(this).attr('name') !== 'undefined') {
$(this).find(':input[type!="hidden"],select').first()
.attr('name', $(this).attr('name'));
}
});
if ($('#f_' + rownum + ' .default_type').val() === 'USER_DEFINED') {
$('#f_' + rownum + ' .default_type').attr('name','col_default_sel');
} else {
$('#f_' + rownum + ' .default_value').attr('name','col_default_val');
}
var datastring = $('#f_' + rownum + ' :input').serialize();
$.ajax({
type: 'POST',
url: 'index.php?route=/database/central-columns',
data: datastring + CommonParams.get('arg_separator') + 'ajax_request=true',
dataType: 'json',
success: function (data) {
if (data.message !== '1') {
Functions.ajaxShowMessage(
'<div class="alert alert-danger" role="alert">' +
data.message +
'</div>',
false
);
} else {
$('#f_' + rownum + ' td input[id=checkbox_row_' + rownum + ']').val($('#f_' + rownum + ' input[name=col_name]').val()).html();
$('#f_' + rownum + ' td[name=col_name] span').text($('#f_' + rownum + ' input[name=col_name]').val()).html();
$('#f_' + rownum + ' td[name=col_type] span').text($('#f_' + rownum + ' select[name=col_type]').val()).html();
$('#f_' + rownum + ' td[name=col_length] span').text($('#f_' + rownum + ' input[name=col_length]').val()).html();
$('#f_' + rownum + ' td[name=collation] span').text($('#f_' + rownum + ' select[name=collation]').val()).html();
$('#f_' + rownum + ' td[name=col_attribute] span').text($('#f_' + rownum + ' select[name=col_attribute]').val()).html();
$('#f_' + rownum + ' td[name=col_isNull] span').text($('#f_' + rownum + ' input[name=col_isNull]').is(':checked') ? 'Yes' : 'No').html();
$('#f_' + rownum + ' td[name=col_extra] span').text($('#f_' + rownum + ' input[name=col_extra]').is(':checked') ? 'auto_increment' : '').html();
$('#f_' + rownum + ' td[name=col_default] span').text($('#f_' + rownum + ' :input[name=col_default]').val()).html();
}
$('#save_' + rownum).hide();
$('#edit_' + rownum).show();
$('#f_' + rownum + ' td span').show();
$('#f_' + rownum + ' input, #f_' + rownum + ' select,#f_' + rownum + ' .default_value, #f_' + rownum + ' .open_enum_editor').hide();
$('#tableslistcontainer').find('.checkall').show();
},
error: function () {
Functions.ajaxShowMessage(
'<div class="alert alert-danger" role="alert">' +
Messages.strErrorProcessingRequest +
'</div>',
false
);
}
});
});
$('#table-select').on('change', function () {
var selectValue = $(this).val();
var defaultColumnSelect = $('#column-select').find('option').first();
var href = 'index.php?route=/database/central-columns/populate';
var params = {
'ajax_request' : true,
'server' : CommonParams.get('server'),
'db' : CommonParams.get('db'),
'selectedTable' : selectValue
};
$('#column-select').html('<option value="">' + Messages.strLoading + '</option>');
if (selectValue !== '') {
$.post(href, params, function (data) {
$('#column-select').empty().append(defaultColumnSelect);
$('#column-select').append(data.message);
});
}
});
$('#add_column').on('submit', function (e) {
var selectvalue = $('#column-select').val();
if (selectvalue === '') {
e.preventDefault();
e.stopPropagation();
}
});
$('#add_col_div').find('>a').on('click', function () {
$('#add_new').slideToggle('slow');
var $addColDivLinkSpan = $('#add_col_div').find('>a span');
if ($addColDivLinkSpan.html() === '+') {
$addColDivLinkSpan.html('-');
} else {
$addColDivLinkSpan.html('+');
}
});
$('#add_new').on('submit', function () {
$('#add_new').toggle();
});
$('#tableslistcontainer').find('select.default_type').on('change', function () {
if ($(this).val() === 'USER_DEFINED') {
$(this).siblings('.default_value').attr('name','col_default');
$(this).attr('name','col_default_sel');
} else {
$(this).attr('name','col_default');
$(this).siblings('.default_value').attr('name','col_default_val');
}
});
});

View file

@ -1,579 +0,0 @@
AJAX.registerTeardown('database/events.js', function () {
$(document).off('click', 'a.ajax.add_anchor, a.ajax.edit_anchor');
$(document).off('click', 'a.ajax.export_anchor');
$(document).off('click', '#bulkActionExportButton');
$(document).off('click', 'a.ajax.drop_anchor');
$(document).off('click', '#bulkActionDropButton');
$(document).off('change', 'select[name=item_type]');
});
const DatabaseEvents = {
/**
* @var $ajaxDialog Query object containing the reference to the
* dialog that contains the editor
*/
$ajaxDialog: null,
/**
* @var syntaxHiglighter Reference to the codemirror editor
*/
syntaxHiglighter: null,
/**
* Validate editor form fields.
*
* @return {bool}
*/
validate: function () {
/**
* @var $elm a jQuery object containing the reference
* to an element that is being validated
*/
var $elm = null;
// Common validation. At the very least the name
// and the definition must be provided for an item
$elm = $('table.rte_table').last().find('input[name=item_name]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
$elm = $('table.rte_table').find('textarea[name=item_definition]');
if ($elm.val() === '') {
if (this.syntaxHiglighter !== null) {
this.syntaxHiglighter.focus();
} else {
$('textarea[name=item_definition]').last().trigger('focus');
}
alert(Messages.strFormEmpty);
return false;
}
// The validation has so far passed, so now
// we can validate item-specific fields.
return this.validateCustom();
},
exportDialog: function ($this) {
var $msg = Functions.ajaxShowMessage();
if ($this.attr('id') === 'bulkActionExportButton') {
var combined = {
success: true,
title: Messages.strExport,
message: '',
error: ''
};
// export anchors of all selected rows
var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor');
var count = exportAnchors.length;
var returnCount = 0;
var p = $.when();
exportAnchors.each(function () {
var h = $(this).attr('href');
p = p.then(function () {
return $.get(h, { 'ajax_request': true }, function (data) {
returnCount++;
if (data.success === true) {
combined.message += '\n' + data.message + '\n';
if (returnCount === count) {
showExport(combined);
}
} else {
// complain even if one export is failing
combined.success = false;
combined.error += '\n' + data.error + '\n';
if (returnCount === count) {
showExport(combined);
}
}
});
});
});
} else {
$.get($this.attr('href'), { 'ajax_request': true }, showExport);
}
Functions.ajaxRemoveMessage($msg);
function showExport (data) {
if (data.success === true) {
Functions.ajaxRemoveMessage($msg);
/**
* @var buttonOptions Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-primary',
click: function () {
$(this).dialog('close').remove();
},
},
};
/**
* Display the dialog to the user
*/
data.message = '<textarea cols="40" rows="15" class="w-100">' + data.message + '</textarea>';
var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 500,
buttons: buttonOptions,
title: data.title
});
// Attach syntax highlighted editor to export dialog
/**
* @var $elm jQuery object containing the reference
* to the Export textarea.
*/
var $elm = $ajaxDialog.find('textarea');
Functions.getSqlEditor($elm);
} else {
Functions.ajaxShowMessage(data.error, false);
}
} // end showExport()
}, // end exportDialog()
editorDialog: function (isNew, $this) {
var that = this;
/**
* @var $edit_row jQuery object containing the reference to
* the row of the the item being edited
* from the list of items
*/
var $editRow = null;
if ($this.hasClass('edit_anchor')) {
// Remember the row of the item being edited for later,
// so that if the edit is successful, we can replace the
// row with info about the modified item.
$editRow = $this.parents('tr');
}
/**
* @var $msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage();
$.get($this.attr('href'), { 'ajax_request': true }, function (data) {
if (data.success === true) {
// We have successfully fetched the editor form
Functions.ajaxRemoveMessage($msg);
/**
* @var buttonOptions Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary',
},
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-secondary',
},
};
// Now define the function that is called when
// the user presses the "Go" button
buttonOptions[Messages.strGo].click = function () {
// Move the data from the codemirror editor back to the
// textarea, where it can be used in the form submission.
if (typeof CodeMirror !== 'undefined') {
that.syntaxHiglighter.save();
}
// Validate editor and submit request, if passed.
if (that.validate()) {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $('form.rte_form').last().serialize();
$msg = Functions.ajaxShowMessage(
Messages.strProcessingRequest
);
var url = $('form.rte_form').last().attr('action');
$.post(url, data, function (data) {
if (data.success === true) {
// Item created successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
that.$ajaxDialog.dialog('close');
// If we are in 'edit' mode, we must
// remove the reference to the old row.
if (mode === 'edit' && $editRow !== null) {
$editRow.remove();
}
// Sometimes, like when moving a trigger from
// a table to another one, the new row should
// not be inserted into the list. In this case
// "data.insert" will be set to false.
if (data.insert) {
// Insert the new row at the correct
// location in the list of items
/**
* @var text Contains the name of an item from
* the list that is used in comparisons
* to find the correct location where
* to insert a new row.
*/
var text = '';
/**
* @var inserted Whether a new item has been
* inserted in the list or not
*/
var inserted = false;
$('table.data').find('tr').each(function () {
text = $(this)
.children('td')
.eq(0)
.find('strong')
.text()
.toUpperCase()
.trim();
if (text !== '' && text > data.name) {
$(this).before(data.new_row);
inserted = true;
return false;
}
});
if (! inserted) {
// If we didn't manage to insert the row yet,
// it must belong at the end of the list,
// so we insert it there.
$('table.data').append(data.new_row);
}
// Fade-in the new row
$('tr.ajaxInsert')
.show('slow')
.removeClass('ajaxInsert');
} else if ($('table.data').find('tr').has('td').length === 0) {
// If we are not supposed to insert the new row,
// we will now check if the table is empty and
// needs to be hidden. This will be the case if
// we were editing the only item in the list,
// which we removed and will not be inserting
// something else in its place.
$('table.data').hide('slow', function () {
$('#nothing2display').show('slow');
});
}
// Now we have inserted the row at the correct
// position, but surely at least some row classes
// are wrong now. So we will iterate through
// all rows and assign correct classes to them
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$('table.data').find('tr').has('td').each(function () {
rowclass = (ct % 2 === 0) ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
// If this is the first item being added, remove
// the "No items" message and show the list.
if ($('table.data').find('tr').has('td').length > 0 &&
$('#nothing2display').is(':visible')
) {
$('#nothing2display').hide('slow', function () {
$('table.data').show('slow');
});
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
} // end "if (that.validate())"
}; // end of function that handles the submission of the Editor
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close');
};
/**
* Display the dialog to the user
*/
that.$ajaxDialog = $('<div id="rteDialog">' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 700,
minWidth: 500,
buttons: buttonOptions,
// Issue #15810 - use button titles for modals (eg: new procedure)
// Respect the order: title on href tag, href content, title sent in response
title: $this.attr('title') || $this.text() || $(data.title).text(),
modal: true,
open: function () {
$('#rteDialog').dialog('option', 'max-height', $(window).height());
if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) {
$('#rteDialog').dialog('option', 'height', $(window).height());
}
$(this).find('input[name=item_name]').trigger('focus');
$(this).find('input.datefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'date');
});
$(this).find('input.datetimefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'datetime');
});
$.datepicker.initialized = false;
},
close: function () {
$(this).remove();
}
});
/**
* @var mode Used to remember whether the editor is in
* "Edit" or "Add" mode
*/
var mode = 'add';
if ($('input[name=editor_process_edit]').length > 0) {
mode = 'edit';
}
// Attach syntax highlighted editor to the definition
/**
* @var elm jQuery object containing the reference to
* the Definition textarea.
*/
var $elm = $('textarea[name=item_definition]').last();
var linterOptions = {};
linterOptions.eventEditor = true;
that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.get()
},
dropDialog: function ($this) {
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $this.parents('tr');
/**
* @var question String containing the question to be asked for confirmation
*/
var question = $('<div></div>').text(
$currRow.children('td').children('.drop_sql').html()
);
// We ask for confirmation first here, before submitting the ajax request
$this.confirm(question, $this.attr('href'), function (url) {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $this.getPostData());
$.post(url, params, function (data) {
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('slow', function () {
$(this).remove();
// Now we have removed the row from the list, but maybe
// some row classes are wrong now. So we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = (ct % 2 === 1) ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
});
}
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
// Show the query that we just executed
Functions.slidingMessage(data.sql_query);
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
},
dropMultipleDialog: function ($this) {
// We ask for confirmation here
$this.confirm(Messages.strDropRTEitems, '', function () {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
// drop anchors of all selected rows
var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor');
var success = true;
var count = dropAnchors.length;
var returnCount = 0;
dropAnchors.each(function () {
var $anchor = $(this);
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $anchor.parents('tr');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
$.post($anchor.attr('href'), params, function (data) {
returnCount++;
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('fast', function () {
// we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = (ct % 2 === 1) ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
});
$currRow.remove();
}
if (returnCount === count) {
if (success) {
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
$('#rteListForm_checkall').prop({ checked: false, indeterminate: false });
}
Navigation.reload();
}
} else {
Functions.ajaxShowMessage(data.error, false);
success = false;
if (returnCount === count) {
Navigation.reload();
}
}
}); // end $.post()
}); // end drop_anchors.each()
});
},
/**
* Validate custom editor form fields.
*
* @return {bool}
*/
validateCustom: function () {
/**
* @var elm a jQuery object containing the reference
* to an element that is being validated
*/
var $elm = null;
if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'RECURRING') {
// The interval field must not be empty for recurring events
$elm = this.$ajaxDialog.find('input[name=item_interval_value]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
} else {
// The execute_at field must not be empty for "once off" events
$elm = this.$ajaxDialog.find('input[name=item_execute_at]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
}
return true;
}
};
AJAX.registerOnload('database/events.js', function () {
/**
* Attach Ajax event handlers for the Add/Edit functionality.
*/
$(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) {
event.preventDefault();
if ($(this).hasClass('add_anchor')) {
$.datepicker.initialized = false;
}
DatabaseEvents.editorDialog($(this).hasClass('add_anchor'), $(this));
});
/**
* Attach Ajax event handlers for Export
*/
$(document).on('click', 'a.ajax.export_anchor', function (event) {
event.preventDefault();
DatabaseEvents.exportDialog($(this));
}); // end $(document).on()
$(document).on('click', '#bulkActionExportButton', function (event) {
event.preventDefault();
DatabaseEvents.exportDialog($(this));
}); // end $(document).on()
/**
* Attach Ajax event handlers for Drop functionality
*/
$(document).on('click', 'a.ajax.drop_anchor', function (event) {
event.preventDefault();
DatabaseEvents.dropDialog($(this));
}); // end $(document).on()
$(document).on('click', '#bulkActionDropButton', function (event) {
event.preventDefault();
DatabaseEvents.dropMultipleDialog($(this));
}); // end $(document).on()
/**
* Attach Ajax event handlers for the "Change event type" functionality, so that the correct
* rows are shown in the editor when changing the event type
*/
$(document).on('change', 'select[name=item_type]', function () {
$(this).closest('table').find('tr.recurring_event_row, tr.onetime_event_row').toggle();
});
});

View file

@ -1,224 +0,0 @@
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
* @requires js/database/query_generator.js
*
*/
/* global generateFromBlock, generateWhereBlock */ // js/database/query_generator.js
/**
* js file for handling AJAX and other events in /database/multi-table-query
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/multi_table_query.js', function () {
$('.tableNameSelect').each(function () {
$(this).off('change');
});
$('#update_query_button').off('click');
$('#add_column_button').off('click');
});
AJAX.registerOnload('database/multi_table_query.js', function () {
var editor = Functions.getSqlEditor($('#MultiSqlquery'), {}, 'both');
$('.CodeMirror-line').css('text-align', 'left');
editor.setSize(-1, 50);
var columnCount = 3;
addNewColumnCallbacks();
$('#update_query_button').on('click', function () {
var columns = [];
var tableAliases = {};
$('.tableNameSelect').each(function () {
var $show = $(this).siblings('.show_col').first();
if ($(this).val() !== '' && $show.prop('checked')) {
var tableAlias = $(this).siblings('.table_alias').first().val();
var columnAlias = $(this).siblings('.col_alias').first().val();
if (tableAlias !== '') {
columns.push([tableAlias, $(this).siblings('.columnNameSelect').first().val()]);
} else {
columns.push([$(this).val(), $(this).siblings('.columnNameSelect').first().val()]);
}
columns[columns.length - 1].push(columnAlias);
if ($(this).val() in tableAliases) {
if (!(tableAliases[$(this).val()].includes(tableAlias))) {
tableAliases[$(this).val()].push(tableAlias);
}
} else {
tableAliases[$(this).val()] = [tableAlias];
}
}
});
if (Object.keys(tableAliases).length === 0) {
Functions.ajaxShowMessage('Nothing selected', false, 'error');
return;
}
var foreignKeys;
$.ajax({
type: 'GET',
async: false,
url: 'index.php?route=/database/multi-table-query/tables',
data: {
'server': sessionStorage.server,
'db': $('#db_name').val(),
'tables': Object.keys(tableAliases),
'ajax_request': '1',
'token': CommonParams.get('token')
},
success: function (response) {
foreignKeys = response.foreignKeyConstrains;
}
});
var query = 'SELECT ' + '`' + Functions.escapeBacktick(columns[0][0]) + '`.';
if (columns[0][1] === '*') {
query += '*';
} else {
query += '`' + Functions.escapeBacktick(columns[0][1]) + '`';
}
if (columns[0][2] !== '') {
query += ' AS `' + Functions.escapeBacktick(columns[0][2]) + '`';
}
for (var i = 1; i < columns.length; i++) {
query += ', `' + Functions.escapeBacktick(columns[i][0]) + '`.';
if (columns[i][1] === '*') {
query += '*';
} else {
query += '`' + Functions.escapeBacktick(columns[i][1]) + '`';
}
if (columns[i][2] !== '') {
query += ' AS `' + Functions.escapeBacktick(columns[i][2]) + '`';
}
}
query += '\nFROM ';
query += generateFromBlock(tableAliases, foreignKeys);
var $criteriaColCount = $('.criteria_col:checked').length;
if ($criteriaColCount > 0) {
query += '\nWHERE ';
query += generateWhereBlock();
}
query += ';';
editor.getDoc().setValue(query);
});
$('#submit_query').on('click', function () {
var query = editor.getDoc().getValue();
// Verifying that the query is not empty
if (query === '') {
Functions.ajaxShowMessage(Messages.strEmptyQuery, false, 'error');
return;
}
var data = {
'db': $('#db_name').val(),
'sql_query': query,
'ajax_request': '1',
'server': CommonParams.get('server'),
'token': CommonParams.get('token')
};
$.ajax({
type: 'POST',
url: 'index.php?route=/database/multi-table-query/query',
data: data,
success: function (data) {
var $resultsDom = $(data.message);
$resultsDom.find('.ajax:not(.pageselector)').each(function () {
$(this).on('click', function (event) {
event.preventDefault();
});
});
$resultsDom.find('.autosubmit, .pageselector, .showAllRows, .filter_rows').each(function () {
$(this).on('change click select focus', function (event) {
event.preventDefault();
});
});
$('#sql_results').html($resultsDom);
$('#slide-handle').trigger('click');// Collapse search criteria area
}
});
});
$('#add_column_button').on('click', function () {
columnCount++;
var $newColumnDom = $($('#new_column_layout').html()).clone();
$newColumnDom.find('.jsCriteriaButton').first().attr('data-bs-target', '#criteriaOptionsExtra' + columnCount.toString());
$newColumnDom.find('.jsCriteriaButton').first().attr('aria-controls', 'criteriaOptionsExtra' + columnCount.toString());
$newColumnDom.find('.jsCriteriaOptions').first().attr('id', 'criteriaOptionsExtra' + columnCount.toString());
$('#add_column_button').parent().before($newColumnDom);
addNewColumnCallbacks();
});
function addNewColumnCallbacks () {
$('.tableNameSelect').each(function () {
$(this).on('change', function () {
var $sibs = $(this).siblings('.columnNameSelect');
if ($sibs.length === 0) {
$sibs = $(this).parent().parent().find('.columnNameSelect');
}
$sibs.first().html($('#' + $(this).find(':selected').data('hash')).html());
});
});
$('.jsRemoveColumn').each(function () {
$(this).on('click', function () {
$(this).parent().remove();
});
});
$('.jsCriteriaButton').each(function () {
$(this).on('click', function (event, from) {
if (from === null) {
var $checkbox = $(this).siblings('.criteria_col').first();
$checkbox.prop('checked', !$checkbox.prop('checked'));
}
var $criteriaColCount = $('.criteria_col:checked').length;
if ($criteriaColCount > 1) {
$(this).siblings('.jsCriteriaOptions').first().find('.logical_operator').first().css('display','table-row');
}
});
});
$('.criteria_col').each(function () {
$(this).on('change', function () {
var $anchor = $(this).siblings('.jsCriteriaButton').first();
if ($(this).is(':checked') && ! $anchor.hasClass('collapsed')) {
// Do not collapse on checkbox tick as it does not make sense
// The user has it open and wants to tick the box
return;
}
$anchor.trigger('click', ['Trigger']);
});
});
$('.criteria_rhs').each(function () {
$(this).on('change', function () {
var $rhsCol = $(this).parent().parent().siblings('.rhs_table').first();
var $rhsText = $(this).parent().parent().siblings('.rhs_text').first();
if ($(this).val() === 'text') {
$rhsCol.css('display', 'none');
$rhsText.css('display', 'table-row');
} else if ($(this).val() === 'anotherColumn') {
$rhsText.css('display', 'none');
$rhsCol.css('display', 'table-row');
} else {
$rhsText.css('display', 'none');
$rhsCol.css('display', 'none');
}
});
});
}
});

View file

@ -1,177 +0,0 @@
/**
* @fileoverview function used in server privilege pages
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Ajax event handlers here for /database/operations
*
* Actions Ajaxified here:
* Rename Database
* Copy Database
* Change Charset
* Drop Database
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/operations.js', function () {
$(document).off('submit', '#rename_db_form.ajax');
$(document).off('submit', '#copy_db_form.ajax');
$(document).off('submit', '#change_db_charset_form.ajax');
$(document).off('click', '#drop_db_anchor.ajax');
});
AJAX.registerOnload('database/operations.js', function () {
/**
* Ajax event handlers for 'Rename Database'
*/
$(document).on('submit', '#rename_db_form.ajax', function (event) {
event.preventDefault();
if (Functions.emptyCheckTheField(this, 'newname')) {
Functions.ajaxShowMessage(Messages.strFormEmpty, false, 'error');
return false;
}
var oldDbName = CommonParams.get('db');
var newDbName = $('#new_db_name').val();
if (newDbName === oldDbName) {
Functions.ajaxShowMessage(Messages.strDatabaseRenameToSameName, false, 'error');
return false;
}
var $form = $(this);
var question = Functions.escapeHtml('CREATE DATABASE ' + newDbName + ' / DROP DATABASE ' + oldDbName);
Functions.prepareForAjaxRequest($form);
$form.confirm(question, $form.attr('action'), function (url) {
Functions.ajaxShowMessage(Messages.strRenamingDatabases, false);
$.post(url, $('#rename_db_form').serialize() + CommonParams.get('arg_separator') + 'is_js_confirmed=1', function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
CommonParams.set('db', data.newname);
Navigation.reload(function () {
$('#pma_navigation_tree')
.find('a:not(\'.expander\')')
.each(function () {
var $thisAnchor = $(this);
if ($thisAnchor.text() === data.newname) {
// simulate a click on the new db name
// in navigation
$thisAnchor.trigger('click');
}
});
});
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
}); // end Rename Database
/**
* Ajax Event Handler for 'Copy Database'
*/
$(document).on('submit', '#copy_db_form.ajax', function (event) {
event.preventDefault();
if (Functions.emptyCheckTheField(this, 'newname')) {
Functions.ajaxShowMessage(Messages.strFormEmpty, false, 'error');
return false;
}
Functions.ajaxShowMessage(Messages.strCopyingDatabase, false);
var $form = $(this);
Functions.prepareForAjaxRequest($form);
$.post($form.attr('action'), $form.serialize(), function (data) {
// use messages that stay on screen
$('.alert-success, .alert-danger').fadeOut();
if (typeof data !== 'undefined' && data.success === true) {
if ($('#checkbox_switch').is(':checked')) {
CommonParams.set('db', data.newname);
CommonActions.refreshMain(false, function () {
Functions.ajaxShowMessage(data.message);
});
} else {
CommonParams.set('db', data.db);
Functions.ajaxShowMessage(data.message);
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end copy database
/**
* Change tables columns visible only if change tables is checked
*/
$('#span_change_all_tables_columns_collations').hide();
$('#checkbox_change_all_tables_collations').on('click', function () {
$('#span_change_all_tables_columns_collations').toggle();
});
/**
* Ajax Event handler for 'Change Charset' of the database
*/
$(document).on('submit', '#change_db_charset_form.ajax', function (event) {
event.preventDefault();
var $form = $(this);
Functions.prepareForAjaxRequest($form);
Functions.ajaxShowMessage(Messages.strChangingCharset);
$.post($form.attr('action'), $form.serialize(), function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}); // end change charset
/**
* Ajax event handlers for Drop Database
*/
$(document).on('click', '#drop_db_anchor.ajax', function (event) {
event.preventDefault();
var $link = $(this);
/**
* @var {String} question String containing the question to be asked for confirmation
*/
var question = Messages.strDropDatabaseStrongWarning + ' ';
question += Functions.sprintf(
Messages.strDoYouReally,
'DROP DATABASE `' + Functions.escapeHtml(CommonParams.get('db') + '`')
);
var params = Functions.getJsConfirmCommonParam(this, $link.getPostData());
$(this).confirm(question, $(this).attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strProcessingRequest);
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
// Database deleted successfully, refresh both the frames
Navigation.reload();
CommonParams.set('db', '');
CommonActions.refreshMain(
'index.php?route=/server/databases',
function () {
Functions.ajaxShowMessage(data.message);
}
);
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
});
});

View file

@ -1,86 +0,0 @@
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/**
* Ajax event handlers here for /database/qbe
*
* Actions Ajaxified here:
* Select saved search
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/qbe.js', function () {
$(document).off('change', 'select[name^=criteriaColumn]');
$(document).off('change', '#searchId');
$(document).off('click', '#saveSearch');
$(document).off('click', '#updateSearch');
$(document).off('click', '#deleteSearch');
});
AJAX.registerOnload('database/qbe.js', function () {
Functions.getSqlEditor($('#textSqlquery'), {}, 'none');
$('#tblQbe').width($('#tblQbe').parent().width());
$('#tblQbeFooters').width($('#tblQbeFooters').parent().width());
$('#tblQbe').on('resize', function () {
var newWidthTblQbe = $('#textSqlquery').next().width();
$('#tblQbe').width(newWidthTblQbe);
$('#tblQbeFooters').width(newWidthTblQbe);
});
/**
* Ajax handler to check the corresponding 'show' checkbox when column is selected
*/
$(document).on('change', 'select[name^=criteriaColumn]', function () {
if ($(this).val()) {
var index = (/\d+/).exec($(this).attr('name'));
$('input[name=criteriaShow\\[' + index + '\\]]').prop('checked', true);
}
});
/**
* Ajax event handlers for 'Select saved search'
*/
$(document).on('change', '#searchId', function () {
$('#action').val('load');
$('#formQBE').trigger('submit');
});
/**
* Ajax event handlers for 'Create bookmark'
*/
$(document).on('click', '#saveSearch', function () {
$('#action').val('create');
});
/**
* Ajax event handlers for 'Update bookmark'
*/
$(document).on('click', '#updateSearch', function () {
$('#action').val('update');
});
/**
* Ajax event handlers for 'Delete bookmark'
*/
$(document).on('click', '#deleteSearch', function () {
var question = Functions.sprintf(Messages.strConfirmDeleteQBESearch, $('#searchId').find('option:selected').text());
if (!confirm(question)) {
return false;
}
$('#action').val('delete');
});
var windowwidth = $(window).width();
$('.jsresponsive').css('max-width', (windowwidth - 35) + 'px');
});

View file

@ -1,131 +0,0 @@
/**
* @fileoverview function used in QBE for DB
* @name Database Operations
*
* @requires jQuery
* @requires jQueryUI
* @requires js/functions.js
*
*/
/* global sprintf */ // js/vendor/sprintf.js
function getFormatsText () {
return {
'=': ' = \'%s\'',
'>': ' > \'%s\'',
'>=': ' >= \'%s\'',
'<': ' < \'%s\'',
'<=': ' <= \'%s\'',
'!=': ' != \'%s\'',
'LIKE': ' LIKE \'%s\'',
'LIKE %...%': ' LIKE \'%%%s%%\'',
'NOT LIKE': ' NOT LIKE \'%s\'',
'NOT LIKE %...%': ' NOT LIKE \'%%%s%%\'',
'BETWEEN': ' BETWEEN \'%s\'',
'NOT BETWEEN': ' NOT BETWEEN \'%s\'',
'IS NULL': ' \'%s\' IS NULL',
'IS NOT NULL': ' \'%s\' IS NOT NULL',
'REGEXP': ' REGEXP \'%s\'',
'REGEXP ^...$': ' REGEXP \'^%s$\'',
'NOT REGEXP': ' NOT REGEXP \'%s\''
};
}
function generateCondition (criteriaDiv, table) {
var query = '`' + Functions.escapeBacktick(table.val()) + '`.';
query += '`' + Functions.escapeBacktick(table.siblings('.columnNameSelect').first().val()) + '`';
if (criteriaDiv.find('.criteria_rhs').first().val() === 'text') {
var formatsText = getFormatsText();
query += sprintf(formatsText[criteriaDiv.find('.criteria_op').first().val()], Functions.escapeSingleQuote(criteriaDiv.find('.rhs_text_val').first().val()));
} else {
query += ' ' + criteriaDiv.find('.criteria_op').first().val();
query += ' `' + Functions.escapeBacktick(criteriaDiv.find('.tableNameSelect').first().val()) + '`.';
query += '`' + Functions.escapeBacktick(criteriaDiv.find('.columnNameSelect').first().val()) + '`';
}
return query;
}
// eslint-disable-next-line no-unused-vars
function generateWhereBlock () {
var count = 0;
var query = '';
$('.tableNameSelect').each(function () {
var criteriaDiv = $(this).siblings('.jsCriteriaOptions').first();
var useCriteria = $(this).siblings('.criteria_col').first();
if ($(this).val() !== '' && useCriteria.prop('checked')) {
if (count > 0) {
criteriaDiv.find('input.logical_op').each(function () {
if ($(this).prop('checked')) {
query += ' ' + $(this).val() + ' ';
}
});
}
query += generateCondition(criteriaDiv, $(this));
count++;
}
});
return query;
}
function generateJoin (newTable, tableAliases, fk) {
var query = '';
query += ' \n\tLEFT JOIN ' + '`' + Functions.escapeBacktick(newTable) + '`';
if (tableAliases[fk.TABLE_NAME][0] !== '') {
query += ' AS `' + Functions.escapeBacktick(tableAliases[newTable][0]) + '`';
query += ' ON `' + Functions.escapeBacktick(tableAliases[fk.TABLE_NAME][0]) + '`';
} else {
query += ' ON `' + Functions.escapeBacktick(fk.TABLE_NAME) + '`';
}
query += '.`' + fk.COLUMN_NAME + '`';
if (tableAliases[fk.REFERENCED_TABLE_NAME][0] !== '') {
query += ' = `' + Functions.escapeBacktick(tableAliases[fk.REFERENCED_TABLE_NAME][0]) + '`';
} else {
query += ' = `' + Functions.escapeBacktick(fk.REFERENCED_TABLE_NAME) + '`';
}
query += '.`' + fk.REFERENCED_COLUMN_NAME + '`';
return query;
}
function existReference (table, fk, usedTables) {
var isReferredBy = fk.TABLE_NAME === table && usedTables.includes(fk.REFERENCED_TABLE_NAME);
var isReferencedBy = fk.REFERENCED_TABLE_NAME === table && usedTables.includes(fk.TABLE_NAME);
return isReferredBy || isReferencedBy;
}
function tryJoinTable (table, tableAliases, usedTables, foreignKeys) {
for (var i = 0; i < foreignKeys.length; i++) {
var fk = foreignKeys[i];
if (existReference(table, fk, usedTables)) {
return generateJoin(table, tableAliases, fk);
}
}
return '';
}
function appendTable (table, tableAliases, usedTables, foreignKeys) {
var query = tryJoinTable (table, tableAliases, usedTables, foreignKeys);
if (query === '') {
if (usedTables.length > 0) {
query += '\n\t, ';
}
query += '`' + Functions.escapeBacktick(table) + '`';
if (tableAliases[table][0] !== '') {
query += ' AS `' + Functions.escapeBacktick(tableAliases[table][0]) + '`';
}
}
usedTables.push(table);
return query;
}
// eslint-disable-next-line no-unused-vars
function generateFromBlock (tableAliases, foreignKeys) {
var usedTables = [];
var query = '';
for (var table in tableAliases) {
if (tableAliases.hasOwnProperty(table)) {
query += appendTable(table, tableAliases, usedTables, foreignKeys);
}
}
return query;
}

View file

@ -1,964 +0,0 @@
AJAX.registerTeardown('database/routines.js', function () {
$(document).off('click', 'a.ajax.add_anchor');
$(document).off('click', 'a.ajax.edit_anchor');
$(document).off('click', 'a.ajax.exec_anchor');
$(document).off('click', 'a.ajax.export_anchor');
$(document).off('click', '#bulkActionExportButton');
$(document).off('click', 'a.ajax.drop_anchor');
$(document).off('click', '#bulkActionDropButton');
$(document).off('change', 'select[name=item_type]');
$(document).off('change', 'select[name^=item_param_type]');
$(document).off('change', 'select[name=item_returntype]');
$(document).off('click', '#addRoutineParameterButton');
$(document).off('click', 'a.routine_param_remove_anchor');
});
const DatabaseRoutines = {
/**
* @var {string} paramTemplate Template for a row in the routine editor
*/
paramTemplate: '',
/**
* @var $ajaxDialog Query object containing the reference to the
* dialog that contains the editor
*/
$ajaxDialog: null,
/**
* @var syntaxHiglighter Reference to the codemirror editor
*/
syntaxHiglighter: null,
/**
* Validate editor form fields.
*
* @return {bool}
*/
validate: function () {
/**
* @var $elm a jQuery object containing the reference
* to an element that is being validated
*/
var $elm = null;
// Common validation. At the very least the name
// and the definition must be provided for an item
$elm = $('table.rte_table').last().find('input[name=item_name]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
$elm = $('table.rte_table').find('textarea[name=item_definition]');
if ($elm.val() === '') {
if (this.syntaxHiglighter !== null) {
this.syntaxHiglighter.focus();
} else {
$('textarea[name=item_definition]').last().trigger('focus');
}
alert(Messages.strFormEmpty);
return false;
}
// The validation has so far passed, so now
// we can validate item-specific fields.
return this.validateCustom();
},
exportDialog: function ($this) {
var $msg = Functions.ajaxShowMessage();
if ($this.attr('id') === 'bulkActionExportButton') {
var combined = {
success: true,
title: Messages.strExport,
message: '',
error: ''
};
// export anchors of all selected rows
var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor');
var count = exportAnchors.length;
var returnCount = 0;
// No routine is exportable (due to privilege issues)
if (count === 0) {
Functions.ajaxShowMessage(Messages.NoExportable);
}
var p = $.when();
exportAnchors.each(function () {
var h = $(this).attr('href');
p = p.then(function () {
return $.get(h, { 'ajax_request': true }, function (data) {
returnCount++;
if (data.success === true) {
combined.message += '\n' + data.message + '\n';
if (returnCount === count) {
showExport(combined);
}
} else {
// complain even if one export is failing
combined.success = false;
combined.error += '\n' + data.error + '\n';
if (returnCount === count) {
showExport(combined);
}
}
});
});
});
} else {
$.get($this.attr('href'), { 'ajax_request': true }, showExport);
}
Functions.ajaxRemoveMessage($msg);
function showExport (data) {
if (data.success === true) {
Functions.ajaxRemoveMessage($msg);
/**
* @var buttonOptions Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-primary',
click: function () {
$(this).dialog('close').remove();
}
},
};
/**
* Display the dialog to the user
*/
data.message = '<textarea cols="40" rows="15" class="w-100">' + data.message + '</textarea>';
var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 500,
buttons: buttonOptions,
title: data.title
});
// Attach syntax highlighted editor to export dialog
/**
* @var $elm jQuery object containing the reference
* to the Export textarea.
*/
var $elm = $ajaxDialog.find('textarea');
Functions.getSqlEditor($elm);
} else {
Functions.ajaxShowMessage(data.error, false);
}
} // end showExport()
}, // end exportDialog()
editorDialog: function (isNew, $this) {
var that = this;
/**
* @var $edit_row jQuery object containing the reference to
* the row of the the item being edited
* from the list of items
*/
var $editRow = null;
if ($this.hasClass('edit_anchor')) {
// Remember the row of the item being edited for later,
// so that if the edit is successful, we can replace the
// row with info about the modified item.
$editRow = $this.parents('tr');
}
/**
* @var $msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage();
$.get($this.attr('href'), { 'ajax_request': true }, function (data) {
if (data.success === true) {
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary',
},
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-secondary',
},
};
// We have successfully fetched the editor form
Functions.ajaxRemoveMessage($msg);
// Now define the function that is called when
// the user presses the "Go" button
buttonOptions[Messages.strGo].click = function () {
// Move the data from the codemirror editor back to the
// textarea, where it can be used in the form submission.
if (typeof CodeMirror !== 'undefined') {
that.syntaxHiglighter.save();
}
// Validate editor and submit request, if passed.
if (that.validate()) {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $('form.rte_form').last().serialize();
$msg = Functions.ajaxShowMessage(
Messages.strProcessingRequest
);
var url = $('form.rte_form').last().attr('action');
$.post(url, data, function (data) {
if (data.success === true) {
// Item created successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
that.$ajaxDialog.dialog('close');
var tableId = '#' + data.tableType + 'Table';
// If we are in 'edit' mode, we must
// remove the reference to the old row.
if (mode === 'edit' && $editRow !== null) {
$editRow.remove();
}
// Sometimes, like when moving a trigger from
// a table to another one, the new row should
// not be inserted into the list. In this case
// "data.insert" will be set to false.
if (data.insert) {
// Insert the new row at the correct
// location in the list of items
/**
* @var text Contains the name of an item from
* the list that is used in comparisons
* to find the correct location where
* to insert a new row.
*/
var text = '';
/**
* @var inserted Whether a new item has been
* inserted in the list or not
*/
var inserted = false;
$(tableId + '.data').find('tr').each(function () {
text = $(this)
.children('td')
.eq(0)
.find('strong')
.text()
.toUpperCase()
.trim();
if (text !== '' && text > data.name) {
$(this).before(data.new_row);
inserted = true;
return false;
}
});
if (! inserted) {
// If we didn't manage to insert the row yet,
// it must belong at the end of the list,
// so we insert it there.
$(tableId + '.data').append(data.new_row);
}
// Fade-in the new row
$('tr.ajaxInsert')
.show('slow')
.removeClass('ajaxInsert');
} else if ($(tableId + '.data').find('tr').has('td').length === 0) {
// If we are not supposed to insert the new row,
// we will now check if the table is empty and
// needs to be hidden. This will be the case if
// we were editing the only item in the list,
// which we removed and will not be inserting
// something else in its place.
$(tableId + '.data').hide('slow', function () {
$('#nothing2display').show('slow');
});
}
// Now we have inserted the row at the correct
// position, but surely at least some row classes
// are wrong now. So we will iterate through
// all rows and assign correct classes to them
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$(tableId + '.data').find('tr').has('td').each(function () {
rowclass = (ct % 2 === 0) ? 'odd' : 'even';
$(this).removeClass('odd even').addClass(rowclass);
ct++;
});
// If this is the first item being added, remove
// the "No items" message and show the list.
if ($(tableId + '.data').find('tr').has('td').length > 0 &&
$('#nothing2display').is(':visible')
) {
$('#nothing2display').hide('slow', function () {
$(tableId + '.data').show('slow');
});
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
} // end "if (that.validate())"
}; // end of function that handles the submission of the Editor
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close');
};
/**
* Display the dialog to the user
*/
that.$ajaxDialog = $('<div id="rteDialog">' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
height: 400,
width: 700,
minWidth: 500,
buttons: buttonOptions,
// Issue #15810 - use button titles for modals (eg: new procedure)
// Respect the order: title on href tag, href content, title sent in response
title: $this.attr('title') || $this.text() || $(data.title).text(),
modal: true,
open: function () {
$('#rteDialog').dialog('option', 'max-height', $(window).height());
if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) {
$('#rteDialog').dialog('option', 'height', $(window).height());
}
$(this).find('input[name=item_name]').trigger('focus');
$(this).find('input.datefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'date');
});
$(this).find('input.datetimefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'datetime');
});
$.datepicker.initialized = false;
},
close: function () {
$(this).remove();
}
});
/**
* @var mode Used to remember whether the editor is in
* "Edit" or "Add" mode
*/
var mode = 'add';
if ($('input[name=editor_process_edit]').length > 0) {
mode = 'edit';
}
// Attach syntax highlighted editor to the definition
/**
* @var elm jQuery object containing the reference to
* the Definition textarea.
*/
var $elm = $('textarea[name=item_definition]').last();
var linterOptions = {};
linterOptions.routineEditor = true;
that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions);
// Execute item-specific code
that.postDialogShow(data);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.get()
},
dropDialog: function ($this) {
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $this.parents('tr');
/**
* @var question String containing the question to be asked for confirmation
*/
var question = $('<div></div>').text(
$currRow.children('td').children('.drop_sql').html()
);
// We ask for confirmation first here, before submitting the ajax request
$this.confirm(question, $this.attr('href'), function (url) {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $this.getPostData());
$.post(url, params, function (data) {
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent().parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('slow', function () {
$(this).remove();
// Now we have removed the row from the list, but maybe
// some row classes are wrong now. So we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = (ct % 2 === 1) ? 'odd' : 'even';
$(this).removeClass('odd even').addClass(rowclass);
ct++;
});
});
}
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
// Show the query that we just executed
Functions.slidingMessage(data.sql_query);
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
},
dropMultipleDialog: function ($this) {
// We ask for confirmation here
$this.confirm(Messages.strDropRTEitems, '', function () {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
// drop anchors of all selected rows
var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor');
var success = true;
var count = dropAnchors.length;
var returnCount = 0;
dropAnchors.each(function () {
var $anchor = $(this);
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $anchor.parents('tr');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
$.post($anchor.attr('href'), params, function (data) {
returnCount++;
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent().parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('fast', function () {
// we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = (ct % 2 === 1) ? 'odd' : 'even';
$(this).removeClass('odd even').addClass(rowclass);
ct++;
});
});
$currRow.remove();
}
if (returnCount === count) {
if (success) {
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
$('#rteListForm_checkall').prop({ checked: false, indeterminate: false });
}
Navigation.reload();
}
} else {
Functions.ajaxShowMessage(data.error, false);
success = false;
if (returnCount === count) {
Navigation.reload();
}
}
}); // end $.post()
}); // end drop_anchors.each()
});
},
/**
* Execute some code after the ajax dialog for the editor is shown.
*
* @param data JSON-encoded data from the ajax request
*/
postDialogShow: function (data) {
// Cache the template for a parameter table row
DatabaseRoutines.paramTemplate = data.paramTemplate;
var that = this;
// Make adjustments in the dialog to make it AJAX compatible
$('td.routine_param_remove').show();
// Enable/disable the 'options' dropdowns for parameters as necessary
$('table.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1');
$('table.routine_params_table').last().find('tr').has('td').each(function () {
that.setOptionsForParameter(
$(this).find('select[name^=item_param_type]'),
$(this).find('input[name^=item_param_length]'),
$(this).find('select[name^=item_param_opts_text]'),
$(this).find('select[name^=item_param_opts_num]')
);
});
// Enable/disable the 'options' dropdowns for
// function return value as necessary
this.setOptionsForParameter(
$('table.rte_table').last().find('select[name=item_returntype]'),
$('table.rte_table').last().find('input[name=item_returnlength]'),
$('table.rte_table').last().find('select[name=item_returnopts_text]'),
$('table.rte_table').last().find('select[name=item_returnopts_num]')
);
// Allow changing parameter order
$('.routine_params_table tbody').sortable({
containment: '.routine_params_table tbody',
handle: '.dragHandle',
stop: function () {
that.reindexParameters();
},
});
},
/**
* Reindexes the parameters after dropping a parameter or reordering parameters
*/
reindexParameters: function () {
/**
* @var index Counter used for reindexing the input
* fields in the routine parameters table
*/
var index = 0;
$('table.routine_params_table tbody').find('tr').each(function () {
$(this).find(':input').each(function () {
/**
* @var inputname The value of the name attribute of
* the input field being reindexed
*/
var inputname = $(this).attr('name');
if (inputname.substr(0, 14) === 'item_param_dir') {
$(this).attr('name', inputname.substr(0, 14) + '[' + index + ']');
} else if (inputname.substr(0, 15) === 'item_param_name') {
$(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
} else if (inputname.substr(0, 15) === 'item_param_type') {
$(this).attr('name', inputname.substr(0, 15) + '[' + index + ']');
} else if (inputname.substr(0, 17) === 'item_param_length') {
$(this).attr('name', inputname.substr(0, 17) + '[' + index + ']');
$(this).attr('id', 'item_param_length_' + index);
} else if (inputname.substr(0, 20) === 'item_param_opts_text') {
$(this).attr('name', inputname.substr(0, 20) + '[' + index + ']');
} else if (inputname.substr(0, 19) === 'item_param_opts_num') {
$(this).attr('name', inputname.substr(0, 19) + '[' + index + ']');
}
});
index++;
});
},
/**
* Validate custom editor form fields.
*
* @return {bool}
*/
validateCustom: function () {
/**
* @var isSuccess Stores the outcome of the validation
*/
var isSuccess = true;
/**
* @var inputname The value of the "name" attribute for
* the field that is being processed
*/
var inputname = '';
this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
// Every parameter of a routine must have
// a non-empty direction, name and type
if (isSuccess) {
$(this).find(':input').each(function () {
inputname = $(this).attr('name');
if (inputname.substr(0, 14) === 'item_param_dir' ||
inputname.substr(0, 15) === 'item_param_name' ||
inputname.substr(0, 15) === 'item_param_type') {
if ($(this).val() === '') {
$(this).trigger('focus');
isSuccess = false;
return false;
}
}
});
} else {
return false;
}
});
if (! isSuccess) {
alert(Messages.strFormEmpty);
return false;
}
this.$ajaxDialog.find('table.routine_params_table').last().find('tr').each(function () {
// SET, ENUM, VARCHAR and VARBINARY fields must have length/values
var $inputtyp = $(this).find('select[name^=item_param_type]');
var $inputlen = $(this).find('input[name^=item_param_length]');
if ($inputtyp.length && $inputlen.length) {
if (($inputtyp.val() === 'ENUM' || $inputtyp.val() === 'SET' || $inputtyp.val().substr(0, 3) === 'VAR') &&
$inputlen.val() === ''
) {
$inputlen.trigger('focus');
isSuccess = false;
return false;
}
}
});
if (! isSuccess) {
alert(Messages.strFormEmpty);
return false;
}
if (this.$ajaxDialog.find('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
// The length/values of return variable for functions must
// be set, if the type is SET, ENUM, VARCHAR or VARBINARY.
var $returntyp = this.$ajaxDialog.find('select[name=item_returntype]');
var $returnlen = this.$ajaxDialog.find('input[name=item_returnlength]');
if (($returntyp.val() === 'ENUM' || $returntyp.val() === 'SET' || $returntyp.val().substr(0, 3) === 'VAR') &&
$returnlen.val() === ''
) {
$returnlen.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
}
if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') {
// A function must contain a RETURN statement in its definition
if (this.$ajaxDialog.find('table.rte_table').find('textarea[name=item_definition]').val().toUpperCase().indexOf('RETURN') < 0) {
this.syntaxHiglighter.focus();
alert(Messages.MissingReturn);
return false;
}
}
return true;
},
/**
* Enable/disable the "options" dropdown and "length" input for
* parameters and the return variable in the routine editor
* as necessary.
*
* @param $type a jQuery object containing the reference
* to the "Type" dropdown box
* @param $len a jQuery object containing the reference
* to the "Length" input box
* @param $text a jQuery object containing the reference
* to the dropdown box with options for
* parameters of text type
* @param $num a jQuery object containing the reference
* to the dropdown box with options for
* parameters of numeric type
*/
setOptionsForParameter: function ($type, $len, $text, $num) {
/**
* @var no_opts a jQuery object containing the reference
* to an element to be displayed when no
* options are available
*/
var $noOpts = $text.parent().parent().find('.no_opts');
/**
* @var no_len a jQuery object containing the reference
* to an element to be displayed when no
* "length/values" field is available
*/
var $noLen = $len.parent().parent().find('.no_len');
// Process for parameter options
switch ($type.val()) {
case 'TINYINT':
case 'SMALLINT':
case 'MEDIUMINT':
case 'INT':
case 'BIGINT':
case 'DECIMAL':
case 'FLOAT':
case 'DOUBLE':
case 'REAL':
$text.parent().hide();
$num.parent().show();
$noOpts.hide();
break;
case 'TINYTEXT':
case 'TEXT':
case 'MEDIUMTEXT':
case 'LONGTEXT':
case 'CHAR':
case 'VARCHAR':
case 'SET':
case 'ENUM':
$text.parent().show();
$num.parent().hide();
$noOpts.hide();
break;
default:
$text.parent().hide();
$num.parent().hide();
$noOpts.show();
break;
}
// Process for parameter length
switch ($type.val()) {
case 'DATE':
case 'TINYBLOB':
case 'TINYTEXT':
case 'BLOB':
case 'TEXT':
case 'MEDIUMBLOB':
case 'MEDIUMTEXT':
case 'LONGBLOB':
case 'LONGTEXT':
$text.closest('tr').find('a').first().hide();
$len.parent().hide();
$noLen.show();
break;
default:
if ($type.val() === 'ENUM' || $type.val() === 'SET') {
$text.closest('tr').find('a').first().show();
} else {
$text.closest('tr').find('a').first().hide();
}
$len.parent().show();
$noLen.hide();
break;
}
},
executeDialog: function ($this) {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage();
var params = Functions.getJsConfirmCommonParam($this[0], $this.getPostData());
$.post($this.attr('href'), params, function (data) {
if (data.success === true) {
Functions.ajaxRemoveMessage($msg);
// If 'data.dialog' is true we show a dialog with a form
// to get the input parameters for routine, otherwise
// we just show the results of the query
if (data.dialog) {
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary',
},
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-secondary',
},
};
// Define the function that is called when
// the user presses the "Go" button
buttonOptions[Messages.strGo].click = function () {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $('form.rte_form').last().serialize();
$msg = Functions.ajaxShowMessage(
Messages.strProcessingRequest
);
$.post('index.php?route=/database/routines', data, function (data) {
if (data.success === true) {
// Routine executed successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
$ajaxDialog.dialog('close');
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
};
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close');
};
/**
* Display the dialog to the user
*/
var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 650,
buttons: buttonOptions,
title: data.title,
modal: true,
close: function () {
$(this).remove();
}
});
$ajaxDialog.find('input[name^=params]').first().trigger('focus');
/**
* Attach the datepickers to the relevant form fields
*/
$ajaxDialog.find('input.datefield, input.datetimefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'));
});
/*
* Define the function if the user presses enter
*/
$('form.rte_form').on('keyup', function (event) {
event.preventDefault();
if (event.keyCode === 13) {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $(this).serialize();
$msg = Functions.ajaxShowMessage(
Messages.strProcessingRequest
);
var url = $(this).attr('action');
$.post(url, data, function (data) {
if (data.success === true) {
// Routine executed successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
$('form.rte_form').off('keyup');
$ajaxDialog.remove();
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
}
});
} else {
// Routine executed successfully
Functions.slidingMessage(data.message);
}
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
}
};
AJAX.registerOnload('database/routines.js', function () {
$(document).on('click', 'a.ajax.add_anchor', function (event) {
event.preventDefault();
$.datepicker.initialized = false;
DatabaseRoutines.editorDialog(true, $(this));
});
$(document).on('click', 'a.ajax.edit_anchor', function (event) {
event.preventDefault();
DatabaseRoutines.editorDialog(false, $(this));
});
$(document).on('click', 'a.ajax.exec_anchor', function (event) {
event.preventDefault();
DatabaseRoutines.executeDialog($(this));
});
$(document).on('click', 'a.ajax.export_anchor', function (event) {
event.preventDefault();
DatabaseRoutines.exportDialog($(this));
});
$(document).on('click', '#bulkActionExportButton', function (event) {
event.preventDefault();
DatabaseRoutines.exportDialog($(this));
});
$(document).on('click', 'a.ajax.drop_anchor', function (event) {
event.preventDefault();
DatabaseRoutines.dropDialog($(this));
});
$(document).on('click', '#bulkActionDropButton', function (event) {
event.preventDefault();
DatabaseRoutines.dropMultipleDialog($(this));
});
$(document).on('change', 'select[name=item_type]', function () {
$(this).closest('table').find('tr.routine_return_row, .routine_direction_cell').toggle();
});
$(document).on('change', 'select[name^=item_param_type]', function () {
const $row = $(this).parents('tr').first();
DatabaseRoutines.setOptionsForParameter(
$row.find('select[name^=item_param_type]'),
$row.find('input[name^=item_param_length]'),
$row.find('select[name^=item_param_opts_text]'),
$row.find('select[name^=item_param_opts_num]')
);
});
$(document).on('change', 'select[name=item_returntype]', function () {
const $table = $(this).closest('table.rte_table');
DatabaseRoutines.setOptionsForParameter(
$table.find('select[name=item_returntype]'),
$table.find('input[name=item_returnlength]'),
$table.find('select[name=item_returnopts_text]'),
$table.find('select[name=item_returnopts_num]')
);
});
$(document).on('click', '#addRoutineParameterButton', function (event) {
event.preventDefault();
/**
* @var routine_params_table jQuery object containing the reference
* to the routine parameters table
*/
const $routineParamsTable = $(this).closest('div.ui-dialog').find('.routine_params_table');
/**
* @var new_param_row A string containing the HTML code for the
* new row for the routine parameters table
*/
const newParamRow = DatabaseRoutines.paramTemplate.replace(/%s/g, $routineParamsTable.find('tr').length - 1);
// Append the new row to the parameters table
$routineParamsTable.append(newParamRow);
// Make sure that the row is correctly shown according to the type of routine
if ($(this).closest('div.ui-dialog').find('table.rte_table select[name=item_type]').val() === 'FUNCTION') {
$('tr.routine_return_row').show();
$('td.routine_direction_cell').hide();
}
/**
* @var newrow jQuery object containing the reference to the newly
* inserted row in the routine parameters table
*/
const $newrow = $(this).closest('div.ui-dialog').find('table.routine_params_table').find('tr').has('td').last();
// Enable/disable the 'options' dropdowns for parameters as necessary
DatabaseRoutines.setOptionsForParameter(
$newrow.find('select[name^=item_param_type]'),
$newrow.find('input[name^=item_param_length]'),
$newrow.find('select[name^=item_param_opts_text]'),
$newrow.find('select[name^=item_param_opts_num]')
);
});
$(document).on('click', 'a.routine_param_remove_anchor', function (event) {
event.preventDefault();
$(this).parent().parent().remove();
// After removing a parameter, the indices of the name attributes in
// the input fields lose the correct order and need to be reordered.
DatabaseRoutines.reindexParameters();
});
});

View file

@ -1,261 +0,0 @@
/**
* JavaScript functions used on Database Search page
*
* @requires jQuery
* @requires js/functions.js
*
* @package PhpMyAdmin
*/
/* global makeGrid */ // js/makegrid.js
/**
* AJAX script for the Database Search page.
*
* Actions ajaxified here:
* Retrieve result of SQL query
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/search.js', function () {
$('a.browse_results').off('click');
$('a.delete_results').off('click');
$('#buttonGo').off('click');
$('#togglesearchresultlink').off('click');
$('#togglequerybox').off('click');
$('#togglesearchformlink').off('click');
$('#select_all').off('click');
$('#unselect_all').off('click');
$(document).off('submit', '#db_search_form.ajax');
});
AJAX.registerOnload('database/search.js', function () {
/** Hide the table link in the initial search result */
var icon = Functions.getImage('s_tbl', '', { 'id': 'table-image' }).toString();
$('#table-info').prepend(icon).hide();
/** Hide the browse and deleted results in the new search criteria */
$('#buttonGo').on('click', function () {
$('#table-info').hide();
$('#browse-results').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
});
/**
* Prepare a div containing a link for toggle the search results
*/
$('#togglesearchresultsdiv')
/** don't show it until we have results on-screen */
.hide();
/**
* Changing the displayed text according to
* the hide/show criteria in search result forms
*/
$('#togglesearchresultlink')
.html(Messages.strHideSearchResults)
.on('click', function () {
var $link = $(this);
$('#searchresults').slideToggle();
if ($link.text() === Messages.strHideSearchResults) {
$link.text(Messages.strShowSearchResults);
} else {
$link.text(Messages.strHideSearchResults);
}
/** avoid default click action */
return false;
});
/**
* Prepare a div containing a link for toggle the search form,
* otherwise it's incorrectly displayed after a couple of clicks
*/
$('#togglesearchformdiv')
.hide(); // don't show it until we have results on-screen
/**
* Changing the displayed text according to
* the hide/show criteria in search form
*/
$('#togglequerybox')
.hide()
.on('click', function () {
var $link = $(this);
$('#sqlqueryform').slideToggle('medium');
if ($link.text() === Messages.strHideQueryBox) {
$link.text(Messages.strShowQueryBox);
} else {
$link.text(Messages.strHideQueryBox);
}
/** avoid default click action */
return false;
});
/** don't show it until we have results on-screen */
/**
* Changing the displayed text according to
* the hide/show criteria in search criteria form
*/
$('#togglesearchformlink')
.html(Messages.strShowSearchCriteria)
.on('click', function () {
var $link = $(this);
$('#db_search_form').slideToggle();
if ($link.text() === Messages.strHideSearchCriteria) {
$link.text(Messages.strShowSearchCriteria);
} else {
$link.text(Messages.strHideSearchCriteria);
}
/** avoid default click action */
return false;
});
/*
* Ajax Event handler for retrieving the results from a table
*/
$(document).on('click', 'a.browse_results', function (e) {
e.preventDefault();
/** Hides the results shown by the delete criteria */
var $msg = Functions.ajaxShowMessage(Messages.strBrowsing, false);
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Load the browse results to the page */
$('#table-info').show();
var tableName = $(this).data('table-name');
$('#table-link').attr({ 'href' : $(this).attr('href') }).text(tableName);
var url = $(this).attr('href') + '#searchresults';
var browseSql = $(this).data('browse-sql');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query' : browseSql
};
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success) {
$('#browse-results').html(data.message);
Functions.ajaxRemoveMessage($msg);
$('.table_results').each(function () {
makeGrid(this, true, true, true, true);
});
$('#browse-results').show();
Functions.highlightSql($('#browse-results'));
$('html, body')
.animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
} else {
Functions.ajaxShowMessage(data.error, false);
}
});
});
/*
* Ajax Event handler for deleting the results from a table
*/
$(document).on('click', 'a.delete_results', function (e) {
e.preventDefault();
/** Hides the results shown by the browse criteria */
$('#table-info').hide();
$('#sqlqueryform').hide();
$('#togglequerybox').hide();
/** Conformation message for deletion */
var msg = Functions.sprintf(
Messages.strConfirmDeleteResults,
$(this).data('table-name')
);
if (confirm(msg)) {
var $msg = Functions.ajaxShowMessage(Messages.strDeleting, false);
/** Load the deleted option to the page*/
$('#sqlqueryform').html('');
var params = {
'ajax_request': true,
'is_js_confirmed': true,
'sql_query': $(this).data('delete-sql')
};
var url = $(this).attr('href');
$.post(url, params, function (data) {
if (typeof data === 'undefined' || !data.success) {
Functions.ajaxShowMessage(data.error, false);
return;
}
$('#sqlqueryform').html(data.sql_query);
/** Refresh the search results after the deletion */
$('#buttonGo').trigger('click');
$('#togglequerybox').html(Messages.strHideQueryBox);
/** Show the results of the deletion option */
$('#browse-results').hide();
$('#sqlqueryform').show();
$('#togglequerybox').show();
$('html, body')
.animate({
scrollTop: $('#browse-results').offset().top
}, 1000);
Functions.ajaxRemoveMessage($msg);
});
}
});
/**
* Ajax Event handler for retrieving the result of an SQL Query
*/
$(document).on('submit', '#db_search_form.ajax', function (event) {
event.preventDefault();
if ($('#criteriaTables :selected').length === 0) {
Functions.ajaxShowMessage(Messages.strNoTableSelected);
return;
}
var $msgbox = Functions.ajaxShowMessage(Messages.strSearching, false);
// jQuery object to reuse
var $form = $(this);
Functions.prepareForAjaxRequest($form);
var url = $form.serialize() + CommonParams.get('arg_separator') + 'submit_search=' + $('#buttonGo').val();
$.post($form.attr('action'), url, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
// found results
$('#searchresults').html(data.message);
$('#togglesearchresultlink')
// always start with the Show message
.text(Messages.strHideSearchResults);
$('#togglesearchresultsdiv')
// now it's time to show the div containing the link
.show();
$('#searchresults').show();
$('#db_search_form')
// workaround for Chrome problem (bug #3168569)
.slideToggle()
.hide();
$('#togglesearchformlink')
// always start with the Show message
.text(Messages.strShowSearchCriteria);
$('#togglesearchformdiv')
// now it's time to show the div containing the link
.show();
} else {
// error message (zero rows)
$('#searchresults').html(data.error).show();
}
Functions.ajaxRemoveMessage($msgbox);
});
});
$('#select_all').on('click', function () {
Functions.setSelectOptions('db_search', 'criteriaTables[]', true);
return false;
});
$('#unselect_all').on('click', function () {
Functions.setSelectOptions('db_search', 'criteriaTables[]', false);
return false;
});
}); // end $()

View file

@ -1,439 +0,0 @@
/**
* @fileoverview functions used on the database structure page
* @name Database Structure
*
* @requires jQuery
* @requires jQueryUI
* @required js/functions.js
*/
var DatabaseStructure = {};
/**
* AJAX scripts for /database/structure
*
* Actions ajaxified here:
* Drop Database
* Truncate Table
* Drop Table
*
*/
/**
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('database/structure.js', function () {
$(document).off('click', 'a.truncate_table_anchor.ajax');
$(document).off('click', 'a.drop_table_anchor.ajax');
$(document).off('click', '#real_end_input');
$(document).off('click', 'a.favorite_table_anchor.ajax');
$('a.real_row_count').off('click');
$('a.row_count_sum').off('click');
$('select[name=submit_mult]').off('change');
});
/**
* Adjust number of rows and total size in the summary
* when truncating, creating, dropping or inserting into a table
*/
DatabaseStructure.adjustTotals = function () {
var byteUnits = [
Messages.strB,
Messages.strKiB,
Messages.strMiB,
Messages.strGiB,
Messages.strTiB,
Messages.strPiB,
Messages.strEiB
];
/**
* @var $allTr jQuery object that references all the rows in the list of tables
*/
var $allTr = $('#tablesForm').find('table.data tbody').first().find('tr');
// New summary values for the table
var tableSum = $allTr.length;
var rowsSum = 0;
var sizeSum = 0;
var overheadSum = 0;
var rowSumApproximated = false;
$allTr.each(function () {
var $this = $(this);
var i;
var tmpVal;
// Get the number of rows for this SQL table
var strRows = $this.find('.tbl_rows').text();
// If the value is approximated
if (strRows.indexOf('~') === 0) {
rowSumApproximated = true;
// The approximated value contains a preceding ~ (Eg 100 --> ~100)
strRows = strRows.substring(1, strRows.length);
}
strRows = strRows.replace(/[,.\s]/g, '');
var intRow = parseInt(strRows, 10);
if (! isNaN(intRow)) {
rowsSum += intRow;
}
// Extract the size and overhead
var valSize = 0;
var valOverhead = 0;
var strSize = $this.find('.tbl_size span:not(.unit)').text().trim();
var strSizeUnit = $this.find('.tbl_size span.unit').text().trim();
var strOverhead = $this.find('.tbl_overhead span:not(.unit)').text().trim();
var strOverheadUnit = $this.find('.tbl_overhead span.unit').text().trim();
// Given a value and a unit, such as 100 and KiB, for the table size
// and overhead calculate their numeric values in bytes, such as 102400
for (i = 0; i < byteUnits.length; i++) {
if (strSizeUnit === byteUnits[i]) {
tmpVal = parseFloat(strSize);
valSize = tmpVal * Math.pow(1024, i);
break;
}
}
for (i = 0; i < byteUnits.length; i++) {
if (strOverheadUnit === byteUnits[i]) {
tmpVal = parseFloat(strOverhead);
valOverhead = tmpVal * Math.pow(1024, i);
break;
}
}
sizeSum += valSize;
overheadSum += valOverhead;
});
// Add some commas for readability:
// 1000000 becomes 1,000,000
var strRowSum = rowsSum + '';
var regex = /(\d+)(\d{3})/;
while (regex.test(strRowSum)) {
strRowSum = strRowSum.replace(regex, '$1' + ',' + '$2');
}
// If approximated total value add ~ in front
if (rowSumApproximated) {
strRowSum = '~' + strRowSum;
}
// Calculate the magnitude for the size and overhead values
var sizeMagnitude = 0;
var overheadMagnitude = 0;
while (sizeSum >= 1024) {
sizeSum /= 1024;
sizeMagnitude++;
}
while (overheadSum >= 1024) {
overheadSum /= 1024;
overheadMagnitude++;
}
sizeSum = Math.round(sizeSum * 10) / 10;
overheadSum = Math.round(overheadSum * 10) / 10;
// Update summary with new data
var $summary = $('#tbl_summary_row');
$summary.find('.tbl_num').text(Functions.sprintf(Messages.strNTables, tableSum));
if (rowSumApproximated) {
$summary.find('.row_count_sum').text(strRowSum);
} else {
$summary.find('.tbl_rows').text(strRowSum);
}
$summary.find('.tbl_size').text(sizeSum + ' ' + byteUnits[sizeMagnitude]);
$summary.find('.tbl_overhead').text(overheadSum + ' ' + byteUnits[overheadMagnitude]);
};
/**
* Gets the real row count for a table or DB.
* @param {object} $target Target for appending the real count value.
*/
DatabaseStructure.fetchRealRowCount = function ($target) {
var $throbber = $('#pma_navigation').find('.throbber')
.first()
.clone()
.css({ visibility: 'visible', display: 'inline-block' })
.on('click', false);
$target.html($throbber);
$.ajax({
type: 'GET',
url: $target.attr('href'),
cache: false,
dataType: 'json',
success: function (response) {
if (response.success) {
// If to update all row counts for a DB.
if (response.real_row_count_all) {
$.each(JSON.parse(response.real_row_count_all),
function (index, table) {
// Update each table row count.
$('table.data td[data-table*="' + table.table + '"]')
.text(table.row_count);
}
);
}
// If to update a particular table's row count.
if (response.real_row_count) {
// Append the parent cell with real row count.
$target.parent().text(response.real_row_count);
}
// Adjust the 'Sum' displayed at the bottom.
DatabaseStructure.adjustTotals();
} else {
Functions.ajaxShowMessage(Messages.strErrorRealRowCount);
}
},
error: function () {
Functions.ajaxShowMessage(Messages.strErrorRealRowCount);
}
});
};
AJAX.registerOnload('database/structure.js', function () {
/**
* Event handler on select of "Make consistent with central list"
*/
$('select[name=submit_mult]').on('change', function (event) {
var url = 'index.php?route=/database/structure';
var action = $(this).val();
if (action === 'make_consistent_with_central_list') {
event.preventDefault();
event.stopPropagation();
$('#makeConsistentWithCentralListModal').modal('show').on('shown.bs.modal', function () {
$('#makeConsistentWithCentralListContinue').on('click', function () {
const $form = $('#tablesForm');
const argSep = CommonParams.get('arg_separator');
const data = $form.serialize() + argSep + 'ajax_request=true' + argSep + 'ajax_page_request=true';
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post(
'index.php?route=/database/structure/central-columns/make-consistent',
data,
AJAX.responseHandler
);
$('#makeConsistentWithCentralListModal').modal('hide');
});
});
return;
}
if (action === 'copy_tbl' ||
action === 'add_prefix_tbl' ||
action === 'replace_prefix_tbl' ||
action === 'copy_tbl_change_prefix'
) {
event.preventDefault();
event.stopPropagation();
if ($('input[name="selected_tbl[]"]:checked').length === 0) {
return false;
}
var formData = $('#tablesForm').serialize();
var modalTitle = '';
if (action === 'copy_tbl') {
url = 'index.php?route=/database/structure/copy-form';
modalTitle = Messages.strCopyTablesTo;
} else if (action === 'add_prefix_tbl') {
url = 'index.php?route=/database/structure/add-prefix';
modalTitle = Messages.strAddPrefix;
} else if (action === 'replace_prefix_tbl') {
url = 'index.php?route=/database/structure/change-prefix-form';
modalTitle = Messages.strReplacePrefix;
} else if (action === 'copy_tbl_change_prefix') {
url = 'index.php?route=/database/structure/change-prefix-form';
modalTitle = Messages.strCopyPrefix;
}
$.ajax({
type: 'POST',
url: url,
dataType: 'html',
data: formData
}).done(function (modalBody) {
const bulkActionModal = $('#bulkActionModal');
bulkActionModal.on('show.bs.modal', function () {
this.querySelector('.modal-title').innerText = modalTitle;
this.querySelector('.modal-body').innerHTML = modalBody;
});
bulkActionModal.modal('show').on('shown.bs.modal', function () {
$('#bulkActionContinue').on('click', function () {
$('#ajax_form').trigger('submit');
$('#bulkActionModal').modal('hide');
});
});
});
return;
}
if (action === 'analyze_tbl') {
url = 'index.php?route=/table/maintenance/analyze';
} else if (action === 'sync_unique_columns_central_list') {
url = 'index.php?route=/database/structure/central-columns/add';
} else if (action === 'delete_unique_columns_central_list') {
url = 'index.php?route=/database/structure/central-columns/remove';
} else if (action === 'check_tbl') {
url = 'index.php?route=/table/maintenance/check';
} else if (action === 'checksum_tbl') {
url = 'index.php?route=/table/maintenance/checksum';
} else if (action === 'drop_tbl') {
url = 'index.php?route=/database/structure/drop-form';
} else if (action === 'empty_tbl') {
url = 'index.php?route=/database/structure/empty-form';
} else if (action === 'export') {
url = 'index.php?route=/export/tables';
} else if (action === 'optimize_tbl') {
url = 'index.php?route=/table/maintenance/optimize';
} else if (action === 'repair_tbl') {
url = 'index.php?route=/table/maintenance/repair';
} else if (action === 'show_create') {
url = 'index.php?route=/database/structure/show-create';
} else {
$('#tablesForm').trigger('submit');
return;
}
var $form = $(this).parents('form');
var argsep = CommonParams.get('arg_separator');
var data = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true';
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post(url, data, AJAX.responseHandler);
});
/**
* Ajax Event handler for 'Truncate Table'
*/
$(document).on('click', 'a.truncate_table_anchor.ajax', function (event) {
event.preventDefault();
/**
* @var $this_anchor Object referring to the anchor clicked
*/
var $thisAnchor = $(this);
// extract current table name and build the question string
/**
* @var curr_table_name String containing the name of the table to be truncated
*/
var currTableName = $thisAnchor.parents('tr').children('th').children('a').text();
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strTruncateTableStrongWarning + ' ' +
Functions.sprintf(Messages.strDoYouReally, 'TRUNCATE `' + Functions.escapeHtml(currTableName) + '`') +
Functions.getForeignKeyCheckboxLoader();
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
// Adjust table statistics
var $tr = $thisAnchor.closest('tr');
$tr.find('.tbl_rows').text('0');
$tr.find('.tbl_size, .tbl_overhead').text('-');
DatabaseStructure.adjustTotals();
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, Functions.loadForeignKeyCheckbox);
}); // end of Truncate Table Ajax action
/**
* Ajax Event handler for 'Drop Table' or 'Drop View'
*/
$(document).on('click', 'a.drop_table_anchor.ajax', function (event) {
event.preventDefault();
var $thisAnchor = $(this);
// extract current table name and build the question string
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $thisAnchor.parents('tr');
/**
* @var curr_table_name String containing the name of the table to be truncated
*/
var currTableName = $currRow.children('th').children('a').text();
/**
* @var is_view Boolean telling if we have a view
*/
var isView = $currRow.hasClass('is_view') || $thisAnchor.hasClass('view');
/**
* @var question String containing the question to be asked for confirmation
*/
var question;
if (! isView) {
question = Messages.strDropTableStrongWarning + ' ' +
Functions.sprintf(Messages.strDoYouReally, 'DROP TABLE `' + Functions.escapeHtml(currTableName) + '`');
} else {
question =
Functions.sprintf(Messages.strDoYouReally, 'DROP VIEW `' + Functions.escapeHtml(currTableName) + '`');
}
question += Functions.getForeignKeyCheckboxLoader();
$thisAnchor.confirm(question, $thisAnchor.attr('href'), function (url) {
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $thisAnchor.getPostData());
$.post(url, params, function (data) {
if (typeof data !== 'undefined' && data.success === true) {
Functions.ajaxShowMessage(data.message);
$currRow.hide('medium').remove();
DatabaseStructure.adjustTotals();
Navigation.reload();
Functions.ajaxRemoveMessage($msg);
} else {
Functions.ajaxShowMessage(Messages.strErrorProcessingRequest + ' : ' + data.error, false);
}
}); // end $.post()
}, Functions.loadForeignKeyCheckbox);
}); // end of Drop Table Ajax action
// Calculate Real End for InnoDB
/**
* Ajax Event handler for calculating the real end for a InnoDB table
*
*/
$(document).on('click', '#real_end_input', function (event) {
event.preventDefault();
/**
* @var question String containing the question to be asked for confirmation
*/
var question = Messages.strOperationTakesLongTime;
$(this).confirm(question, '', function () {
return true;
});
return false;
}); // end Calculate Real End for InnoDB
// Add tooltip to favorite icons.
$('.favorite_table_anchor').each(function () {
Functions.tooltip(
$(this),
'a',
$(this).attr('title')
);
});
// Get real row count via Ajax.
$('a.real_row_count').on('click', function (event) {
event.preventDefault();
DatabaseStructure.fetchRealRowCount($(this));
});
// Get all real row count.
$('a.row_count_sum').on('click', function (event) {
event.preventDefault();
DatabaseStructure.fetchRealRowCount($(this));
});
});

View file

@ -1,93 +0,0 @@
/**
* Unbind all event handlers before tearing down the page
*/
AJAX.registerTeardown('database/tracking.js', function () {
$('body').off('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]');
$('body').off('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]');
$('body').off('click', 'a.delete_tracking_anchor.ajax');
});
/**
* Bind event handlers
*/
AJAX.registerOnload('database/tracking.js', function () {
var $versions = $('#versions');
$versions.find('tr').first().find('th').append($('<div class="sorticon"></div>'));
$versions.tablesorter({
sortList: [[1, 0]],
headers: {
0: { sorter: false },
2: { sorter: 'integer' },
5: { sorter: false },
6: { sorter: false },
7: { sorter: false }
}
});
var $noVersions = $('#noversions');
$noVersions.find('tr').first().find('th').append($('<div class="sorticon"></div>'));
$noVersions.tablesorter({
sortList: [[1, 0]],
headers: {
0: { sorter: false },
2: { sorter: false }
}
});
var $body = $('body');
/**
* Handles multi submit for tracked tables
*/
$body.on('click', '#trackedForm.ajax button[name="submit_mult"], #trackedForm.ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
if ($button.val() === 'delete_tracking') {
var question = Messages.strDeleteTrackingDataMultiple;
$button.confirm(question, $form.attr('action'), function (url) {
Functions.ajaxShowMessage(Messages.strDeletingTrackingData);
AJAX.source = $form;
$.post(url, submitData, AJAX.responseHandler);
});
} else {
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
}
});
/**
* Handles multi submit for untracked tables
*/
$body.on('click', '#untrackedForm.ajax button[name="submit_mult"], #untrackedForm.ajax input[name="submit_mult"]', function (e) {
e.preventDefault();
var $button = $(this);
var $form = $button.parent('form');
var argsep = CommonParams.get('arg_separator');
var submitData = $form.serialize() + argsep + 'ajax_request=true' + argsep + 'ajax_page_request=true' + argsep + 'submit_mult=' + $button.val();
Functions.ajaxShowMessage();
AJAX.source = $form;
$.post($form.attr('action'), submitData, AJAX.responseHandler);
});
/**
* Ajax Event handler for 'Delete tracking'
*/
$body.on('click', 'a.delete_tracking_anchor.ajax', function (e) {
e.preventDefault();
var $anchor = $(this);
var question = Messages.strDeleteTrackingData;
$anchor.confirm(question, $anchor.attr('href'), function (url) {
Functions.ajaxShowMessage(Messages.strDeletingTrackingData);
AJAX.source = $anchor;
var argSep = CommonParams.get('arg_separator');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
params += argSep + 'ajax_page_request=1';
$.post(url, params, AJAX.responseHandler);
});
});
});

View file

@ -1,546 +0,0 @@
AJAX.registerTeardown('database/triggers.js', function () {
$(document).off('click', 'a.ajax.add_anchor, a.ajax.edit_anchor');
$(document).off('click', 'a.ajax.export_anchor');
$(document).off('click', '#bulkActionExportButton');
$(document).off('click', 'a.ajax.drop_anchor');
$(document).off('click', '#bulkActionDropButton');
});
const DatabaseTriggers = {
/**
* @var $ajaxDialog Query object containing the reference to the
* dialog that contains the editor
*/
$ajaxDialog: null,
/**
* @var syntaxHiglighter Reference to the codemirror editor
*/
syntaxHiglighter: null,
/**
* Validate editor form fields.
*
* @return {bool}
*/
validate: function () {
/**
* @var $elm a jQuery object containing the reference
* to an element that is being validated
*/
var $elm = null;
// Common validation. At the very least the name
// and the definition must be provided for an item
$elm = $('table.rte_table').last().find('input[name=item_name]');
if ($elm.val() === '') {
$elm.trigger('focus');
alert(Messages.strFormEmpty);
return false;
}
$elm = $('table.rte_table').find('textarea[name=item_definition]');
if ($elm.val() === '') {
if (this.syntaxHiglighter !== null) {
this.syntaxHiglighter.focus();
} else {
$('textarea[name=item_definition]').last().trigger('focus');
}
alert(Messages.strFormEmpty);
return false;
}
// The validation has so far passed, so now
// we can validate item-specific fields.
return this.validateCustom();
}, // end validate()
/**
* Validate custom editor form fields.
* This function can be overridden by
* other files in this folder
*
* @return {bool}
*/
validateCustom: function () {
return true;
}, // end validateCustom()
exportDialog: function ($this) {
var $msg = Functions.ajaxShowMessage();
if ($this.attr('id') === 'bulkActionExportButton') {
var combined = {
success: true,
title: Messages.strExport,
message: '',
error: ''
};
// export anchors of all selected rows
var exportAnchors = $('input.checkall:checked').parents('tr').find('.export_anchor');
var count = exportAnchors.length;
var returnCount = 0;
var p = $.when();
exportAnchors.each(function () {
var h = $(this).attr('href');
p = p.then(function () {
return $.get(h, { 'ajax_request': true }, function (data) {
returnCount++;
if (data.success === true) {
combined.message += '\n' + data.message + '\n';
if (returnCount === count) {
showExport(combined);
}
} else {
// complain even if one export is failing
combined.success = false;
combined.error += '\n' + data.error + '\n';
if (returnCount === count) {
showExport(combined);
}
}
});
});
});
} else {
$.get($this.attr('href'), { 'ajax_request': true }, showExport);
}
Functions.ajaxRemoveMessage($msg);
function showExport (data) {
if (data.success === true) {
Functions.ajaxRemoveMessage($msg);
/**
* @var buttonOptions Object containing options
* for jQueryUI dialog buttons
*/
var buttonOptions = {
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-primary',
},
};
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close').remove();
};
/**
* Display the dialog to the user
*/
data.message = '<textarea cols="40" rows="15" class="w-100">' + data.message + '</textarea>';
var $ajaxDialog = $('<div>' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 500,
buttons: buttonOptions,
title: data.title
});
// Attach syntax highlighted editor to export dialog
/**
* @var $elm jQuery object containing the reference
* to the Export textarea.
*/
var $elm = $ajaxDialog.find('textarea');
Functions.getSqlEditor($elm);
} else {
Functions.ajaxShowMessage(data.error, false);
}
} // end showExport()
}, // end exportDialog()
editorDialog: function (isNew, $this) {
var that = this;
/**
* @var $edit_row jQuery object containing the reference to
* the row of the the item being edited
* from the list of items
*/
var $editRow = null;
if ($this.hasClass('edit_anchor')) {
// Remember the row of the item being edited for later,
// so that if the edit is successful, we can replace the
// row with info about the modified item.
$editRow = $this.parents('tr');
}
/**
* @var $msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage();
$.get($this.attr('href'), { 'ajax_request': true }, function (data) {
if (data.success === true) {
var buttonOptions = {
[Messages.strGo]: {
text: Messages.strGo,
class: 'btn btn-primary',
},
[Messages.strClose]: {
text: Messages.strClose,
class: 'btn btn-secondary',
},
};
// We have successfully fetched the editor form
Functions.ajaxRemoveMessage($msg);
// Now define the function that is called when
// the user presses the "Go" button
buttonOptions[Messages.strGo].click = function () {
// Move the data from the codemirror editor back to the
// textarea, where it can be used in the form submission.
if (typeof CodeMirror !== 'undefined') {
that.syntaxHiglighter.save();
}
// Validate editor and submit request, if passed.
if (that.validate()) {
/**
* @var data Form data to be sent in the AJAX request
*/
var data = $('form.rte_form').last().serialize();
$msg = Functions.ajaxShowMessage(
Messages.strProcessingRequest
);
var url = $('form.rte_form').last().attr('action');
$.post(url, data, function (data) {
if (data.success === true) {
// Item created successfully
Functions.ajaxRemoveMessage($msg);
Functions.slidingMessage(data.message);
that.$ajaxDialog.dialog('close');
// If we are in 'edit' mode, we must
// remove the reference to the old row.
if (mode === 'edit' && $editRow !== null) {
$editRow.remove();
}
// Sometimes, like when moving a trigger from
// a table to another one, the new row should
// not be inserted into the list. In this case
// "data.insert" will be set to false.
if (data.insert) {
// Insert the new row at the correct
// location in the list of items
/**
* @var text Contains the name of an item from
* the list that is used in comparisons
* to find the correct location where
* to insert a new row.
*/
var text = '';
/**
* @var inserted Whether a new item has been
* inserted in the list or not
*/
var inserted = false;
$('table.data').find('tr').each(function () {
text = $(this)
.children('td')
.eq(0)
.find('strong')
.text()
.toUpperCase()
.trim();
if (text !== '' && text > data.name) {
$(this).before(data.new_row);
inserted = true;
return false;
}
});
if (! inserted) {
// If we didn't manage to insert the row yet,
// it must belong at the end of the list,
// so we insert it there.
$('table.data').append(data.new_row);
}
// Fade-in the new row
$('tr.ajaxInsert')
.show('slow')
.removeClass('ajaxInsert');
} else if ($('table.data').find('tr').has('td').length === 0) {
// If we are not supposed to insert the new row,
// we will now check if the table is empty and
// needs to be hidden. This will be the case if
// we were editing the only item in the list,
// which we removed and will not be inserting
// something else in its place.
$('table.data').hide('slow', function () {
$('#nothing2display').show('slow');
});
}
// Now we have inserted the row at the correct
// position, but surely at least some row classes
// are wrong now. So we will iterate through
// all rows and assign correct classes to them
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$('table.data').find('tr').has('td').each(function () {
rowclass = (ct % 2 === 0) ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
// If this is the first item being added, remove
// the "No items" message and show the list.
if ($('table.data').find('tr').has('td').length > 0 &&
$('#nothing2display').is(':visible')
) {
$('#nothing2display').hide('slow', function () {
$('table.data').show('slow');
});
}
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
} // end "if (that.validate())"
}; // end of function that handles the submission of the Editor
buttonOptions[Messages.strClose].click = function () {
$(this).dialog('close');
};
/**
* Display the dialog to the user
*/
that.$ajaxDialog = $('<div id="rteDialog">' + data.message + '</div>').dialog({
classes: {
'ui-dialog-titlebar-close': 'btn-close'
},
width: 700,
minWidth: 500,
buttons: buttonOptions,
// Issue #15810 - use button titles for modals (eg: new procedure)
// Respect the order: title on href tag, href content, title sent in response
title: $this.attr('title') || $this.text() || $(data.title).text(),
modal: true,
open: function () {
$('#rteDialog').dialog('option', 'max-height', $(window).height());
if ($('#rteDialog').parents('.ui-dialog').height() > $(window).height()) {
$('#rteDialog').dialog('option', 'height', $(window).height());
}
$(this).find('input[name=item_name]').trigger('focus');
$(this).find('input.datefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'date');
});
$(this).find('input.datetimefield').each(function () {
Functions.addDatepicker($(this).css('width', '95%'), 'datetime');
});
$.datepicker.initialized = false;
},
close: function () {
$(this).remove();
}
});
/**
* @var mode Used to remember whether the editor is in
* "Edit" or "Add" mode
*/
var mode = 'add';
if ($('input[name=editor_process_edit]').length > 0) {
mode = 'edit';
}
// Attach syntax highlighted editor to the definition
/**
* @var elm jQuery object containing the reference to
* the Definition textarea.
*/
var $elm = $('textarea[name=item_definition]').last();
var linterOptions = {};
linterOptions.triggerEditor = true;
that.syntaxHiglighter = Functions.getSqlEditor($elm, {}, 'both', linterOptions);
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.get()
},
dropDialog: function ($this) {
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $this.parents('tr');
/**
* @var question String containing the question to be asked for confirmation
*/
var question = $('<div></div>').text(
$currRow.children('td').children('.drop_sql').html()
);
// We ask for confirmation first here, before submitting the ajax request
$this.confirm(question, $this.attr('href'), function (url) {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
var params = Functions.getJsConfirmCommonParam(this, $this.getPostData());
$.post(url, params, function (data) {
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('slow', function () {
$(this).remove();
// Now we have removed the row from the list, but maybe
// some row classes are wrong now. So we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = (ct % 2 === 1) ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
});
}
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
// Show the query that we just executed
Functions.slidingMessage(data.sql_query);
Navigation.reload();
} else {
Functions.ajaxShowMessage(data.error, false);
}
}); // end $.post()
});
},
dropMultipleDialog: function ($this) {
// We ask for confirmation here
$this.confirm(Messages.strDropRTEitems, '', function () {
/**
* @var msg jQuery object containing the reference to
* the AJAX message shown to the user
*/
var $msg = Functions.ajaxShowMessage(Messages.strProcessingRequest);
// drop anchors of all selected rows
var dropAnchors = $('input.checkall:checked').parents('tr').find('.drop_anchor');
var success = true;
var count = dropAnchors.length;
var returnCount = 0;
dropAnchors.each(function () {
var $anchor = $(this);
/**
* @var $curr_row Object containing reference to the current row
*/
var $currRow = $anchor.parents('tr');
var params = Functions.getJsConfirmCommonParam(this, $anchor.getPostData());
$.post($anchor.attr('href'), params, function (data) {
returnCount++;
if (data.success === true) {
/**
* @var $table Object containing reference
* to the main list of elements
*/
var $table = $currRow.parent();
// Check how many rows will be left after we remove
// the one that the user has requested us to remove
if ($table.find('tr').length === 3) {
// If there are two rows left, it means that they are
// the header of the table and the rows that we are
// about to remove, so after the removal there will be
// nothing to show in the table, so we hide it.
$table.hide('slow', function () {
$(this).find('tr.even, tr.odd').remove();
$('.withSelected').remove();
$('#nothing2display').show('slow');
});
} else {
$currRow.hide('fast', function () {
// we will iterate
// through all rows and assign correct classes to them.
/**
* @var ct Count of processed rows
*/
var ct = 0;
/**
* @var rowclass Class to be attached to the row
* that is being processed
*/
var rowclass = '';
$table.find('tr').has('td').each(function () {
rowclass = (ct % 2 === 1) ? 'odd' : 'even';
$(this).removeClass().addClass(rowclass);
ct++;
});
});
$currRow.remove();
}
if (returnCount === count) {
if (success) {
// Get rid of the "Loading" message
Functions.ajaxRemoveMessage($msg);
$('#rteListForm_checkall').prop({ checked: false, indeterminate: false });
}
Navigation.reload();
}
} else {
Functions.ajaxShowMessage(data.error, false);
success = false;
if (returnCount === count) {
Navigation.reload();
}
}
}); // end $.post()
}); // end drop_anchors.each()
});
}
};
AJAX.registerOnload('database/triggers.js', function () {
/**
* Attach Ajax event handlers for the Add/Edit functionality.
*/
$(document).on('click', 'a.ajax.add_anchor, a.ajax.edit_anchor', function (event) {
event.preventDefault();
if ($(this).hasClass('add_anchor')) {
$.datepicker.initialized = false;
}
DatabaseTriggers.editorDialog($(this).hasClass('add_anchor'), $(this));
});
/**
* Attach Ajax event handlers for Export
*/
$(document).on('click', 'a.ajax.export_anchor', function (event) {
event.preventDefault();
DatabaseTriggers.exportDialog($(this));
});
$(document).on('click', '#bulkActionExportButton', function (event) {
event.preventDefault();
DatabaseTriggers.exportDialog($(this));
});
/**
* Attach Ajax event handlers for Drop functionality
*/
$(document).on('click', 'a.ajax.drop_anchor', function (event) {
event.preventDefault();
DatabaseTriggers.dropDialog($(this));
});
$(document).on('click', '#bulkActionDropButton', function (event) {
event.preventDefault();
DatabaseTriggers.dropMultipleDialog($(this));
});
});

View file

@ -1,234 +0,0 @@
var designerTables = [
{
name: 'pdf_pages',
key: 'pgNr',
autoIncrement: true
},
{
name: 'table_coords',
key: 'id',
autoIncrement: true
}
];
// eslint-disable-next-line no-unused-vars
var DesignerOfflineDB = (function () {
var designerDB = {};
/**
* @type {IDBDatabase|null}
*/
var datastore = null;
/**
* @param {String} table
* @return {IDBTransaction}
*/
designerDB.getTransaction = function (table) {
return datastore.transaction([table], 'readwrite');
};
/**
* @param {String} table
* @return {IDBObjectStore}
*/
designerDB.getObjectStore = function (table) {
var transaction = designerDB.getTransaction(table);
var objStore = transaction.objectStore(table);
return objStore;
};
/**
* @param {IDBTransaction} transaction
* @param {String} table
* @return {IDBObjectStore}
*/
designerDB.getCursorRequest = function (transaction, table) {
var objStore = transaction.objectStore(table);
var keyRange = IDBKeyRange.lowerBound(0);
var cursorRequest = objStore.openCursor(keyRange);
return cursorRequest;
};
/**
* @param {Function} callback
* @return {void}
*/
designerDB.open = function (callback) {
var version = 1;
var request = window.indexedDB.open('pma_designer', version);
request.onupgradeneeded = function (e) {
var db = e.target.result;
e.target.transaction.onerror = designerDB.onerror;
var t;
for (t in designerTables) {
if (db.objectStoreNames.contains(designerTables[t].name)) {
db.deleteObjectStore(designerTables[t].name);
}
}
for (t in designerTables) {
db.createObjectStore(designerTables[t].name, {
keyPath: designerTables[t].key,
autoIncrement: designerTables[t].autoIncrement
});
}
};
request.onsuccess = function (e) {
datastore = e.target.result;
if (typeof callback === 'function') {
callback(true);
}
};
request.onerror = function () {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
};
};
/**
* @param {String} table
* @param {String} id
* @param {Function} callback
* @return {void}
*/
designerDB.loadObject = function (table, id, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var objStore = designerDB.getObjectStore(table);
var cursorRequest = objStore.get(parseInt(id));
cursorRequest.onsuccess = function (e) {
callback(e.target.result);
};
cursorRequest.onerror = designerDB.onerror;
};
/**
* @param {String} table
* @param {Function} callback
* @return {void}
*/
designerDB.loadAllObjects = function (table, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var transaction = designerDB.getTransaction(table);
var cursorRequest = designerDB.getCursorRequest(transaction, table);
var results = [];
transaction.oncomplete = function () {
callback(results);
};
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
if (Boolean(result) === false) {
return;
}
results.push(result.value);
result.continue();
};
cursorRequest.onerror = designerDB.onerror;
};
/**
* @param {String} table
* @param {Function} callback
* @return {void}
*/
designerDB.loadFirstObject = function (table, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var transaction = designerDB.getTransaction(table);
var cursorRequest = designerDB.getCursorRequest(transaction, table);
var firstResult = null;
transaction.oncomplete = function () {
callback(firstResult);
};
cursorRequest.onsuccess = function (e) {
var result = e.target.result;
if (Boolean(result) === false) {
return;
}
firstResult = result.value;
};
cursorRequest.onerror = designerDB.onerror;
};
/**
* @param {String} table
* @param {Object} obj
* @param {Function} callback
* @return {void}
*/
designerDB.addObject = function (table, obj, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var objStore = designerDB.getObjectStore(table);
var request = objStore.put(obj);
request.onsuccess = function (e) {
if (typeof callback === 'function') {
callback(e.currentTarget.result);
}
};
request.onerror = designerDB.onerror;
};
/**
* @param {String} table
* @param {String} id
* @param {Function} callback
* @return {void}
*/
designerDB.deleteObject = function (table, id, callback) {
if (datastore === null) {
Functions.ajaxShowMessage(Messages.strIndexedDBNotWorking, null, 'error');
return;
}
var objStore = designerDB.getObjectStore(table);
var request = objStore.delete(parseInt(id));
request.onsuccess = function () {
if (typeof callback === 'function') {
callback(true);
}
};
request.onerror = designerDB.onerror;
};
/**
* @param {Error} e
* @return {void}
*/
designerDB.onerror = function (e) {
// eslint-disable-next-line no-console
console.log(e);
};
// Export the designerDB object.
return designerDB;
}());

View file

@ -1,833 +0,0 @@
/**
* @fileoverview function used in this file builds history tab and generates query.
*
* @requires jQuery
* @requires move.js
*/
/* global contr */ // js/designer/init.js
/* global fromArray:writable */ // js/designer/move.js
/* global themeImagePath */ // templates/javascript/variables.twig
var DesignerHistory = {};
var historyArray = []; // Global array to store history objects
var selectField = []; // Global array to store information for columns which are used in select clause
var gIndex;
var vqbEditor = null;
/**
* To display details of objects(where,rename,Having,aggregate,groupby,orderby,having)
*
* @param {number} index index of historyArray where change is to be made
* @return {string}
*/
DesignerHistory.detail = function (index) {
var type = historyArray[index].getType();
var str;
if (type === 'Where') {
str = 'Where ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
} else if (type === 'Rename') {
str = 'Rename ' + historyArray[index].getColumnName() + ' To ' + historyArray[index].getObj().getRenameTo();
} else if (type === 'Aggregate') {
str = 'Select ' + historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )';
} else if (type === 'GroupBy') {
str = 'GroupBy ' + historyArray[index].getColumnName();
} else if (type === 'OrderBy') {
str = 'OrderBy ' + historyArray[index].getColumnName() + ' ' + historyArray[index].getObj().getOrder();
} else if (type === 'Having') {
str = 'Having ';
if (historyArray[index].getObj().getOperator() !== 'None') {
str += historyArray[index].getObj().getOperator() + '( ' + historyArray[index].getColumnName() + ' )';
str += historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
} else {
str = 'Having ' + historyArray[index].getColumnName() + historyArray[index].getObj().getRelationOperator() + historyArray[index].getObj().getQuery();
}
}
return str;
};
/**
* Sorts historyArray[] first,using table name as the key and then generates the HTML code for history tab,
* clubbing all objects of same tables together
* This function is called whenever changes are made in historyArray[]
*
*
* @param {number} init starting index of unsorted array
* @param {number} finit last index of unsorted array
* @return {string}
*/
DesignerHistory.display = function (init, finit) {
var str;
var i;
var j;
var k;
var sto;
var temp;
// this part sorts the history array based on table name,this is needed for clubbing all object of same name together.
for (i = init; i < finit; i++) {
sto = historyArray[i];
temp = historyArray[i].getTab();// + '.' + historyArray[i].getObjNo(); for Self JOINS
for (j = 0; j < i; j++) {
if (temp > (historyArray[j].getTab())) {// + '.' + historyArray[j].getObjNo())) { //for Self JOINS
for (k = i; k > j; k--) {
historyArray[k] = historyArray[k - 1];
}
historyArray[j] = sto;
break;
}
}
}
// this part generates HTML code for history tab.adds delete,edit,and/or and detail features with objects.
str = ''; // string to store Html code for history tab
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
temp = historyArray[i].getTab(); // + '.' + historyArray[i].getObjNo(); for Self JOIN
str += '<h3 class="tiger"><a href="#">' + temp + '</a></h3>';
str += '<div class="toggle_container">\n';
while ((historyArray[i].getTab()) === temp) { // + '.' + historyArray[i].getObjNo()) === temp) {
str += '<div class="block"> <table class="table table-sm w-auto mb-0">';
str += '<thead><tr><td>';
if (historyArray[i].getAndOr()) {
str += '<img src="' + themeImagePath + 'designer/or_icon.png" onclick="DesignerHistory.andOr(' + i + ')" title="OR"></td>';
} else {
str += '<img src="' + themeImagePath + 'designer/and_icon.png" onclick="DesignerHistory.andOr(' + i + ')" title="AND"></td>';
}
str += '<td style="padding-left: 5px;" class="text-end">' + Functions.getImage('b_sbrowse', Messages.strColumnName) + '</td>' +
'<td width="175" style="padding-left: 5px">' + $('<div/>').text(historyArray[i].getColumnName()).html() + '<td>';
if (historyArray[i].getType() === 'GroupBy' || historyArray[i].getType() === 'OrderBy') {
var detailDescGroupBy = $('<div/>').text(DesignerHistory.detail(i)).html();
str += '<td class="text-center">' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '</td>' +
'<td title="' + detailDescGroupBy + '">' + historyArray[i].getType() + '</td>' +
'<td onclick=DesignerHistory.historyDelete(' + i + ')>' + Functions.getImage('b_drop', Messages.strDelete) + '</td>';
} else {
var detailDesc = $('<div/>').text(DesignerHistory.detail(i)).html();
str += '<td class="text-center">' + Functions.getImage('s_info', DesignerHistory.detail(i)) + '</td>' +
'<td title="' + detailDesc + '">' + historyArray[i].getType() + '</td>' +
'<td onclick=DesignerHistory.historyEdit(' + i + ')>' + Functions.getImage('b_edit', Messages.strEdit) + '</td>' +
'<td onclick=DesignerHistory.historyDelete(' + i + ')>' + Functions.getImage('b_drop', Messages.strDelete) + '</td>';
}
str += '</tr></thead>';
i++;
if (i >= historyArrayLength) {
break;
}
str += '</table></div>';
}
i--;
str += '</div>';
}
return str;
};
/**
* To change And/Or relation in history tab
*
*
* @param {number} index index of historyArray where change is to be made
* @return {void}
*/
DesignerHistory.andOr = function (index) {
if (historyArray[index].getAndOr()) {
historyArray[index].setAndOr(0);
} else {
historyArray[index].setAndOr(1);
}
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* Deletes entry in historyArray
*
* @param {number} index of historyArray[] which is to be deleted
* @return {void}
*/
DesignerHistory.historyDelete = function (index) {
var fromArrayLength = fromArray.length;
for (var k = 0; k < fromArrayLength; k++) {
if (fromArray[k] === historyArray[index].getTab()) {
fromArray.splice(k, 1);
break;
}
}
historyArray.splice(index, 1);
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* @param {string} elementId
* @return {void}
*/
DesignerHistory.changeStyle = function (elementId) {
var element = document.getElementById(elementId);
element.style.left = '530px';
element.style.top = '130px';
element.style.position = 'absolute';
element.style.zIndex = '103';
element.style.visibility = 'visible';
element.style.display = 'block';
};
/**
* To show where,rename,aggregate,having forms to edit a object
*
* @param {number} index index of historyArray where change is to be made
* @return {void}
*/
DesignerHistory.historyEdit = function (index) {
gIndex = index;
var type = historyArray[index].getType();
if (type === 'Where') {
document.getElementById('eQuery').value = historyArray[index].getObj().getQuery();
document.getElementById('erel_opt').value = historyArray[index].getObj().getRelationOperator();
DesignerHistory.changeStyle('query_where');
} else if (type === 'Having') {
document.getElementById('hQuery').value = historyArray[index].getObj().getQuery();
document.getElementById('hrel_opt').value = historyArray[index].getObj().getRelationOperator();
document.getElementById('hoperator').value = historyArray[index].getObj().getOperator();
DesignerHistory.changeStyle('query_having');
} else if (type === 'Rename') {
document.getElementById('e_rename').value = historyArray[index].getObj().getRenameTo();
DesignerHistory.changeStyle('query_rename_to');
} else if (type === 'Aggregate') {
document.getElementById('e_operator').value = historyArray[index].getObj().getOperator();
DesignerHistory.changeStyle('query_Aggregate');
}
};
/**
* Make changes in historyArray when Edit button is clicked
* checks for the type of object and then sets the new value
*
* @param {string} type of historyArray where change is to be made
* @return {void}
*/
DesignerHistory.edit = function (type) {
if (type === 'Rename') {
if (document.getElementById('e_rename').value !== '') {
historyArray[gIndex].getObj().setRenameTo(document.getElementById('e_rename').value);
document.getElementById('e_rename').value = '';
}
document.getElementById('query_rename_to').style.visibility = 'hidden';
} else if (type === 'Aggregate') {
if (document.getElementById('e_operator').value !== '---') {
historyArray[gIndex].getObj().setOperator(document.getElementById('e_operator').value);
document.getElementById('e_operator').value = '---';
}
document.getElementById('query_Aggregate').style.visibility = 'hidden';
} else if (type === 'Where') {
if (document.getElementById('erel_opt').value !== '--' && document.getElementById('eQuery').value !== '') {
historyArray[gIndex].getObj().setQuery(document.getElementById('eQuery').value);
historyArray[gIndex].getObj().setRelationOperator(document.getElementById('erel_opt').value);
}
document.getElementById('query_where').style.visibility = 'hidden';
} else if (type === 'Having') {
if (document.getElementById('hrel_opt').value !== '--' && document.getElementById('hQuery').value !== '') {
historyArray[gIndex].getObj().setQuery(document.getElementById('hQuery').value);
historyArray[gIndex].getObj().setRelationOperator(document.getElementById('hrel_opt').value);
historyArray[gIndex].getObj().setOperator(document.getElementById('hoperator').value);
}
document.getElementById('query_having').style.visibility = 'hidden';
}
var existingDiv = document.getElementById('ab');
existingDiv.innerHTML = DesignerHistory.display(0, 0);
$('#ab').accordion('refresh');
};
/**
* history object closure
*
* @param nColumnName name of the column on which conditions are put
* @param nObj object details(where,rename,orderby,groupby,aggregate)
* @param nTab table name of the column on which conditions are applied
* @param nObjNo object no used for inner join
* @param nType type of object
*
*/
DesignerHistory.HistoryObj = function (nColumnName, nObj, nTab, nObjNo, nType) {
var andOr;
var obj;
var tab;
var columnName;
var objNo;
var type;
this.setColumnName = function (nColumnName) {
columnName = nColumnName;
};
this.getColumnName = function () {
return columnName;
};
this.setAndOr = function (nAndOr) {
andOr = nAndOr;
};
this.getAndOr = function () {
return andOr;
};
this.getRelation = function () {
return andOr;
};
this.setObj = function (nObj) {
obj = nObj;
};
this.getObj = function () {
return obj;
};
this.setTab = function (nTab) {
tab = nTab;
};
this.getTab = function () {
return tab;
};
this.setObjNo = function (nObjNo) {
objNo = nObjNo;
};
this.getObjNo = function () {
return objNo;
};
this.setType = function (nType) {
type = nType;
};
this.getType = function () {
return type;
};
this.setObjNo(nObjNo);
this.setTab(nTab);
this.setAndOr(0);
this.setObj(nObj);
this.setColumnName(nColumnName);
this.setType(nType);
};
/**
* where object closure, makes an object with all information of where
*
* @param nRelationOperator type of relation operator to be applied
* @param nQuery stores value of value/sub-query
*
*/
DesignerHistory.Where = function (nRelationOperator, nQuery) {
var relationOperator;
var query;
this.setRelationOperator = function (nRelationOperator) {
relationOperator = nRelationOperator;
};
this.setQuery = function (nQuery) {
query = nQuery;
};
this.getQuery = function () {
return query;
};
this.getRelationOperator = function () {
return relationOperator;
};
this.setQuery(nQuery);
this.setRelationOperator(nRelationOperator);
};
/**
* Orderby object closure
*
* @param nOrder order, ASC or DESC
*/
DesignerHistory.OrderBy = function (nOrder) {
var order;
this.setOrder = function (nOrder) {
order = nOrder;
};
this.getOrder = function () {
return order;
};
this.setOrder(nOrder);
};
/**
* Having object closure, makes an object with all information of where
*
* @param nRelationOperator type of relation operator to be applied
* @param nQuery stores value of value/sub-query
* @param nOperator operator
*/
DesignerHistory.Having = function (nRelationOperator, nQuery, nOperator) {
var relationOperator;
var query;
var operator;
this.setOperator = function (nOperator) {
operator = nOperator;
};
this.setRelationOperator = function (nRelationOperator) {
relationOperator = nRelationOperator;
};
this.setQuery = function (nQuery) {
query = nQuery;
};
this.getQuery = function () {
return query;
};
this.getRelationOperator = function () {
return relationOperator;
};
this.getOperator = function () {
return operator;
};
this.setQuery(nQuery);
this.setRelationOperator(nRelationOperator);
this.setOperator(nOperator);
};
/**
* rename object closure,makes an object with all information of rename
*
* @param nRenameTo new name information
*
*/
DesignerHistory.Rename = function (nRenameTo) {
var renameTo;
this.setRenameTo = function (nRenameTo) {
renameTo = nRenameTo;
};
this.getRenameTo = function () {
return renameTo;
};
this.setRenameTo(nRenameTo);
};
/**
* aggregate object closure
*
* @param nOperator aggregate operator
*
*/
DesignerHistory.Aggregate = function (nOperator) {
var operator;
this.setOperator = function (nOperator) {
operator = nOperator;
};
this.getOperator = function () {
return operator;
};
this.setOperator(nOperator);
};
/**
* This function returns unique element from an array
*
* @param arrayName array from which duplicate elem are to be removed.
* @return unique array
*/
DesignerHistory.unique = function (arrayName) {
var newArray = [];
uniquetop:
for (var i = 0; i < arrayName.length; i++) {
var newArrayLength = newArray.length;
for (var j = 0; j < newArrayLength; j++) {
if (newArray[j] === arrayName[i]) {
continue uniquetop;
}
}
newArray[newArrayLength] = arrayName[i];
}
return newArray;
};
/**
* This function takes in array and a value as input and returns 1 if values is present in array
* else returns -1
*
* @param arrayName array
* @param value value which is to be searched in the array
*/
DesignerHistory.found = function (arrayName, value) {
var arrayNameLength = arrayName.length;
for (var i = 0; i < arrayNameLength; i++) {
if (arrayName[i] === value) {
return 1;
}
}
return -1;
};
/**
* This function concatenates two array
*
* @param {object} add array elements of which are pushed in
* @param {obj[]} arr array in which elements are added
*
* @return {obj[]}
*/
DesignerHistory.addArray = function (add, arr) {
var addLength = add.length;
for (var i = 0; i < addLength; i++) {
arr.push(add[i]);
}
return arr;
};
/**
* This function removes all elements present in one array from the other.
*
* @param {object} rem array from which each element is removed from other array.
* @param {obj[]} arr array from which elements are removed.
*
* @return {obj[]}
*
*/
DesignerHistory.removeArray = function (rem, arr) {
var remLength = rem.length;
for (var i = 0; i < remLength; i++) {
var arrLength = arr.length;
for (var j = 0; j < arrLength; j++) {
if (rem[i] === arr[j]) {
arr.splice(j, 1);
}
}
}
return arr;
};
/**
* This function builds the groupby clause from history object
* @return {string}
*/
DesignerHistory.queryGroupBy = function () {
var i;
var str = '';
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
if (historyArray[i].getType() === 'GroupBy') {
str += '`' + historyArray[i].getColumnName() + '`, ';
}
}
str = str.substr(0, str.length - 2);
return str;
};
/**
* This function builds the Having clause from the history object.
* @return {string}
*/
DesignerHistory.queryHaving = function () {
var i;
var and = '(';
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
if (historyArray[i].getType() === 'Having') {
if (historyArray[i].getObj().getOperator() !== 'None') {
and += historyArray[i].getObj().getOperator() + '(`' + historyArray[i].getColumnName() + '`) ' + historyArray[i].getObj().getRelationOperator();
and += ' ' + historyArray[i].getObj().getQuery() + ', ';
} else {
and += '`' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ', ';
}
}
}
if (and === '(') {
and = '';
} else {
and = and.substr(0, and.length - 2) + ')';
}
return and;
};
/**
* This function builds the orderby clause from the history object.
* @return {string}
*/
DesignerHistory.queryOrderBy = function () {
var i;
var str = '';
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
if (historyArray[i].getType() === 'OrderBy') {
str += '`' + historyArray[i].getColumnName() + '` ' +
historyArray[i].getObj().getOrder() + ', ';
}
}
str = str.substr(0, str.length - 2);
return str;
};
/**
* This function builds the Where clause from the history object.
* @return {string}
*/
DesignerHistory.queryWhere = function () {
var i;
var and = '(';
var or = '(';
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
if (historyArray[i].getType() === 'Where') {
if (historyArray[i].getAndOr() === 0) {
and += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')';
and += ' AND ';
} else {
or += '( `' + historyArray[i].getColumnName() + '` ' + historyArray[i].getObj().getRelationOperator() + ' ' + historyArray[i].getObj().getQuery() + ')';
or += ' OR ';
}
}
}
if (or !== '(') {
or = or.substring(0, (or.length - 4)) + ')';
} else {
or = '';
}
if (and !== '(') {
and = and.substring(0, (and.length - 5)) + ')';
} else {
and = '';
}
if (or !== '') {
and = and + ' OR ' + or + ' )';
}
return and;
};
DesignerHistory.checkAggregate = function (idThis) {
var i;
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`';
if (temp === idThis && historyArray[i].getType() === 'Aggregate') {
return historyArray[i].getObj().getOperator() + '(' + idThis + ')';
}
}
return '';
};
DesignerHistory.checkRename = function (idThis) {
var i;
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
var temp = '`' + historyArray[i].getTab() + '`.`' + historyArray[i].getColumnName() + '`';
if (temp === idThis && historyArray[i].getType() === 'Rename') {
return ' AS `' + historyArray[i].getObj().getRenameTo() + '`';
}
}
return '';
};
/**
* This function builds from clause of query
* makes automatic joins.
*
* @return {string}
*/
DesignerHistory.queryFrom = function () {
var i;
var tabLeft = [];
var tabUsed = [];
var tTabLeft = [];
var temp;
var query = '';
var quer = '';
var parts = [];
var tArray = [];
tArray = fromArray;
var K = 0;
var k;
var key;
var key2;
var key3;
var parts1;
// the constraints that have been used in the LEFT JOIN
var constraintsAdded = [];
var historyArrayLength = historyArray.length;
for (i = 0; i < historyArrayLength; i++) {
fromArray.push(historyArray[i].getTab());
}
fromArray = DesignerHistory.unique(fromArray);
tabLeft = fromArray;
temp = tabLeft.shift();
quer = '`' + temp + '`';
tabUsed.push(temp);
// if master table (key2) matches with tab used get all keys and check if tab_left matches
// after this check if master table (key2) matches with tab left then check if any foreign matches with master .
for (i = 0; i < 2; i++) {
for (K in contr) {
for (key in contr[K]) {// contr name
for (key2 in contr[K][key]) {// table name
parts = key2.split('.');
if (DesignerHistory.found(tabUsed, parts[1]) > 0) {
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split('.');
if (DesignerHistory.found(tabLeft, parts1[1]) > 0) {
if (DesignerHistory.found(constraintsAdded, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += '\n' + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraintsAdded.push(key);
}
tTabLeft.push(parts[1]);
}
}
}
}
}
}
K = 0;
tTabLeft = DesignerHistory.unique(tTabLeft);
tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed);
tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft);
tTabLeft = [];
for (K in contr) {
for (key in contr[K]) {
for (key2 in contr[K][key]) {// table name
parts = key2.split('.');
if (DesignerHistory.found(tabLeft, parts[1]) > 0) {
for (key3 in contr[K][key][key2]) {
parts1 = contr[K][key][key2][key3][0].split('.');
if (DesignerHistory.found(tabUsed, parts1[1]) > 0) {
if (DesignerHistory.found(constraintsAdded, key) > 0) {
query += ' AND ' + '`' + parts[1] + '`.`' + key3 + '` = ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` ';
} else {
query += '\n' + 'LEFT JOIN ';
query += '`' + parts[1] + '` ON ';
query += '`' + parts1[1] + '`.`' + contr[K][key][key2][key3][1] + '` = ';
query += '`' + parts[1] + '`.`' + key3 + '` ';
constraintsAdded.push(key);
}
tTabLeft.push(parts[1]);
}
}
}
}
}
}
tTabLeft = DesignerHistory.unique(tTabLeft);
tabUsed = DesignerHistory.addArray(tTabLeft, tabUsed);
tabLeft = DesignerHistory.removeArray(tTabLeft, tabLeft);
tTabLeft = [];
}
for (k in tabLeft) {
quer += ' , `' + tabLeft[k] + '`';
}
query = quer + query;
fromArray = tArray;
return query;
};
/**
* This function is the main function for query building.
* uses history object details for this.
*
* @uses DesignerHistory.queryWhere()
* @uses DesignerHistory.queryGroupBy()
* @uses DesignerHistory.queryHaving()
* @uses DesignerHistory.queryOrderBy()
*/
DesignerHistory.buildQuery = function () {
var qSelect = 'SELECT ';
var temp;
var selectFieldLength = selectField.length;
if (selectFieldLength > 0) {
for (var i = 0; i < selectFieldLength; i++) {
temp = DesignerHistory.checkAggregate(selectField[i]);
if (temp !== '') {
qSelect += temp;
temp = DesignerHistory.checkRename(selectField[i]);
qSelect += temp + ', ';
} else {
temp = DesignerHistory.checkRename(selectField[i]);
qSelect += selectField[i] + temp + ', ';
}
}
qSelect = qSelect.substring(0, qSelect.length - 2);
} else {
qSelect += '* ';
}
qSelect += '\nFROM ' + DesignerHistory.queryFrom();
var qWhere = DesignerHistory.queryWhere();
if (qWhere !== '') {
qSelect += '\nWHERE ' + qWhere;
}
var qGroupBy = DesignerHistory.queryGroupBy();
if (qGroupBy !== '') {
qSelect += '\nGROUP BY ' + qGroupBy;
}
var qHaving = DesignerHistory.queryHaving();
if (qHaving !== '') {
qSelect += '\nHAVING ' + qHaving;
}
var qOrderBy = DesignerHistory.queryOrderBy();
if (qOrderBy !== '') {
qSelect += '\nORDER BY ' + qOrderBy;
}
$('#buildQuerySubmitButton').on('click', function () {
if (vqbEditor) {
var $elm = $('#buildQueryModal').find('textarea');
vqbEditor.save();
$elm.val(vqbEditor.getValue());
}
$('#vqb_form').trigger('submit');
});
$('#buildQueryModal').modal('show');
$('#buildQueryModalLabel').first().text('SELECT');
$('#buildQueryModal').on('shown.bs.modal', function () {
// Attach syntax highlighted editor to query dialog
/**
* @var $elm jQuery object containing the reference
* to the query textarea.
*/
var $elm = $('#buildQueryModal').find('textarea');
if (! vqbEditor) {
vqbEditor = Functions.getSqlEditor($elm);
}
if (vqbEditor) {
vqbEditor.setValue(qSelect);
vqbEditor.focus();
} else {
$elm.val(qSelect);
$elm.trigger('focus');
}
});
};
AJAX.registerTeardown('designer/history.js', function () {
vqbEditor = null;
historyArray = [];
selectField = [];
$('#ok_edit_rename').off('click');
$('#ok_edit_having').off('click');
$('#ok_edit_Aggr').off('click');
$('#ok_edit_where').off('click');
});
AJAX.registerOnload('designer/history.js', function () {
$('#ok_edit_rename').on('click', function () {
DesignerHistory.edit('Rename');
});
$('#ok_edit_having').on('click', function () {
DesignerHistory.edit('Having');
});
$('#ok_edit_Aggr').on('click', function () {
DesignerHistory.edit('Aggregate');
});
$('#ok_edit_where').on('click', function () {
DesignerHistory.edit('Where');
});
$('#ab').accordion({ collapsible : true, active : 'none' });
});

Some files were not shown because too many files have changed in this diff Show more