1 /* vim: set expandtab sw=4 ts=4 sts=4: */
8 * Holds common parameters such as server, db, table, etc
10 * The content for this is normally loaded from Header.php or
11 * Response.php and executed by ajax.js
13 var PMA_commonParams = (function () {
15 * @var hash params An associative array of key value pairs
19 // The returned object is the public part of the module
22 * Saves all the key value pair that
23 * are provided in the input array
25 * @param obj hash The input array
29 setAll: function (obj) {
31 var updateNavigation = false;
33 if (params[i] !== undefined && params[i] !== obj[i]) {
34 if (i === 'db' || i === 'table') {
35 updateNavigation = true;
41 if (updateNavigation &&
42 $('#pma_navigation_tree').hasClass('synced')
44 PMA_showCurrentNavigation();
48 * Retrieves a value given its key
49 * Returns empty string for undefined values
51 * @param name string The key
55 get: function (name) {
59 * Saves a single key value pair
61 * @param name string The key
62 * @param value string The value
64 * @return self For chainability
66 set: function (name, value) {
67 var updateNavigation = false;
68 if (name === 'db' || name === 'table' &&
69 params[name] !== value
71 updateNavigation = true;
74 if (updateNavigation &&
75 $('#pma_navigation_tree').hasClass('synced')
77 PMA_showCurrentNavigation();
82 * Returns the url query string using the saved parameters
86 getUrlQuery: function () {
87 var common = this.get('common_query');
89 if (common.length > 0) {
93 '%s%sserver=%s&db=%s&table=%s',
94 this.get('common_query'),
96 encodeURIComponent(this.get('server')),
97 encodeURIComponent(this.get('db')),
98 encodeURIComponent(this.get('table'))
105 * Holds common parameters such as server, db, table, etc
107 * The content for this is normally loaded from Header.php or
108 * Response.php and executed by ajax.js
110 var PMA_commonActions = {
112 * Saves the database name when it's changed
113 * and reloads the query window, if necessary
115 * @param new_db string new_db The name of the new database
119 setDb: function (new_db) {
120 if (new_db !== PMA_commonParams.get('db')) {
121 PMA_commonParams.setAll({ 'db': new_db, 'table': '' });
125 * Opens a database in the main part of the page
127 * @param new_db string The name of the new database
131 openDb: function (new_db) {
136 PMA_commonParams.get('opendb_url')
140 * Refreshes the main frame
142 * @param mixed url Undefined to refresh to the same page
143 * String to go to a different page, e.g: 'index.php'
147 refreshMain: function (url, callback) {
149 url = $('#selflink').find('a').attr('href');
150 url = url.substring(0, url.indexOf('?'));
152 url += PMA_commonParams.getUrlQuery();
153 $('<a />', { href: url })
157 AJAX._callback = callback;
162 * Class to handle PMA Drag and Drop Import
167 * @var int, count of total uploads in this view
171 * @var int, count of live uploads
175 * @var string array, allowed extensions
177 allowedExtensions: ['sql', 'xml', 'ldi', 'mediawiki', 'shp'],
179 * @var string array, allowed extensions for compressed files
181 allowedCompressedExtensions: ['gz', 'bz2', 'zip'],
183 * @var obj array to store message returned by import_status.php
187 * Checks if any dropped file has valid extension or not
189 * @param file filename
191 * @return string, extension for valid extension, '' otherwise
193 _getExtension: function (file) {
194 var arr = file.split('.');
195 ext = arr[arr.length - 1];
197 // check if compressed
198 if (jQuery.inArray(ext.toLowerCase(),
199 PMA_DROP_IMPORT.allowedCompressedExtensions) !== -1) {
200 ext = arr[arr.length - 2];
203 // Now check for extension
204 if (jQuery.inArray(ext.toLowerCase(),
205 PMA_DROP_IMPORT.allowedExtensions) !== -1) {
211 * Shows upload progress for different sql uploads
213 * @param: hash (string), hash for specific file upload
214 * @param: percent (float), file upload percentage
218 _setProgress: function (hash, percent) {
219 $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
220 .children('progress').val(percent);
223 * Function to upload the file asynchronously
225 * @param formData FormData object for a specific file
226 * @param hash hash of the current file upload
230 _sendFileToServer: function (formData, hash) {
231 var uploadURL = './import.php'; // Upload URL
235 var xhrobj = $.ajaxSettings.xhr();
237 xhrobj.upload.addEventListener('progress', function (event) {
239 var position = event.loaded || event.position;
240 var total = event.total;
241 if (event.lengthComputable) {
242 percent = Math.ceil(position / total * 100);
245 PMA_DROP_IMPORT._setProgress(hash, percent);
256 success: function (data) {
257 PMA_DROP_IMPORT._importFinished(hash, false, data.success);
259 PMA_DROP_IMPORT.importStatus[PMA_DROP_IMPORT.importStatus.length] = {
267 // -- provide link to cancel the upload
268 $('.pma_sql_import_status div li[data-hash="' + hash +
269 '"] span.filesize').html('<span hash="' +
270 hash + '" class="pma_drop_file_status" task="cancel">' +
271 PMA_messages.dropImportMessageCancel + '</span>');
273 // -- add event listener to this link to abort upload operation
274 $('.pma_sql_import_status div li[data-hash="' + hash +
275 '"] span.filesize span.pma_drop_file_status')
276 .on('click', function () {
277 if ($(this).attr('task') === 'cancel') {
279 $(this).html('<span>' + PMA_messages.dropImportMessageAborted + '</span>');
280 PMA_DROP_IMPORT._importFinished(hash, true, false);
281 } else if ($(this).children('span').html() ===
282 PMA_messages.dropImportMessageFailed) {
283 // -- view information
285 $.each(PMA_DROP_IMPORT.importStatus,
286 function (key, value) {
287 if (value.hash === hash) {
288 $('.pma_drop_result:visible').remove();
289 var filename = $this.parent('span').attr('data-filename');
290 $('body').append('<div class="pma_drop_result"><h2>' +
291 PMA_messages.dropImportImportResultHeader + ' - ' +
292 filename + '<span class="close">x</span></h2>' + value.message + '</div>');
293 $('.pma_drop_result').draggable(); // to make this dialog draggable
300 * Triggered when an object is dragged into the PMA UI
306 _dragenter : function (event) {
307 // We don't want to prevent users from using
308 // browser's default drag-drop feature on some page(s)
309 if ($('.noDragDrop').length !== 0) {
313 event.stopPropagation();
314 event.preventDefault();
315 if (!PMA_DROP_IMPORT._hasFiles(event)) {
318 if (PMA_commonParams.get('db') === '') {
319 $('.pma_drop_handler').html(PMA_messages.dropImportSelectDB);
321 $('.pma_drop_handler').html(PMA_messages.dropImportDropFiles);
323 $('.pma_drop_handler').fadeIn();
326 * Check if dragged element contains Files
328 * @param event the event object
332 _hasFiles: function (event) {
333 return !(typeof event.originalEvent.dataTransfer.types === 'undefined' ||
334 $.inArray('Files', event.originalEvent.dataTransfer.types) < 0 ||
336 'application/x-moz-nativeimage',
337 event.originalEvent.dataTransfer.types
341 * Triggered when dragged file is being dragged over PMA UI
347 _dragover: function (event) {
348 // We don't want to prevent users from using
349 // browser's default drag-drop feature on some page(s)
350 if ($('.noDragDrop').length !== 0) {
354 event.stopPropagation();
355 event.preventDefault();
356 if (!PMA_DROP_IMPORT._hasFiles(event)) {
359 $('.pma_drop_handler').fadeIn();
362 * Triggered when dragged objects are left
368 _dragleave: function (event) {
369 // We don't want to prevent users from using
370 // browser's default drag-drop feature on some page(s)
371 if ($('.noDragDrop').length !== 0) {
374 event.stopPropagation();
375 event.preventDefault();
376 var $pma_drop_handler = $('.pma_drop_handler');
377 $pma_drop_handler.clearQueue().stop();
378 $pma_drop_handler.fadeOut();
379 $pma_drop_handler.html(PMA_messages.dropImportDropFiles);
382 * Called when upload has finished
384 * @param string, unique hash for a certain upload
385 * @param bool, true if upload was aborted
386 * @param bool, status of sql upload, as sent by server
390 _importFinished: function (hash, aborted, status) {
391 $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
392 .children('progress').hide();
393 var icon = 'icon ic_s_success';
394 // -- provide link to view upload status
397 $('.pma_sql_import_status div li[data-hash="' + hash +
398 '"] span.filesize span.pma_drop_file_status')
399 .html('<span>' + PMA_messages.dropImportMessageSuccess + '</a>');
401 $('.pma_sql_import_status div li[data-hash="' + hash +
402 '"] span.filesize span.pma_drop_file_status')
403 .html('<span class="underline">' + PMA_messages.dropImportMessageFailed +
405 icon = 'icon ic_s_error';
408 icon = 'icon ic_s_notice';
410 $('.pma_sql_import_status div li[data-hash="' + hash +
411 '"] span.filesize span.pma_drop_file_status')
412 .attr('task', 'info');
415 $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
416 .prepend('<img src="./themes/dot.gif" title="finished" class="' +
419 // Decrease liveUploadCount by one
420 $('.pma_import_count').html(--PMA_DROP_IMPORT.liveUploadCount);
421 if (!PMA_DROP_IMPORT.liveUploadCount) {
422 $('.pma_sql_import_status h2 .close').fadeIn();
426 * Triggered when dragged objects are dropped to UI
427 * From this function, the AJAX Upload operation is initiated
429 * @param event object
433 _drop: function (event) {
434 // We don't want to prevent users from using
435 // browser's default drag-drop feature on some page(s)
436 if ($('.noDragDrop').length !== 0) {
440 var dbname = PMA_commonParams.get('db');
441 var server = PMA_commonParams.get('server');
443 // if no database is selected -- no
445 var files = event.originalEvent.dataTransfer.files;
446 if (!files || files.length === 0) {
447 // No files actually transferred
448 $('.pma_drop_handler').fadeOut();
449 event.stopPropagation();
450 event.preventDefault();
453 $('.pma_sql_import_status').slideDown();
454 for (var i = 0; i < files.length; i++) {
455 var ext = (PMA_DROP_IMPORT._getExtension(files[i].name));
456 var hash = AJAX.hash(++PMA_DROP_IMPORT.uploadCount);
458 var $pma_sql_import_status_div = $('.pma_sql_import_status div');
459 $pma_sql_import_status_div.append('<li data-hash="' + hash + '">' +
460 ((ext !== '') ? '' : '<img src="./themes/dot.gif" title="invalid format" class="icon ic_s_notice"> ') +
461 escapeHtml(files[i].name) + '<span class="filesize" data-filename="' +
462 escapeHtml(files[i].name) + '">' + (files[i].size / 1024).toFixed(2) +
465 // scroll the UI to bottom
466 $pma_sql_import_status_div.scrollTop(
467 $pma_sql_import_status_div.scrollTop() + 50
468 ); // 50 hardcoded for now
471 // Increment liveUploadCount by one
472 $('.pma_import_count').html(++PMA_DROP_IMPORT.liveUploadCount);
473 $('.pma_sql_import_status h2 .close').fadeOut();
475 $('.pma_sql_import_status div li[data-hash="' + hash + '"]')
476 .append('<br><progress max="100" value="2"></progress>');
479 var fd = new FormData();
480 fd.append('import_file', files[i]);
481 fd.append('noplugin', Math.random().toString(36).substring(2, 12));
482 fd.append('db', dbname);
483 fd.append('server', server);
484 fd.append('token', PMA_commonParams.get('token'));
485 fd.append('import_type', 'database');
486 // todo: method to find the value below
487 fd.append('MAX_FILE_SIZE', '4194304');
488 // todo: method to find the value below
489 fd.append('charset_of_file','utf-8');
490 // todo: method to find the value below
491 fd.append('allow_interrupt', 'yes');
492 fd.append('skip_queries', '0');
493 fd.append('format',ext);
494 fd.append('sql_compatibility','NONE');
495 fd.append('sql_no_auto_value_on_zero','something');
496 fd.append('ajax_request','true');
497 fd.append('hash', hash);
500 PMA_DROP_IMPORT._sendFileToServer(fd, hash);
501 } else if (!PMA_DROP_IMPORT.liveUploadCount) {
502 $('.pma_sql_import_status h2 .close').fadeIn();
506 $('.pma_drop_handler').fadeOut();
507 event.stopPropagation();
508 event.preventDefault();
513 * Called when some user drags, dragover, leave
514 * a file to the PMA UI
515 * @param object Event data
518 $(document).on('dragenter', PMA_DROP_IMPORT._dragenter);
519 $(document).on('dragover', PMA_DROP_IMPORT._dragover);
520 $(document).on('dragleave', '.pma_drop_handler', PMA_DROP_IMPORT._dragleave);
522 // when file is dropped to PMA UI
523 $(document).on('drop', 'body', PMA_DROP_IMPORT._drop);
525 // minimizing-maximising the sql ajax upload status
526 $(document).on('click', '.pma_sql_import_status h2 .minimize', function () {
527 if ($(this).attr('toggle') === 'off') {
528 $('.pma_sql_import_status div').css('height','270px');
529 $(this).attr('toggle','on');
530 $(this).html('-'); // to minimize
532 $('.pma_sql_import_status div').css('height','0px');
533 $(this).attr('toggle','off');
534 $(this).html('+'); // to maximise
538 // closing sql ajax upload status
539 $(document).on('click', '.pma_sql_import_status h2 .close', function () {
540 $('.pma_sql_import_status').fadeOut(function () {
541 $('.pma_sql_import_status div').html('');
542 PMA_DROP_IMPORT.importStatus = []; // clear the message array
546 // Closing the import result box
547 $(document).on('click', '.pma_drop_result h2 .close', function () {
548 $(this).parent('h2').parent('div').remove();