diff --git a/db_events.php b/db_events.php index 7d22f5d8c5..f65960770a 100644 --- a/db_events.php +++ b/db_events.php @@ -1,40 +1,33 @@ diff --git a/db_routines.php b/db_routines.php index 13234a5539..726674c7d3 100644 --- a/db_routines.php +++ b/db_routines.php @@ -11,7 +11,6 @@ */ require_once './libraries/common.inc.php'; require_once './libraries/common.lib.php'; -require_once './libraries/db_routines.lib.php'; require_once './libraries/mysql_charsets.lib.php'; if (PMA_DRIZZLE) { require_once './libraries/data_drizzle.inc.php'; @@ -24,432 +23,17 @@ if (PMA_DRIZZLE) { */ $GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js'; $GLOBALS['js_include'][] = 'jquery/timepicker.js'; -$GLOBALS['js_include'][] = 'db_routines.js'; +$GLOBALS['js_include'][] = 'rte/common.js'; +$GLOBALS['js_include'][] = 'rte/routines.js'; /** - * Create labels for the list + * Include all other files */ -$titles = PMA_buildActionTitles(); - -if ($GLOBALS['is_ajax_request'] != true) { - /** - * Displays the header - */ - require_once './libraries/db_common.inc.php'; - /** - * Displays the tabs - */ - require_once './libraries/db_info.inc.php'; -} else { - if (strlen($db)) { - PMA_DBI_select_db($db); - if (! isset($url_query)) { - $url_query = PMA_generate_common_url($db); - } - } -} +require_once './libraries/rte/rte_routines.lib.php'; /** - * Process all requests + * Do the magic */ - -// Some definitions -$param_directions = array('IN', - 'OUT', - 'INOUT'); -$param_opts_num = array('UNSIGNED', - 'ZEROFILL', - 'UNSIGNED ZEROFILL'); -$param_sqldataaccess = array('NO SQL', - 'CONTAINS SQL', - 'READS SQL DATA', - 'MODIFIES SQL DATA'); - -/** - * Generate the conditional classes that will be used to attach jQuery events to links. - */ -$ajax_class = array( - 'add' => '', - 'edit' => '', - 'exec' => '', - 'drop' => '', - 'export' => '' - ); -if ($GLOBALS['cfg']['AjaxEnable']) { - $ajax_class['add'] = 'class="add_routine_anchor"'; - $ajax_class['edit'] = 'class="edit_routine_anchor"'; - $ajax_class['exec'] = 'class="exec_routine_anchor"'; - $ajax_class['drop'] = 'class="drop_routine_anchor"'; - $ajax_class['export'] = 'class="export_routine_anchor"'; -} - -/** - * Keep a list of errors that occured while processing an 'Add' or 'Edit' operation. - */ -$routine_errors = array(); - -/** - * Handle all user requests other than the default of listing routines - */ -if (! empty($_REQUEST['execute_routine']) && ! empty($_REQUEST['routine_name'])) { - // Build the queries - $routine = PMA_RTN_getRoutineDataFromName($db, $_REQUEST['routine_name'], false); - if ($routine !== false) { - $queries = array(); - $end_query = array(); - $args = array(); - for ($i=0; $i<$routine['num_params']; $i++) { - if (isset($_REQUEST['params'][$routine['param_name'][$i]])) { - $value = $_REQUEST['params'][$routine['param_name'][$i]]; - if (is_array($value)) { // is SET type - $value = implode(',', $value); - } - $value = PMA_sqlAddSlashes($value); - if (! empty($_REQUEST['funcs'][$routine['param_name'][$i]]) - && in_array($_REQUEST['funcs'][$routine['param_name'][$i]], $cfg['Functions'])) { - $queries[] = "SET @p$i={$_REQUEST['funcs'][$routine['param_name'][$i]]}('$value');\n"; - } else { - $queries[] = "SET @p$i='$value';\n"; - } - $args[] = "@p$i"; - } else { - $args[] = "@p$i"; - } - if ($routine['type'] == 'PROCEDURE') { - if ($routine['param_dir'][$i] == 'OUT' || $routine['param_dir'][$i] == 'INOUT') { - $end_query[] = "@p$i AS " . PMA_backquote($routine['param_name'][$i]); - } - } - } - if ($routine['type'] == 'PROCEDURE') { - $queries[] = "CALL " . PMA_backquote($routine['name']) - . "(" . implode(', ', $args) . ");\n"; - if (count($end_query)) { - $queries[] = "SELECT " . implode(', ', $end_query) . ";\n"; - } - } else { - $queries[] = "SELECT " . PMA_backquote($routine['name']) - . "(" . implode(', ', $args) . ") " - . "AS " . PMA_backquote($routine['name']) . ";\n"; - } - // Execute the queries - $affected = 0; - $result = null; - $outcome = true; - foreach ($queries as $num => $query) { - $resource = PMA_DBI_try_query($query); - if ($resource === false) { - $outcome = false; - break; - } - while (true) { - if(! PMA_DBI_more_results()) { - break; - } - PMA_DBI_next_result(); - } - if (substr($query, 0, 6) == 'SELECT') { - $result = $resource; - } else if (substr($query, 0, 4) == 'CALL') { - $affected = PMA_DBI_affected_rows() - PMA_DBI_num_rows($resource); - } - } - // Generate output - if ($outcome) { - $message = __('Your SQL query has been executed successfully'); - if ($routine['type'] == 'PROCEDURE') { - $message .= '
'; - $message .= sprintf(_ngettext('%d row affected by the last statement inside the procedure', '%d rows affected by the last statement inside the procedure', $affected), $affected); - } - $message = PMA_message::success($message); - // Pass the SQL queries through the "pretty printer" - $output = ''; - $output .= PMA_SQP_formatHtml(PMA_SQP_parse(implode($queries))); - $output .= ''; - // Display results - if ($result) { - $output .= "
"; - $output .= sprintf(__('Execution results of routine %s'), - PMA_backquote(htmlspecialchars($routine['name']))); - $output .= ""; - $output .= ""; - foreach (PMA_DBI_get_fields_meta($result) as $key => $field) { - $output .= ""; - } - $output .= ""; - // Stored routines can only ever return ONE ROW. - $data = PMA_DBI_fetch_single_row($result); - foreach ($data as $key => $value) { - if ($value === null) { - $value = 'NULL'; - } else { - $value = htmlspecialchars($value); - } - $output .= ""; - } - $output .= "
" . htmlspecialchars($field->name) . "
" . $value . "
"; - } else { - $notice = __('MySQL returned an empty result set (i.e. zero rows).'); - $output .= PMA_message::notice($notice)->getDisplay(); - } - } else { - $output = ''; - $message = PMA_message::error(sprintf(__('The following query has failed: "%s"'), $query) . '

' - . __('MySQL said: ') . PMA_DBI_getError(null)); - } - // Print/send output - if ($GLOBALS['is_ajax_request']) { - $extra_data = array('dialog' => false); - PMA_ajaxResponse($message->getDisplay() . $output, $message->isSuccess(), $extra_data); - } else { - echo $message->getDisplay() . $output; - if ($message->isError()) { - // At least one query has failed, so shouldn't - // execute any more queries, so we quit. - exit; - } - unset($_POST); - // Now deliberately fall through to displaying the routines list - } - } else { - $message = __('Error in processing request') . ' : ' - . sprintf(__('No routine with name %1$s found in database %2$s'), - htmlspecialchars(PMA_backquote($_REQUEST['routine_name'])), - htmlspecialchars(PMA_backquote($db))); - $message = PMA_message::error($message); - if ($GLOBALS['is_ajax_request']) { - PMA_ajaxResponse($message, $message->isSuccess()); - } else { - echo $message->getDisplay(); - unset($_POST); - } - } -} else if (! empty($_GET['execute_dialog']) && ! empty($_GET['routine_name'])) { - /** - * Display the execute form for a routine. - */ - $routine = PMA_RTN_getRoutineDataFromName($db, $_GET['routine_name'], false); - if ($routine !== false) { - $form = PMA_RTN_getExecuteForm($routine, $GLOBALS['is_ajax_request']); - if ($GLOBALS['is_ajax_request'] == true) { - $extra_data = array(); - $extra_data['dialog'] = true; - $extra_data['title'] = __("Execute routine") . " "; - $extra_data['title'] .= PMA_backquote(htmlentities($_GET['routine_name'], ENT_QUOTES)); - PMA_ajaxResponse($form, true, $extra_data); - } else { - echo "\n\n

" . __("Execute routine") . "

\n\n"; - echo $form; - require './libraries/footer.inc.php'; - // exit; - } - } else if (($GLOBALS['is_ajax_request'] == true)) { - $message = __('Error in processing request') . ' : ' - . sprintf(__('No routine with name %1$s found in database %2$s'), - htmlspecialchars(PMA_backquote($_REQUEST['routine_name'])), - htmlspecialchars(PMA_backquote($db))); - $message = PMA_message::error($message); - PMA_ajaxResponse($message, false); - } -} else if (! empty($_GET['exportroutine']) && ! empty($_GET['routine_name'])) { - /** - * Display the export for a routine. - */ - $routine_name = htmlspecialchars(PMA_backquote($_GET['routine_name'])); - $routine_type = PMA_DBI_fetch_value("SELECT ROUTINE_TYPE " - . "FROM INFORMATION_SCHEMA.ROUTINES " - . "WHERE ROUTINE_SCHEMA='" . PMA_sqlAddSlashes($db) . "' " - . "AND SPECIFIC_NAME='" . PMA_sqlAddSlashes($_GET['routine_name']) . "';"); - if (! empty($routine_type) && $create_proc = PMA_DBI_get_definition($db, $routine_type, $_GET['routine_name'])) { - $create_proc = ''; - if ($GLOBALS['is_ajax_request']) { - $extra_data = array('title' => sprintf(__('Export of routine %s'), $routine_name)); - PMA_ajaxResponse($create_proc, true, $extra_data); - } else { - echo '
' . "\n" - . ' ' . sprintf(__('Export of routine %s'), $routine_name) . '' . "\n" - . $create_proc . "\n" - . '
'; - } - } else { - $response = __('Error in processing request') . ' : ' - . sprintf(__('No routine with name %1$s found in database %2$s'), - $routine_name, htmlspecialchars(PMA_backquote($db))); - $response = PMA_message::error($response); - if ($GLOBALS['is_ajax_request']) { - PMA_ajaxResponse($response, false); - } else { - $response->display(); - } - } -} else if (! empty($_REQUEST['routine_process_addroutine']) || ! empty($_REQUEST['routine_process_editroutine'])) { - /** - * Handle a request to create/edit a routine - */ - $sql_query = ''; - $routine_query = PMA_RTN_getQueryFromRequest(); - if (! count($routine_errors)) { // set by PMA_RTN_getQueryFromRequest() - // Execute the created query - if (! empty($_REQUEST['routine_process_editroutine'])) { - if (! in_array($_REQUEST['routine_original_type'], array('PROCEDURE', 'FUNCTION'))) { - $routine_errors[] = sprintf(__('Invalid routine type: "%s"'), htmlspecialchars($_REQUEST['routine_original_type'])); - } else { - // Backup the old routine, in case something goes wrong - $create_routine = PMA_DBI_get_definition($db, $_REQUEST['routine_original_type'], $_REQUEST['routine_original_name']); - $drop_routine = "DROP {$_REQUEST['routine_original_type']} " . PMA_backquote($_REQUEST['routine_original_name']) . ";\n"; - $result = PMA_DBI_try_query($drop_routine); - if (! $result) { - $routine_errors[] = sprintf(__('The following query has failed: "%s"'), $drop_routine) . '
' - . __('MySQL said: ') . PMA_DBI_getError(null); - } else { - $result = PMA_DBI_try_query($routine_query); - if (! $result) { - $routine_errors[] = sprintf(__('The following query has failed: "%s"'), $routine_query) . '
' - . __('MySQL said: ') . PMA_DBI_getError(null); - // We dropped the old routine, but were unable to create the new one - // Try to restore the backup query - $result = PMA_DBI_try_query($create_routine); - if (! $result) { - // OMG, this is really bad! We dropped the query, failed to create a new one - // and now even the backup query does not execute! - // This should not happen, but we better handle this just in case. - $routine_errors[] = __('Sorry, we failed to restore the dropped routine.') . '
' - . __('The backed up query was:') . "\"$create_routine\"" . '
' - . __('MySQL said: ') . PMA_DBI_getError(null); - } - } else { - $message = PMA_Message::success(__('Routine %1$s has been modified.')); - $message->addParam(PMA_backquote($_REQUEST['routine_name'])); - $sql_query = $drop_routine . $routine_query; - } - } - } - } else { - // 'Add a new routine' mode - $result = PMA_DBI_try_query($routine_query); - if (! $result) { - $routine_errors[] = sprintf(__('The following query has failed: "%s"'), $routine_query) . '

' - . __('MySQL said: ') . PMA_DBI_getError(null); - } else { - $message = PMA_Message::success(__('Routine %1$s has been created.')); - $message->addParam(PMA_backquote($_REQUEST['routine_name'])); - $sql_query = $routine_query; - } - } - } - - if (count($routine_errors)) { - $message = PMA_Message::error(__('One or more errors have occured while processing your request:')); - $message->addString(''); - } - - $output = PMA_showMessage($message, $sql_query); - if ($GLOBALS['is_ajax_request']) { - $extra_data = array(); - if ($message->isSuccess()) { - $columns = "`SPECIFIC_NAME`, `ROUTINE_NAME`, `ROUTINE_TYPE`, `DTD_IDENTIFIER`, `ROUTINE_DEFINITION`"; - $where = "ROUTINE_SCHEMA='" . PMA_sqlAddSlashes($db) . "' AND ROUTINE_NAME='" . PMA_sqlAddSlashes($_REQUEST['routine_name']) . "'"; - $routine = PMA_DBI_fetch_single_row("SELECT $columns FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE $where;"); - $extra_data['name'] = htmlspecialchars(strtoupper($_REQUEST['routine_name'])); - $extra_data['new_row'] = PMA_RTN_getRowForRoutinesList($routine, 0, true); - $response = $output; - } else { - $response = $message; - } - PMA_ajaxResponse($response, $message->isSuccess(), $extra_data); - } -} - -/** - * Display a form used to add/edit a routine, if necessary - */ -if (count($routine_errors) || ( empty($_REQUEST['routine_process_addroutine']) && empty($_REQUEST['routine_process_editroutine']) && - (! empty($_REQUEST['addroutine']) || ! empty($_REQUEST['editroutine']) - || ! empty($_REQUEST['routine_addparameter']) || ! empty($_REQUEST['routine_removeparameter']) - || ! empty($_REQUEST['routine_changetype'])))) { // FIXME: this must be simpler than that - // Handle requests to add/remove parameters and changing routine type - // This is necessary when JS is disabled - $operation = ''; - if (! empty($_REQUEST['routine_addparameter'])) { - $operation = 'add'; - } else if (! empty($_REQUEST['routine_removeparameter'])) { - $operation = 'remove'; - } else if (! empty($_REQUEST['routine_changetype'])) { - $operation = 'change'; - } - // Get the data for the form (if any) - if (! empty($_REQUEST['addroutine'])) { - $title = __("Create routine"); - $routine = PMA_RTN_getRoutineDataFromRequest(); - $mode = 'add'; - } else if (! empty($_REQUEST['editroutine'])) { - $title = __("Edit routine"); - if (! $operation && ! empty($_REQUEST['routine_name']) && empty($_REQUEST['routine_process_editroutine'])) { - $routine = PMA_RTN_getRoutineDataFromName($db, $_REQUEST['routine_name']); - if ($routine !== false) { - $routine['original_name'] = $routine['name']; - $routine['original_type'] = $routine['type']; - } - } else { - $routine = PMA_RTN_getRoutineDataFromRequest(); - } - $mode = 'edit'; - } - if ($routine !== false) { - // Show form - $editor = PMA_RTN_getEditorForm($mode, $operation, $routine, $routine_errors, $GLOBALS['is_ajax_request']); - if ($GLOBALS['is_ajax_request']) { - $template = PMA_RTN_getParameterRow(); - $extra_data = array('title' => $title, 'param_template' => $template, 'type' => $routine['type']); - PMA_ajaxResponse($editor, true, $extra_data); - } - echo "\n\n

$title

\n\n$editor"; - require './libraries/footer.inc.php'; - // exit; - } else { - $message = __('Error in processing request') . ' : ' - . sprintf(__('No routine with name %1$s found in database %2$s'), - htmlspecialchars(PMA_backquote($_REQUEST['routine_name'])), - htmlspecialchars(PMA_backquote($db))); - $message = PMA_message::error($message); - if ($GLOBALS['is_ajax_request']) { - PMA_ajaxResponse($message, false); - } else { - $message->display(); - } - } -} - -/** - * Display a list of available routines - */ -echo PMA_RTN_getRoutinesList(); - -/** - * Display the form for adding a new routine, if the user has the privileges. - */ -echo PMA_RTN_getAddRoutineLink(); - -/** - * Display a warning for users with PHP's old "mysql" extension. - */ -if ($GLOBALS['cfg']['Server']['extension'] === 'mysql') { - trigger_error(__('You are using PHP\'s deprecated \'mysql\' extension, ' - . 'which is not capable of handling multi queries. ' - . 'The execution of some stored routines may fail! ' - . 'Please use the improved \'mysqli\' extension to ' - . 'avoid any problems.'), E_USER_WARNING); -} - -if ($GLOBALS['is_ajax_request'] != true) { - /** - * Displays the footer - */ - require './libraries/footer.inc.php'; -} +require_once './libraries/rte/rte_main.inc.php'; ?> diff --git a/db_triggers.php b/db_triggers.php index 416be77c15..1bd792ec41 100644 --- a/db_triggers.php +++ b/db_triggers.php @@ -1,38 +1,32 @@ diff --git a/export.php b/export.php index 9471ba0c15..6137b96e7c 100644 --- a/export.php +++ b/export.php @@ -125,8 +125,7 @@ $time_start = time(); * Output handler for all exports, if needed buffering, it stores data into * $dump_buffer, otherwise it prints thems out. * - * @param string the insert statement - * + * @param string $line the insert statement * @return bool Whether output suceeded */ function PMA_exportOutputHandler($line) @@ -512,7 +511,7 @@ if ($export_type == 'server') { } if (function_exists('PMA_exportRoutines') && strpos($GLOBALS['sql_structure_or_data'], 'structure') !== false && isset($GLOBALS['sql_procedure_function'])) { - PMA_exportRoutines($db); + PMA_exportRoutines($db); } $i = 0; diff --git a/js/db_events.js b/js/db_events.js deleted file mode 100644 index 3a0ccd5650..0000000000 --- a/js/db_events.js +++ /dev/null @@ -1,2 +0,0 @@ -/* vim: set expandtab sw=4 ts=4 sts=4: */ - diff --git a/js/db_routines.js b/js/db_routines.js deleted file mode 100644 index ceb09626dd..0000000000 --- a/js/db_routines.js +++ /dev/null @@ -1,568 +0,0 @@ -/* vim: set expandtab sw=4 ts=4 sts=4: */ - -/** - * Validate routine editor form fields. - * - * @param syntaxHiglighter an object containing the reference to the - * codemirror editor. This will be used to - * focus the form on the codemirror editor - * if it contains invalid data. - */ -function validateRoutineEditor(syntaxHiglighter) { - /** - * @var inputname Will contain the value of the name - * attribute of input fields being checked. - */ - var inputname = ''; - /** - * @var $elm a jQuery object containing the reference - * to an element that is being validated. - */ - var $elm = null; - /** - * @var isError Stores the outcome of the validation. - */ - var isError = false; - - $elm = $('.rte_table').last().find('input[name=routine_name]'); - if ($elm.val() == '') { - $elm.focus(); - isError = true; - } else if ($elm.val().length > 64) { - alert(PMA_messages['strValueTooLong']); - $elm.focus().select(); - return false; - } - if (! isError) { - $elm = $('.rte_table').find('textarea[name=routine_definition]'); - if ($elm.val() == '') { - syntaxHiglighter.focus(); - isError = true; - } - } - if (! isError) { - $('.routine_params_table').last().find('tr').each(function() { - if (! isError) { - $(this).find(':input').each(function() { - inputname = $(this).attr('name'); - if (inputname.substr(0, 17) == 'routine_param_dir' || - inputname.substr(0, 18) == 'routine_param_name' || - inputname.substr(0, 18) == 'routine_param_type') { - if ($(this).val() == '') { - $(this).focus(); - isError = true; - return false; - } - } - }); - } - }); - } - if (! isError) { - // SET, ENUM, VARCHAR and VARBINARY fields must have length/values - $('.routine_params_table').last().find('tr').each(function() { - var $inputtyp = $(this).find('select[name^=routine_param_type]'); - var $inputlen = $(this).find('input[name^=routine_param_length]'); - if ($inputtyp.length && $inputlen.length) { - if (($inputtyp.val() == 'ENUM' || $inputtyp.val() == 'SET' || $inputtyp.val().substr(0,3) == 'VAR') - && $inputlen.val() == '') { - $inputlen.focus(); - isError = true; - return false; - } - } - }); - } - if (! isError && $('select[name=routine_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 = $('select[name=routine_returntype]'); - var $returnlen = $('input[name=routine_returnlength]'); - if (($returntyp.val() == 'ENUM' || $returntyp.val() == 'SET' || $returntyp.val().substr(0,3) == 'VAR') - && $returnlen.val() == '') { - $returnlen.focus(); - isError = true; - } - } - if (! isError && $('select[name=routine_type]').find(':selected').val() == 'FUNCTION') { - if ($('.rte_table').find('textarea[name=routine_definition]').val().toLowerCase().indexOf('return') < 0) { - syntaxHiglighter.focus(); - alert(PMA_messages['MissingReturn']); - return false; - } - } - if (! isError) { - $elm = $('.rte_table').last().find('input[name=routine_comment]'); - if ($elm.val().length > 64) { - alert(PMA_messages['strValueTooLong']); - $elm.focus().select(); - return false; - } - } - if (! isError) { - return true; - } else { - alert(PMA_messages['strFormEmpty']); - return false; - } -} // end validateRoutineEditor() - -/** - * 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 - */ -function setOptionsForParameter($type, $len, $text, $num) { - // 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(); - break; - case 'TINYTEXT': - case 'TEXT': - case 'MEDIUMTEXT': - case 'LONGTEXT': - case 'CHAR': - case 'VARCHAR': - case 'SET': - case 'ENUM': - $text.parent().show(); - $text.show(); - $num.parent().hide(); - break; - default: - $text.parent().show(); - $text.hide(); - $num.parent().hide(); - break; - } - // Process for parameter length - switch ($type.val()) { - case 'DATE': - case 'DATETIME': - case 'TIME': - case 'TINYBLOB': - case 'TINYTEXT': - case 'BLOB': - case 'TEXT': - case 'MEDIUMBLOB': - case 'MEDIUMTEXT': - case 'LONGBLOB': - case 'LONGTEXT': - $len.hide(); - break; - default: - $len.show(); - break; - } -} - -/** - * Attach Ajax event handlers for the Routines functionalities. - * - * @see $cfg['AjaxEnable'] - */ -$(document).ready(function() { - /** - * @var $ajaxDialog jQuery object containing the reference to the - * dialog that contains the routine editor. - */ - var $ajaxDialog = null; - /** - * @var param_template This variable contains the template for one row - * of the parameters table that is attached to the - * dialog when a new parameter is added. - */ - var param_template = ''; - /** - * @var syntaxHiglighter Reference to the codemirror editor. - */ - var syntaxHiglighter = null; - /** - * @var button_options Object containing options for jQueryUI dialog buttons - */ - var button_options = {}; - - /** - * Attach Ajax event handlers for the Add/Edit routine functionality. - * - * @uses PMA_ajaxShowMessage() - * @uses PMA_ajaxRemoveMessage() - * - * @see $cfg['AjaxEnable'] - */ - $('.add_routine_anchor, .edit_routine_anchor').live('click', function(event) { - event.preventDefault(); - /** - * @var $edit_row jQuery object containing the reference to - * the row of the the routine being edited - * from the list of routines . - */ - var $edit_row = null; - if ($(this).hasClass('edit_routine_anchor')) { - // Remeber the row of the routine being edited for later, - // so that if the edit is successful, we can replace the - // row with info about the modified routine. - $edit_row = $(this).parents('tr'); - } - /** - * @var $msg jQuery object containing the reference to - * the AJAX message shown to the user. - */ - var $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']); - $.get($(this).attr('href'), {'ajax_request': true}, function(data) { - if(data.success == true) { - PMA_ajaxRemoveMessage($msg); - button_options[PMA_messages['strGo']] = function() { - syntaxHiglighter.save(); - // Validate editor and submit request, if passed. - if (validateRoutineEditor(syntaxHiglighter)) { - /** - * @var data Form data to be sent in the AJAX request. - */ - var data = $('.rte_form').last().serialize(); - $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']); - $.post('db_routines.php', data, function (data) { - if(data.success == true) { - // Routine created successfully - PMA_ajaxRemoveMessage($msg); - PMA_slidingMessage(data.message); - $ajaxDialog.dialog('close'); - // If we are in 'edit' mode, we must remove the reference to the old row. - if (mode == 'edit') { - $edit_row.remove(); - } - // Insert the new row at the correct location in the list of routines - /** - * @var text Contains the name of a routine 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 has been inserted - * in the list of routines or not. - */ - var inserted = false; - $('table.data').find('tr').each(function() { - text = $(this).children('td').eq(0).find('strong').text().toUpperCase(); - if (text != '' && text > data.name) { - $(this).before(data.new_row); - inserted = true; - return false; - } - }); - if (! inserted) { - $('table.data').append(data.new_row); - } - // Fade-in the new row - $('.ajaxInsert').show('slow').removeClass('ajaxInsert'); - // Now we have inserted the row at the correct position, but surely - // at least some row classes are wrong now. So we will itirate - // throught all rows and assign correct classes to them. - /** - * @var ct Count of processed rows. - */ - var ct = 0; - $('table.data').find('tr').has('td').each(function() { - rowclass = (ct % 2 == 0) ? 'even' : 'odd'; - $(this).removeClass().addClass(rowclass); - ct++; - }); - // If this is the first routine being added, remove the - // "No routines" message and show the list of routines. - if ($('table.data').find('tr').has('td').length > 0 && $('#nothing2display').is(':visible')) { - $('#nothing2display').hide("slow", function () { - $('table.data').show("slow"); - }); - } - } else { - PMA_ajaxShowMessage(data.error); - } - }); - } - } // end of function that handles the submission of the Editor - button_options[PMA_messages['strClose']] = function() { - $(this).dialog("close"); - } - /** - * Display the dialog to the user - */ - $ajaxDialog = $('
'+data.message+'
').dialog({ - width: 700, // TODO: make a better decision about the size - height: 550, // of the dialog based on the size of the viewport - buttons: button_options, - title: data.title, - modal: true, - close: function () { - $(this).remove(); - } - }); - $ajaxDialog.find('input[name=routine_name]').focus(); - /** - * @var mode Used to remeber whether the editor is in - * "Edit Routine" or "Add Routine" mode. - */ - var mode = 'add'; - if ($('input[name=routine_process_editroutine]').length > 0) { - mode = 'edit'; - } - // Cache the template for a parameter table row - param_template = data.param_template; - // Make adjustments in the dialog to make it AJAX compatible - $('.routine_param_remove').show(); - $('input[name=routine_removeparameter]').remove(); - $('input[name=routine_addparameter]').css('width', '100%'); - // Enable/disable the 'options' dropdowns for parameters as necessary - $('.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1'); - $('.routine_params_table').last().find('tr').has('td').each(function() { - setOptionsForParameter( - $(this).find('select[name^=routine_param_type]'), - $(this).find('input[name^=routine_param_length]'), - $(this).find('select[name^=routine_param_opts_text]'), - $(this).find('select[name^=routine_param_opts_num]') - ); - }); - // Enable/disable the 'options' dropdowns for function return value as necessary - setOptionsForParameter( - $('.rte_table').last().find('select[name=routine_returntype]'), - $('.rte_table').last().find('input[name=routine_returnlength]'), - $('.rte_table').last().find('select[name=routine_returnopts_text]'), - $('.rte_table').last().find('select[name=routine_returnopts_num]') - ); - // Attach syntax highlited editor to routine definition - /** - * @var $elm jQuery object containing the reference to - * the "Routine Definition" textarea. - */ - var $elm = $('textarea[name=routine_definition]').last(); - /** - * @var opts Options to pass to the codemirror editor. - */ - var opts = {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"}; - syntaxHiglighter = CodeMirror.fromTextArea($elm[0], opts); - // Hack to prevent the syntax highlighter from expanding beyond dialog boundries - $('.CodeMirror-scroll').find('div').first().css('width', '1px'); - } else { - PMA_ajaxShowMessage(data.error); - } - }) // end $.get() - }); // end $.live() - - /** - * Attach Ajax event handlers for the "Add parameter to routine" functionality. - * - * @see $cfg['AjaxEnable'] - */ - $('input[name=routine_addparameter]').live('click', function(event) { - event.preventDefault(); - /** - * @var $routine_params_table jQuery object containing the reference - * to the routine parameters table. - */ - var $routine_params_table = $('.routine_params_table').last(); - /** - * @var $new_param_row A string containing the HTML code for the - * new row for the routine paramaters table. - */ - var new_param_row = param_template.replace(/%s/g, $routine_params_table.find('tr').length-1); - $routine_params_table.append(new_param_row); - if ($('.rte_table').find('select[name=routine_type]').val() == 'FUNCTION') { - $('.routine_return_row').show(); - $('.routine_direction_cell').hide(); - } - /** - * @var $newrow jQuery object containing the reference to the newly - * inserted row in the routine parameters table. - */ - var $newrow = $('.routine_params_table').last().find('tr').has('td').last(); - setOptionsForParameter( - $newrow.find('select[name^=routine_param_type]'), - $newrow.find('input[name^=routine_param_length]'), - $newrow.find('select[name^=routine_param_opts_text]'), - $newrow.find('select[name^=routine_param_opts_num]') - ); - }); // end $.live() - - /** - * Attach Ajax event handlers for the "Remove parameter from routine" functionality. - * - * @see $cfg['AjaxEnable'] - */ - $('.routine_param_remove_anchor').live('click', 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. - /** - * @var index Counter used for reindexing the input - * fields in the routine parameters table. - */ - var index = 0; - $('.routine_params_table').last().find('tr').has('td').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, 17) == 'routine_param_dir') { - $(this).attr('name', inputname.substr(0, 17) + '[' + index + ']'); - } else if (inputname.substr(0, 18) == 'routine_param_name') { - $(this).attr('name', inputname.substr(0, 18) + '[' + index + ']'); - } else if (inputname.substr(0, 18) == 'routine_param_type') { - $(this).attr('name', inputname.substr(0, 18) + '[' + index + ']'); - } else if (inputname.substr(0, 20) == 'routine_param_length') { - $(this).attr('name', inputname.substr(0, 20) + '[' + index + ']'); - } else if (inputname.substr(0, 23) == 'routine_param_opts_text') { - $(this).attr('name', inputname.substr(0, 23) + '[' + index + ']'); - } else if (inputname.substr(0, 22) == 'routine_param_opts_num') { - $(this).attr('name', inputname.substr(0, 22) + '[' + index + ']'); - } - }); - index++; - }); - }); // end $.live() - - /** - * Attach Ajax event handlers for the "Change routine type" functionality. - * - * @see $cfg['AjaxEnable'] - */ - $('select[name=routine_type]').live('change', function() { - $('.routine_return_row, .routine_direction_cell').toggle(); - }); // end $.live() - - /** - * Attach Ajax event handlers for the "Change parameter type" functionality. - * - * @see $cfg['AjaxEnable'] - */ - $('select[name^=routine_param_type]').live('change', function() { - /** - * @var $row jQuery object containing the reference to - * a row in the routine parameters table. - */ - var $row = $(this).parents('tr').first(); - setOptionsForParameter( - $row.find('select[name^=routine_param_type]'), - $row.find('input[name^=routine_param_length]'), - $row.find('select[name^=routine_param_opts_text]'), - $row.find('select[name^=routine_param_opts_num]') - ); - }); - - /** - * Attach Ajax event handlers for the "Change the type of return - * variable of function" functionality. - * - * @see $cfg['AjaxEnable'] - */ - $('select[name=routine_returntype]').live('change', function() { - setOptionsForParameter( - $('.rte_table').find('select[name=routine_returntype]'), - $('.rte_table').find('input[name=routine_returnlength]'), - $('.rte_table').find('select[name=routine_returnopts_text]'), - $('.rte_table').find('select[name=routine_returnopts_num]') - ); - }); - - /** - * Attach Ajax event handlers for the Execute routine functionality. - * - * @uses PMA_ajaxShowMessage() - * @uses PMA_ajaxRemoveMessage() - * - * @see $cfg['AjaxEnable'] - */ - $('.exec_routine_anchor').live('click', function(event) { - event.preventDefault(); - /** - * @var $msg jQuery object containing the reference to - * the AJAX message shown to the user. - */ - var $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']); - $.get($(this).attr('href'), {'ajax_request': true}, function(data) { - if(data.success == true) { - PMA_ajaxRemoveMessage($msg); - if (data.dialog) { - button_options[PMA_messages['strGo']] = function() { - /** - * @var data Form data to be sent in the AJAX request. - */ - var data = $('.rte_form').last().serialize(); - $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']); - $.post('db_routines.php', data, function (data) { - if(data.success == true) { - // Routine executed successfully - PMA_ajaxRemoveMessage($msg); - PMA_slidingMessage(data.message); - $ajaxDialog.dialog('close'); - } else { - PMA_ajaxShowMessage(data.error); - } - }); - } - button_options[PMA_messages['strClose']] = function() { - $(this).dialog("close"); - } - /** - * Display the dialog to the user - */ - $ajaxDialog = $('
'+data.message+'
').dialog({ - width: 650, // TODO: make a better decision about the size - // of the dialog based on the size of the viewport - buttons: button_options, - title: data.title, - modal: true, - close: function () { - $(this).remove(); - } - }); - $ajaxDialog.find('input[name^=params]').first().focus(); - } else { - // Routine executed successfully - PMA_slidingMessage(data.message); - } - } else { - PMA_ajaxShowMessage(data.error); - } - }); - }); - - /** - * Attach Ajax event handlers for input fields in the routines editor - * and the routine execution dialog used to submit the Ajax request - * when the ENTER key is pressed. - * - * @see $cfg['AjaxEnable'] - */ - $('input[name^=routine], input[name^=params]').live('keydown', function(e) { - if (e.which == 13) { - e.preventDefault(); - if (typeof button_options[PMA_messages['strGo']] == 'function') { - button_options[PMA_messages['strGo']].call(); - } - } - }); -}); // end of $(document).ready() for the Routine Functionalities diff --git a/js/display_triggers.js b/js/display_triggers.js deleted file mode 100644 index 3a0ccd5650..0000000000 --- a/js/display_triggers.js +++ /dev/null @@ -1,2 +0,0 @@ -/* vim: set expandtab sw=4 ts=4 sts=4: */ - diff --git a/js/functions.js b/js/functions.js index ae5cdbad8f..1b874ca6b9 100644 --- a/js/functions.js +++ b/js/functions.js @@ -1816,6 +1816,76 @@ $(document).ready(function() { }, 'top.frame_content'); //end $(document).ready for 'Create Table' +/** + * jQuery coding for 'Change Table'. Used on tbl_structure.php * + * Attach Ajax Event handlers for Change Table + */ +$(document).ready(function() { + /** + *Ajax action for submitting the column change form + **/ + $("#append_fields_form input[name=do_save_data]").live('click', function(event) { + event.preventDefault(); + /** + * @var the_form object referring to the export form + */ + var $form = $("#append_fields_form"); + + /* + * First validate the form; if there is a problem, avoid submitting it + * + * 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 (checkTableEditForm($form[0], $form.find('input[name=orig_num_fields]').val())) { + // OK, form passed validation step + if ($form.hasClass('ajax')) { + PMA_prepareForAjaxRequest($form); + //User wants to submit the form + $.post($form.attr('action'), $form.serialize()+"&do_save_data=Save", function(data) { + if ($("#sqlqueryresults").length != 0) { + $("#sqlqueryresults").remove(); + } else if ($(".error").length != 0) { + $(".error").remove(); + } + if (data.success == true) { + PMA_ajaxShowMessage(data.message); + $("
").insertAfter("#topmenucontainer"); + $("#sqlqueryresults").html(data.sql_query); + $("#result_query .notice").remove(); + $("#result_query").prepend((data.message)); + if ($("#change_column_dialog").length > 0) { + $("#change_column_dialog").dialog("close").remove(); + } + /*Reload the field form*/ + $.post($("#fieldsForm").attr('action'), $("#fieldsForm").serialize()+"&ajax_request=true", function(form_data) { + $("#fieldsForm").remove(); + var $temp_div = $("
").append(form_data); + if ($("#sqlqueryresults").length != 0) { + $temp_div.find("#fieldsForm").insertAfter("#sqlqueryresults"); + } else { + $temp_div.find("#fieldsForm").insertAfter(".error"); + } + /*Call the function to display the more options in table*/ + displayMoreTableOpts(); + }); + } else { + var $temp_div = $("
").append(data); + var $error = $temp_div.find(".error code").addClass("error"); + PMA_ajaxShowMessage($error); + } + }) // end $.post() + } else { + // non-Ajax submit + $form.append(''); + $form.submit(); + } + } + }) // end change table button "do_save_data" + +}, 'top.frame_content'); //end $(document).ready for 'Change Table' + /** * Attach Ajax event handlers for Drop Database. Moved here from db_structure.js * as it was also required on db_create.php @@ -2355,6 +2425,136 @@ function PMA_init_slider() { }); } +/** + * var toggleButton This is a function that creates a toggle + * sliding button given a jQuery reference + * to the correct DOM element + */ +var toggleButton = function ($obj) { + // In rtl mode the toggle switch is flipped horizontally + // so we need to take that into account + if ($('.text_direction', $obj).text() == 'ltr') { + var right = 'right'; + } else { + var right = 'left'; + } + /** + * var h Height of the button, used to scale the + * background image and position the layers + */ + var h = $obj.height(); + $('img', $obj).height(h); + $('table', $obj).css('bottom', h-1); + /** + * var on Width of the "ON" part of the toggle switch + * var off Width of the "OFF" part of the toggle switch + */ + var on = $('.toggleOn', $obj).width(); + var off = $('.toggleOff', $obj).width(); + // Make the "ON" and "OFF" parts of the switch the same size + $('.toggleOn > div', $obj).width(Math.max(on, off)); + $('.toggleOff > div', $obj).width(Math.max(on, off)); + /** + * var w Width of the central part of the switch + */ + var w = parseInt(($('img', $obj).height() / 16) * 22, 10); + // Resize the central part of the switch on the top + // layer to match the background + $('table td:nth-child(2) > div', $obj).width(w); + /** + * var imgw Width of the background image + * var tblw Width of the foreground layer + * var offset By how many pixels to move the background + * image, so that it matches the top layer + */ + var imgw = $('img', $obj).width(); + var tblw = $('table', $obj).width(); + var offset = parseInt(((imgw - tblw) / 2), 10); + // Move the background to match the layout of the top layer + $obj.find('img').css(right, offset); + /** + * var offw Outer width of the "ON" part of the toggle switch + * var btnw Outer width of the central part of the switch + */ + var offw = $('.toggleOff', $obj).outerWidth(); + var btnw = $('table td:nth-child(2)', $obj).outerWidth(); + // Resize the main div so that exactly one side of + // the switch plus the central part fit into it. + $obj.width(offw + btnw + 2); + /** + * var move How many pixels to move the + * switch by when toggling + */ + var move = $('.toggleOff', $obj).outerWidth(); + // If the switch is initialized to the + // OFF state we need to move it now. + if ($('.container', $obj).hasClass('off')) { + if (right == 'right') { + $('table, img', $obj).animate({'left': '-=' + move + 'px'}, 0); + } else { + $('table, img', $obj).animate({'left': '+=' + move + 'px'}, 0); + } + } + // Attach an 'onclick' event to the switch + $('.container', $obj).click(function () { + if ($(this).hasClass('isActive')) { + return false; + } else { + $(this).addClass('isActive'); + } + var $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']); + var $container = $(this); + var callback = $('.callback', this).text(); + // Perform the actual toggle + if ($(this).hasClass('on')) { + if (right == 'right') { + var operator = '-='; + } else { + var operator = '+='; + } + var url = $(this).find('.toggleOff > span').text(); + var removeClass = 'on'; + var addClass = 'off'; + } else { + if (right == 'right') { + var operator = '+='; + } else { + var operator = '-='; + } + var url = $(this).find('.toggleOn > span').text(); + var removeClass = 'off'; + var addClass = 'on'; + } + $.post(url, {'ajax_request': true}, function(data) { + if(data.success == true) { + PMA_ajaxRemoveMessage($msg); + $container + .removeClass(removeClass) + .addClass(addClass) + .animate({'left': operator + move + 'px'}, function () { + $container.removeClass('isActive'); + }); + eval(callback); + } else { + PMA_ajaxShowMessage(data.error); + $container.removeClass('isActive'); + } + }); + }); +}; + +/** + * Initialise all toggle buttons + */ +$(window).load(function () { + $('.toggleAjax').each(function () { + $(this) + .show() + .find('.toggleButton') + toggleButton($(this)); + }); +}); + /** * Vertical pointer */ @@ -2458,44 +2658,6 @@ $(document).ready(function() { }) // end of $(document).ready() -/** - * Attach Ajax event handlers for Export of Routines, Triggers and Events. - * - * @uses PMA_ajaxShowMessage() - * @uses PMA_ajaxRemoveMessage() - * - * @see $cfg['AjaxEnable'] - */ -$(document).ready(function() { - $('.export_routine_anchor, .export_trigger_anchor, .export_event_anchor').live('click', function(event) { - event.preventDefault(); - var $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']); - $.get($(this).attr('href'), {'ajax_request': true}, function(data) { - if(data.success == true) { - PMA_ajaxRemoveMessage($msg); - /** - * @var button_options Object containing options for jQueryUI dialog buttons - */ - var button_options = {}; - button_options[PMA_messages['strClose']] = function() {$(this).dialog("close").remove();} - /** - * Display the dialog to the user - */ - var $ajaxDialog = $('
'+data.message+'
').dialog({ - width: 500, - buttons: button_options, - title: data.title - }); - // Attach syntax highlited editor to export dialog - var elm = $ajaxDialog.find('textarea'); - CodeMirror.fromTextArea(elm[0], {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"}); - } else { - PMA_ajaxShowMessage(data.error); - } - }) // end $.get() - }); // end $.live() -}); // end of $(document).ready() for Export of Routines, Triggers and Events. - /** * Creates a message inside an object with a sliding effect * @@ -2573,69 +2735,6 @@ function PMA_slidingMessage(msg, $obj) { return true; } // end PMA_slidingMessage() -/** - * Attach Ajax event handlers for Drop functionality of Routines, Triggers and Events. - * - * @uses $.PMA_confirm() - * @uses PMA_ajaxShowMessage() - * @see $cfg['AjaxEnable'] - */ -$(document).ready(function() { - $('.drop_routine_anchor, .drop_trigger_anchor, .drop_event_anchor').live('click', function(event) { - event.preventDefault(); - /** - * @var $curr_row Object containing reference to the current row - */ - var $curr_row = $(this).parents('tr'); - /** - * @var question String containing the question to be asked for confirmation - */ - var question = $('
').text($curr_row.children('td').children('.drop_sql').html()); - $(this).PMA_confirm(question, $(this).attr('href'), function(url) { - /** - * @var $msg jQuery object containing the reference to - * the AJAX message shown to the user. - */ - var $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']); - $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function(data) { - if(data.success == true) { - /** - * @var $table Object containing reference to the main list of elements. - */ - var $table = $curr_row.parent(); - if ($table.find('tr').length == 2) { - $table.hide("slow", function () { - $(this).find('tr.even, tr.odd').remove(); - $('#nothing2display').show("slow"); - }); - } else { - $curr_row.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 itirate - // throught all rows and assign correct classes to them. - /** - * @var ct Count of processed rows. - */ - var ct = 0; - $table.find('tr').has('td').each(function() { - rowclass = (ct % 2 == 0) ? 'even' : 'odd'; - $(this).removeClass().addClass(rowclass); - ct++; - }); - }); - } - // Show the query that we just executed - PMA_ajaxRemoveMessage($msg); - PMA_slidingMessage(data.sql_query); - } else { - PMA_ajaxShowMessage(PMA_messages['strErrorProcessingRequest'] + " : " + data.error); - } - }) // end $.get() - }) // end $.PMA_confirm() - }); // end $.live() -}); //end $(document).ready() for Drop functionality of Routines, Triggers and Events. - /** * Attach Ajax event handlers for Drop Table. * diff --git a/js/messages.php b/js/messages.php index b8ac2bac3a..4bf5d7c142 100644 --- a/js/messages.php +++ b/js/messages.php @@ -122,7 +122,6 @@ $js_messages['strDeleting'] = __('Deleting'); /* For db_routines.js */ $js_messages['MissingReturn'] = __('The definition of a stored function must contain a RETURN statement!'); -$js_messages['strValueTooLong'] = __('Value too long in the form!'); /* For import.js */ $js_messages['strImportCSV'] = __('Note: If the file contains multiple tables, they will be combined into one'); diff --git a/js/rte/common.js b/js/rte/common.js new file mode 100644 index 0000000000..4e3893e5c0 --- /dev/null +++ b/js/rte/common.js @@ -0,0 +1,380 @@ +/* vim: set expandtab sw=4 ts=4 sts=4: */ + +/** + * @var RTE a JavaScript namespace containing the functionality + * for Routines, Triggers and Events. + * + * This namespace is extended by the functionality required + * to handle a specific item (a routine, trigger or event) + * in the relevant javascript files in this folder. + */ +var RTE = { + /** + * @var $ajaxDialog jQuery object containing the reference to the + * dialog that contains the editor. + */ + $ajaxDialog: null, + /** + * @var syntaxHiglighter Reference to the codemirror editor. + */ + syntaxHiglighter: null, + /** + * @var buttonOptions Object containing options for + * the jQueryUI dialog buttons + */ + buttonOptions: {}, + /** + * Validate editor form fields. + */ + 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 = $('.rte_table').last().find('input[name=item_name]'); + if ($elm.val() === '') { + $elm.focus(); + alert(PMA_messages['strFormEmpty']); + return false; + } + $elm = $('.rte_table').find('textarea[name=item_definition]'); + if ($elm.val() === '') { + this.syntaxHiglighter.focus(); + alert(PMA_messages['strFormEmpty']); + return false; + } + // The validation has so far passed, so now + // we can validate item-specific fields. + return RTE.validateCustom(); + }, // end validate() + /** + * Validate custom editor form fields. + * This function can be overridden by + * other files in this folder. + */ + validateCustom: function () { + return true; + }, // end validateCustom() + /** + * Execute some code after the ajax + * dialog for the ditor is shown. + * This function can be overridden by + * other files in this folder. + */ + postDialogShow: function () { + // Nothing by default + } // end postDialogShow() +}; // end RTE namespace + +/** + * Attach Ajax event handlers for the Routines, Triggers and Events editor. + * + * @see $cfg['AjaxEnable'] + */ +$(document).ready(function () { + /** + * Attach Ajax event handlers for the Add/Edit functionality. + */ + $('.ajax_add_anchor, .ajax_edit_anchor').live('click', function (event) { + event.preventDefault(); + /** + * @var $edit_row jQuery object containing the reference to + * the row of the the item being edited + * from the list of items . + */ + var $edit_row = null; + if ($(this).hasClass('ajax_edit_anchor')) { + // Remeber 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. + $edit_row = $(this).parents('tr'); + } + /** + * @var $msg jQuery object containing the reference to + * the AJAX message shown to the user. + */ + var $msg = PMA_ajaxShowMessage(); + $.get($(this).attr('href'), {'ajax_request': true}, function (data) { + if (data.success === true) { + // We have successfully fetched the editor form + PMA_ajaxRemoveMessage($msg); + // Now define the function that is called when + // the user presses the "Go" button + RTE.buttonOptions[PMA_messages['strGo']] = function () { + // Move the data from the codemirror editor back to the + // textarea, where it can be used in the form submission. + RTE.syntaxHiglighter.save(); + // Validate editor and submit request, if passed. + if (RTE.validate()) { + /** + * @var data Form data to be sent in the AJAX request. + */ + var data = $('.rte_form').last().serialize(); + $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']); + $.post($('.rte_form').last().attr('action'), data, function (data) { + if (data.success === true) { + // Item created successfully + PMA_ajaxRemoveMessage($msg); + PMA_slidingMessage(data.message); + RTE.$ajaxDialog.dialog('close'); + // If we are in 'edit' mode, we must remove the reference to the old row. + if (mode === 'edit') { + $edit_row.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(); + text = $.trim(text); + 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 + $('.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 itirate + // throught 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) ? 'even' : 'odd'; + $(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"); + }); + } + } else { + PMA_ajaxShowMessage(data.error); + } + }); // end $.post() + } // end "if (RTE.validate())" + }; // end of function that handles the submission of the Editor + RTE.buttonOptions[PMA_messages['strClose']] = function () { + $(this).dialog("close"); + }; + /** + * Display the dialog to the user + */ + RTE.$ajaxDialog = $('
' + data.message + '
').dialog({ + width: 700, + height: 555, + buttons: RTE.buttonOptions, + title: data.title, + modal: true, + close: function () { + $(this).remove(); + } + }); + RTE.$ajaxDialog.find('input[name=item_name]').focus(); + RTE.$ajaxDialog.find('.datefield, .datetimefield').each(function () { + PMA_addDatepicker($(this).css('width', '95%')); + }); + /** + * @var mode Used to remeber whether the editor is in + * "Edit" or "Add" mode. + */ + var mode = 'add'; + if ($('input[name=editor_process_edit]').length > 0) { + mode = 'edit'; + } + // Attach syntax highlited editor to the definition + /** + * @var $elm jQuery object containing the reference to + * the Definition textarea. + */ + var $elm = $('textarea[name=item_definition]').last(); + /** + * @var opts Options to pass to the codemirror editor. + */ + var opts = {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"}; + RTE.syntaxHiglighter = CodeMirror.fromTextArea($elm[0], opts); + // Hack to prevent the syntax highlighter from expanding beyond dialog boundries + $('.CodeMirror-scroll').find('div').first().css('width', '1px'); + // Execute item-specific code + RTE.postDialogShow(data); + } else { + PMA_ajaxShowMessage(data.error); + } + }); // end $.get() + }); // end $.live() + + /** + * Attach Ajax event handlers for input fields in the editor + * and the routine execution dialog used to submit the Ajax + * request when the ENTER key is pressed. + */ + $('.rte_table').find('input[name^=item], input[name^=params]').live('keydown', function (e) { + if (e.which === 13) { // 13 is the ENTER key + e.preventDefault(); + if (typeof RTE.buttonOptions[PMA_messages['strGo']] === 'function') { + RTE.buttonOptions[PMA_messages['strGo']].call(); + } + } + }); // end $.live() + + /** + * Attach Ajax event handlers for Export of Routines, Triggers and Events. + */ + $('.ajax_export_anchor').live('click', function (event) { + event.preventDefault(); + var $msg = PMA_ajaxShowMessage(); + // Fire the ajax request straight away + $.get($(this).attr('href'), {'ajax_request': true}, function (data) { + if (data.success === true) { + PMA_ajaxRemoveMessage($msg); + /** + * @var button_options Object containing options for jQueryUI dialog buttons + */ + var button_options = {}; + button_options[PMA_messages['strClose']] = function () { + $(this).dialog("close").remove(); + }; + /** + * Display the dialog to the user + */ + var $ajaxDialog = $('
' + data.message + '
').dialog({ + width: 500, + buttons: button_options, + title: data.title + }); + // Attach syntax highlited editor to export dialog + /** + * @var $elm jQuery object containing the reference + * to the Export textarea. + */ + var $elm = $ajaxDialog.find('textarea'); + /** + * @var opts Options to pass to the codemirror editor. + */ + var opts = {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"}; + CodeMirror.fromTextArea($elm[0], opts); + } else { + PMA_ajaxShowMessage(data.error); + } + }); // end $.get() + }); // end $.live() + + /** + * Attach Ajax event handlers for Drop functionality of Routines, Triggers and Events. + */ + $('.ajax_drop_anchor').live('click', function (event) { + event.preventDefault(); + /** + * @var $curr_row Object containing reference to the current row + */ + var $curr_row = $(this).parents('tr'); + /** + * @var question String containing the question to be asked for confirmation + */ + var question = $('
').text($curr_row.children('td').children('.drop_sql').html()); + // We ask for confirmation first here, before submitting the ajax request + $(this).PMA_confirm(question, $(this).attr('href'), function (url) { + /** + * @var $msg jQuery object containing the reference to + * the AJAX message shown to the user. + */ + var $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']); + $.get(url, {'is_js_confirmed': 1, 'ajax_request': true}, function (data) { + if (data.success === true) { + /** + * @var $table Object containing reference to the main list of elements. + */ + var $table = $curr_row.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 === 2) { + // 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(); + $('#nothing2display').show("slow"); + }); + } else { + $curr_row.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 itirate + // throught 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 === 0) ? 'even' : 'odd'; + $(this).removeClass().addClass(rowclass); + ct++; + }); + }); + } + // Get rid of the "Loading" message + PMA_ajaxRemoveMessage($msg); + // Show the query that we just executed + PMA_slidingMessage(data.sql_query); + } else { + PMA_ajaxShowMessage(PMA_messages['strErrorProcessingRequest'] + " : " + data.error); + } + }); // end $.get() + }); // end $.PMA_confirm() + }); // end $.live() +}); // end of $(document).ready() diff --git a/js/rte/events.js b/js/rte/events.js new file mode 100644 index 0000000000..257a17dd9f --- /dev/null +++ b/js/rte/events.js @@ -0,0 +1,43 @@ +/* vim: set expandtab sw=4 ts=4 sts=4: */ + +/** + * Overriding the validateCustom() function defined in common.js + */ +RTE.validateCustom = function () { + /** + * @var $elm a jQuery object containing the reference + * to an element that is being validated. + */ + var $elm = null; + if ($('select[name=item_type]').find(':selected').val() === 'RECURRING') { + // The interval field must not be empty for recurring events + $elm = $('input[name=item_interval_value]'); + if ($elm.val() === '') { + $elm.focus(); + alert(PMA_messages['strFormEmpty']); + return false; + } + } else { + // The execute_at field must not be empty for "once off" events + $elm = $('input[name=item_execute_at]'); + if ($elm.val() === '') { + $elm.focus(); + alert(PMA_messages['strFormEmpty']); + return false; + } + } + return true; +}; // end RTE.validateCustom() + +/** + * Attach Ajax event handlers for the "Change event type" + * functionality in the events editor, so that the correct + * rows are shown in the editor when changing the event type + * + * @see $cfg['AjaxEnable'] + */ +$(document).ready(function () { + $('select[name=item_type]').live('change', function () { + $('.recurring_event_row, .onetime_event_row').toggle(); + }); // end $.live() +}); // end of $(document).ready() diff --git a/js/rte/routines.js b/js/rte/routines.js new file mode 100644 index 0000000000..50c4f00051 --- /dev/null +++ b/js/rte/routines.js @@ -0,0 +1,395 @@ +/* vim: set expandtab sw=4 ts=4 sts=4: */ + +/** + * @var param_template This variable contains the template for one row + * of the parameters table that is attached to the + * dialog when a new parameter is added. + */ +RTE.param_template = ''; + +/** + * Overriding the postDialogShow() function defined in common.js + * + * @param data JSON-encoded data from the ajax request + */ +RTE.postDialogShow = function (data) { + // Cache the template for a parameter table row + RTE.param_template = data.param_template; + // Make adjustments in the dialog to make it AJAX compatible + $('.routine_param_remove').show(); + $('input[name=routine_removeparameter]').remove(); + $('input[name=routine_addparameter]').css('width', '100%'); + // Enable/disable the 'options' dropdowns for parameters as necessary + $('.routine_params_table').last().find('th[colspan=2]').attr('colspan', '1'); + $('.routine_params_table').last().find('tr').has('td').each(function () { + RTE.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 + RTE.setOptionsForParameter( + $('.rte_table').last().find('select[name=item_returntype]'), + $('.rte_table').last().find('input[name=item_returnlength]'), + $('.rte_table').last().find('select[name=item_returnopts_text]'), + $('.rte_table').last().find('select[name=item_returnopts_num]') + ); +}; // end RTE.postDialogShow() + +/** + * Overriding the validateCustom() function defined in common.js + */ +RTE.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 = ''; + $('.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, 17) === 'item_param_dir' || + inputname.substr(0, 18) === 'item_param_name' || + inputname.substr(0, 18) === 'item_param_type') { + if ($(this).val() === '') { + $(this).focus(); + isSuccess = false; + return false; + } + } + }); + } else { + return false; + } + }); + if (! isSuccess) { + alert(PMA_messages['strFormEmpty']); + return false; + } + $('.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.focus(); + isSuccess = false; + return false; + } + } + }); + if (! isSuccess) { + alert(PMA_messages['strFormEmpty']); + return false; + } + if ($('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 = $('select[name=item_returntype]'); + var $returnlen = $('input[name=item_returnlength]'); + if (($returntyp.val() === 'ENUM' || $returntyp.val() === 'SET' || $returntyp.val().substr(0, 3) === 'VAR') + && $returnlen.val() === '') { + $returnlen.focus(); + alert(PMA_messages['strFormEmpty']); + return false; + } + } + if ($('select[name=item_type]').find(':selected').val() === 'FUNCTION') { + // A function must contain a RETURN statement in its definition + if ($('.rte_table').find('textarea[name=item_definition]').val().toUpperCase().indexOf('RETURN') < 0) { + RTE.syntaxHiglighter.focus(); + alert(PMA_messages['MissingReturn']); + return false; + } + } + return true; +}; // end RTE.validateCustom() + +/** + * 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 + */ +RTE.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 $no_opts = $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 $no_len = $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(); + $no_opts.hide(); + break; + case 'TINYTEXT': + case 'TEXT': + case 'MEDIUMTEXT': + case 'LONGTEXT': + case 'CHAR': + case 'VARCHAR': + case 'SET': + case 'ENUM': + $text.parent().show(); + $num.parent().hide(); + $no_opts.hide(); + break; + default: + $text.parent().hide(); + $num.parent().hide(); + $no_opts.show(); + break; + } + // Process for parameter length + switch ($type.val()) { + case 'DATE': + case 'DATETIME': + case 'TIME': + case 'TINYBLOB': + case 'TINYTEXT': + case 'BLOB': + case 'TEXT': + case 'MEDIUMBLOB': + case 'MEDIUMTEXT': + case 'LONGBLOB': + case 'LONGTEXT': + $len.parent().hide(); + $no_len.show(); + break; + default: + $len.parent().show(); + $no_len.hide(); + break; + } +}; // end RTE.setOptionsForParameter() + +/** + * Attach Ajax event handlers for the Routines functionalities. + * + * @see $cfg['AjaxEnable'] + */ +$(document).ready(function () { + /** + * Attach Ajax event handlers for the "Add parameter to routine" functionality. + */ + $('input[name=routine_addparameter]').live('click', function (event) { + event.preventDefault(); + /** + * @var $routine_params_table jQuery object containing the reference + * to the routine parameters table. + */ + var $routine_params_table = $('.routine_params_table').last(); + /** + * @var $new_param_row A string containing the HTML code for the + * new row for the routine paramaters table. + */ + var new_param_row = RTE.param_template.replace(/%s/g, $routine_params_table.find('tr').length - 1); + // Append the new row to the parameters table + $routine_params_table.append(new_param_row); + // Make sure that the row is correctly shown according to the type of routine + if ($('.rte_table').find('select[name=item_type]').val() === 'FUNCTION') { + $('.routine_return_row').show(); + $('.routine_direction_cell').hide(); + } + /** + * @var $newrow jQuery object containing the reference to the newly + * inserted row in the routine parameters table. + */ + var $newrow = $('.routine_params_table').last().find('tr').has('td').last(); + // Enable/disable the 'options' dropdowns for parameters as necessary + RTE.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]') + ); + }); // end $.live() + + /** + * Attach Ajax event handlers for the "Remove parameter from routine" functionality. + */ + $('.routine_param_remove_anchor').live('click', 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. + /** + * @var index Counter used for reindexing the input + * fields in the routine parameters table. + */ + var index = 0; + $('.routine_params_table').last().find('tr').has('td').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, 17) === 'item_param_dir') { + $(this).attr('name', inputname.substr(0, 17) + '[' + index + ']'); + } else if (inputname.substr(0, 18) === 'item_param_name') { + $(this).attr('name', inputname.substr(0, 18) + '[' + index + ']'); + } else if (inputname.substr(0, 18) === 'item_param_type') { + $(this).attr('name', inputname.substr(0, 18) + '[' + index + ']'); + } else if (inputname.substr(0, 20) === 'item_param_length') { + $(this).attr('name', inputname.substr(0, 20) + '[' + index + ']'); + } else if (inputname.substr(0, 23) === 'item_param_opts_text') { + $(this).attr('name', inputname.substr(0, 23) + '[' + index + ']'); + } else if (inputname.substr(0, 22) === 'item_param_opts_num') { + $(this).attr('name', inputname.substr(0, 22) + '[' + index + ']'); + } + }); + index++; + }); + }); // end $.live() + + /** + * Attach Ajax event handlers for the "Change routine type" + * functionality in the routines editor, so that the correct + * fields are shown in the editor when changing the routine type + */ + $('select[name=item_type]').live('change', function () { + $('.routine_return_row, .routine_direction_cell').toggle(); + }); // end $.live() + + /** + * Attach Ajax event handlers for the "Change parameter type" + * functionality in the routines editor, so that the correct + * option/length fields, if any, are shown when changing + * a parameter type + */ + $('select[name^=item_param_type]').live('change', function () { + /** + * @var $row jQuery object containing the reference to + * a row in the routine parameters table + */ + var $row = $(this).parents('tr').first(); + RTE.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]') + ); + }); // end $.live() + + /** + * Attach Ajax event handlers for the "Change the type of return + * variable of function" functionality, so that the correct fields, + * if any, are shown when changing the function return type type + */ + $('select[name=item_returntype]').live('change', function () { + RTE.setOptionsForParameter( + $('.rte_table').find('select[name=item_returntype]'), + $('.rte_table').find('input[name=item_returnlength]'), + $('.rte_table').find('select[name=item_returnopts_text]'), + $('.rte_table').find('select[name=item_returnopts_num]') + ); + }); // end $.live() + + /** + * Attach Ajax event handlers for the Execute routine functionality. + */ + $('.ajax_exec_anchor').live('click', function (event) { + event.preventDefault(); + /** + * @var $msg jQuery object containing the reference to + * the AJAX message shown to the user + */ + var $msg = PMA_ajaxShowMessage(); + $.get($(this).attr('href'), {'ajax_request': true}, function (data) { + if (data.success === true) { + PMA_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) { + // Define the function that is called when + // the user presses the "Go" button + RTE.buttonOptions[PMA_messages['strGo']] = function () { + /** + * @var data Form data to be sent in the AJAX request. + */ + var data = $('.rte_form').last().serialize(); + $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']); + $.post('db_routines.php', data, function (data) { + if (data.success === true) { + // Routine executed successfully + PMA_ajaxRemoveMessage($msg); + PMA_slidingMessage(data.message); + $ajaxDialog.dialog('close'); + } else { + PMA_ajaxShowMessage(data.error); + } + }); + }; + RTE.buttonOptions[PMA_messages['strClose']] = function () { + $(this).dialog("close"); + }; + /** + * Display the dialog to the user + */ + $ajaxDialog = $('
' + data.message + '
').dialog({ + width: 650, + buttons: RTE.buttonOptions, + title: data.title, + modal: true, + close: function () { + $(this).remove(); + } + }); + $ajaxDialog.find('input[name^=params]').first().focus(); + /** + * Attach the datepickers to the relevant form fields + */ + $ajaxDialog.find('.datefield, .datetimefield').each(function () { + PMA_addDatepicker($(this).css('width', '95%')); + }); + } else { + // Routine executed successfully + PMA_slidingMessage(data.message); + } + } else { + PMA_ajaxShowMessage(data.error); + } + }); // end $.get() + }); // end $.live() +}); // end of $(document).ready() for the Routine Functionalities diff --git a/js/rte/triggers.js b/js/rte/triggers.js new file mode 100644 index 0000000000..826cd55cfb --- /dev/null +++ b/js/rte/triggers.js @@ -0,0 +1,8 @@ +/* vim: set expandtab sw=4 ts=4 sts=4: */ + +/** + * So far it looks like triggers don't need + * any special treatment as far as JavaScript + * goes, but leaving this file here in case + * the need for custom code will arise. + */ diff --git a/js/tbl_structure.js b/js/tbl_structure.js index c58bd5443a..a9b9adae77 100644 --- a/js/tbl_structure.js +++ b/js/tbl_structure.js @@ -18,7 +18,7 @@ * */ $(document).ready(function() { - + /** * Attach Event Handler for 'Drop Column' * @@ -181,53 +181,6 @@ $(document).ready(function() { changeColumns(action,url); }); - /** - *Ajax action for submitting the column change form - **/ - $("#append_fields_form input[name=do_save_data].ajax").live('click', function(event) { - event.preventDefault(); - /** - * @var the_form object referring to the export form - */ - var $form = $("#append_fields_form"); - - PMA_prepareForAjaxRequest($form); - //User wants to submit the form - $.post($form.attr('action'), $form.serialize()+"&do_save_data=Save", function(data) { - if ($("#sqlqueryresults").length != 0) { - $("#sqlqueryresults").remove(); - } else if ($(".error").length != 0) { - $(".error").remove(); - } - if (data.success == true) { - PMA_ajaxShowMessage(data.message); - $("
").insertAfter("#topmenucontainer"); - $("#sqlqueryresults").html(data.sql_query); - $("#result_query .notice").remove(); - $("#result_query").prepend((data.message)); - if ($("#change_column_dialog").length > 0) { - $("#change_column_dialog").dialog("close").remove(); - } - /*Reload the field form*/ - $.post($("#fieldsForm").attr('action'), $("#fieldsForm").serialize()+"&ajax_request=true", function(form_data) { - $("#fieldsForm").remove(); - var $temp_div = $("
").append(form_data); - if ($("#sqlqueryresults").length != 0) { - $temp_div.find("#fieldsForm").insertAfter("#sqlqueryresults"); - } else { - $temp_div.find("#fieldsForm").insertAfter(".error"); - } - /*Call the function to display the more options in table*/ - displayMoreTableOpts(); - }); - } else { - var $temp_div = $("
").append(data); - var $error = $temp_div.find(".error code").addClass("error"); - PMA_ajaxShowMessage($error); - } - }) // end $.post() - }) // end insert table button "do_save_data" - /** *Ajax event handler for index edit **/ @@ -239,7 +192,11 @@ $(document).ready(function() { } url = url + "&ajax_request=true"; - var div = $('
'); + /*Remove the hidden dialogs if there are*/ + if ($('#edit_index_dialog').length != 0) { + $('#edit_index_dialog').remove(); + } + var $div = $('
'); /** * @var button_options Object that stores the options passed to jQueryUI @@ -256,7 +213,7 @@ $(document).ready(function() { $.get( "tbl_indexes.php" , url , function(data) { //in the case of an error, show the error message returned. if (data.success != undefined && data.success == false) { - div + $div .append(data.error) .dialog({ title: PMA_messages['strEdit'], @@ -267,7 +224,7 @@ $(document).ready(function() { buttons : button_options_error })// end dialog options } else { - div + $div .append(data) .dialog({ title: PMA_messages['strEdit'], @@ -280,6 +237,7 @@ $(document).ready(function() { //Remove the top menu container from the dialog .find("#topmenucontainer").hide() ; // end dialog options + checkIndexType(); checkIndexName("index_frm"); } PMA_ajaxRemoveMessage($msgbox); @@ -311,22 +269,22 @@ $(document).ready(function() { /*Reload the field form*/ $("#table_index").remove(); - var temp_div = $("
").append(data.index_table); - $(temp_div).find("#table_index").insertAfter("#index_header"); + var $temp_div = $("
").append(data.index_table); + $temp_div.find("#table_index").insertAfter("#index_header"); if ($("#edit_index_dialog").length > 0) { $("#edit_index_dialog").dialog("close").remove(); } } else { if(data.error != undefined) { - var temp_div = $("
").append(data.error); - if($(temp_div).find(".error code").length != 0) { - var error = $(temp_div).find(".error code").addClass("error"); + var $temp_div = $("
").append(data.error); + if ($temp_div.find(".error code").length != 0) { + var $error = $temp_div.find(".error code").addClass("error"); } else { - var error = temp_div; + var $error = $temp_div; } } - PMA_ajaxShowMessage(error); + PMA_ajaxShowMessage($error); } }) // end $.post() @@ -346,8 +304,8 @@ $(document).ready(function() { //User wants to submit the form $.post($form.attr('action'), $form.serialize()+"&add_fields=Go", function(data) { $("#index_columns").remove(); - var temp_div = $("
").append(data); - $(temp_div).find("#index_columns").appendTo("#index_edit_fields"); + var $temp_div = $("
").append(data); + $temp_div.find("#index_columns").appendTo("#index_edit_fields"); }) // end $.post() }) // end insert table button "Go" @@ -394,7 +352,7 @@ function changeColumns(action,url) { if ($('#change_column_dialog').length != 0) { $('#change_column_dialog').remove(); } - var div = $('
'); + var $div = $('
'); /** * @var button_options Object that stores the options passed to jQueryUI @@ -411,7 +369,7 @@ function changeColumns(action,url) { $.get( action , url , function(data) { //in the case of an error, show the error message returned. if (data.success != undefined && data.success == false) { - div + $div .append(data.error) .dialog({ title: PMA_messages['strChangeTbl'], @@ -422,7 +380,7 @@ function changeColumns(action,url) { buttons : button_options_error })// end dialog options } else { - div + $div .append(data) .dialog({ title: PMA_messages['strChangeTbl'], diff --git a/libraries/Index.class.php b/libraries/Index.class.php index 35ea369253..822ba2d845 100644 --- a/libraries/Index.class.php +++ b/libraries/Index.class.php @@ -194,9 +194,10 @@ class PMA_Index // $columns[names][] // $columns[sub_parts][] foreach ($columns['names'] as $key => $name) { + $sub_part = isset($columns['sub_parts'][$key]) ? $columns['sub_parts'][$key] : ''; $_columns[] = array( 'Column_name' => $name, - 'Sub_part' => $columns['sub_parts'][$key], + 'Sub_part' => $sub_part, ); } } else { diff --git a/libraries/common.inc.php b/libraries/common.inc.php index 8ea4081f2d..06f6417f99 100644 --- a/libraries/common.inc.php +++ b/libraries/common.inc.php @@ -363,6 +363,7 @@ $goto_whitelist = array( 'db_create.php', 'db_datadict.php', 'db_sql.php', + 'db_events.php', 'db_export.php', 'db_importdocsql.php', 'db_qbe.php', diff --git a/libraries/common.lib.php b/libraries/common.lib.php index e006fa01e3..522e471e4f 100644 --- a/libraries/common.lib.php +++ b/libraries/common.lib.php @@ -2406,6 +2406,87 @@ function PMA_generate_slider_effect($id, $message) \n"; + if ($GLOBALS['cfg']['AjaxEnable']) { + $retval .= "\n"; + $retval .= "
\n"; + $retval .= "
\n"; + $retval .= "
\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
 
\n"; + $retval .= " \n"; + $retval .= " $link_off\n"; + $retval .= "
"; + $retval .= str_replace(' ', ' ', $options[0]['label']) . "
\n"; + $retval .= "
\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " $callback\n"; + $retval .= " {$GLOBALS['text_dir']}\n"; + $retval .= "
\n"; + $retval .= "
\n"; + $retval .= "
\n"; + } + $retval .= ""; + + return $retval; +} // end PMA_toggleButton() + /** * Clears cache content which needs to be refreshed on user change. */ diff --git a/libraries/database_interface.lib.php b/libraries/database_interface.lib.php index 243ebfe182..c40397dc9e 100644 --- a/libraries/database_interface.lib.php +++ b/libraries/database_interface.lib.php @@ -1592,7 +1592,7 @@ function PMA_DBI_get_triggers($db, $table = '', $delimiter = '//') // Note: in http://dev.mysql.com/doc/refman/5.0/en/faqs-triggers.html // their example uses WHERE TRIGGER_SCHEMA='dbname' so let's use this // instead of WHERE EVENT_OBJECT_SCHEMA='dbname' - $query = "SELECT TRIGGER_SCHEMA, TRIGGER_NAME, EVENT_MANIPULATION, EVENT_OBJECT_TABLE, ACTION_TIMING, ACTION_STATEMENT, EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA= '" . PMA_sqlAddSlashes($db,true) . "';"; + $query = "SELECT TRIGGER_SCHEMA, TRIGGER_NAME, EVENT_MANIPULATION, EVENT_OBJECT_TABLE, ACTION_TIMING, ACTION_STATEMENT, EVENT_OBJECT_SCHEMA, EVENT_OBJECT_TABLE, DEFINER FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA= '" . PMA_sqlAddSlashes($db,true) . "';"; if (! empty($table)) { $query .= " AND EVENT_OBJECT_TABLE = '" . PMA_sqlAddSlashes($table, true) . "';"; } @@ -1611,12 +1611,15 @@ function PMA_DBI_get_triggers($db, $table = '', $delimiter = '//') $trigger['EVENT_MANIPULATION'] = $trigger['Event']; $trigger['EVENT_OBJECT_TABLE'] = $trigger['Table']; $trigger['ACTION_STATEMENT'] = $trigger['Statement']; + $trigger['DEFINER'] = $trigger['Definer']; } $one_result = array(); $one_result['name'] = $trigger['TRIGGER_NAME']; $one_result['table'] = $trigger['EVENT_OBJECT_TABLE']; $one_result['action_timing'] = $trigger['ACTION_TIMING']; $one_result['event_manipulation'] = $trigger['EVENT_MANIPULATION']; + $one_result['definition'] = $trigger['ACTION_STATEMENT']; + $one_result['definer'] = $trigger['DEFINER']; // do not prepend the schema name; this way, importing the // definition into another schema will work @@ -1627,6 +1630,14 @@ function PMA_DBI_get_triggers($db, $table = '', $delimiter = '//') $result[] = $one_result; } } + + // Sort results by name + $name = array(); + foreach($result as $key => $value) { + $name[] = $value['name']; + } + array_multisort($name, SORT_ASC, $result); + return($result); } diff --git a/libraries/db_events.inc.php b/libraries/db_events.inc.php deleted file mode 100644 index adf265e2f3..0000000000 --- a/libraries/db_events.inc.php +++ /dev/null @@ -1,150 +0,0 @@ -' . $create_event . ''; - if (! empty($_REQUEST['ajax_request'])) { - $extra_data = array('title' => sprintf(__('Export of event %s'), $event_name)); - PMA_ajaxResponse($create_event, true, $extra_data); - } else { - echo '
' . "\n" - . ' ' . sprintf(__('Export of event "%s"'), $event_name) . '' . "\n" - . $create_event - . '
'; - } - } else { - $response = __('Error in Processing Request') . ' : ' - . sprintf(__('No event with name %s found in database %s'), - $event_name, htmlspecialchars(PMA_backquote($db))); - $response = PMA_message::error($response); - if (! empty($_REQUEST['ajax_request'])) { - PMA_ajaxResponse($response, false); - } else { - $response->display(); - } - } -} - -/** - * Display a list of available events - */ -echo "\n\n\n\n"; -echo '
' . "\n"; -echo ' ' . __('Events') . '' . "\n"; -if (! $events) { - echo __('There are no events to display.'); -} else { - echo '
' . __('There are no events to display.') . '
'; - echo ''; - echo sprintf(' - - - - ', - __('Name'), - __('Action'), - __('Type')); - $ct=0; - $delimiter = '//'; - foreach ($events as $event) { - - // information_schema (at least in MySQL 5.1.22) does not return - // the full CREATE EVENT statement in a way that could be useful for us - // so we rely on PMA_DBI_get_definition() which uses SHOW CREATE EVENT - - $create_event = PMA_DBI_get_definition($db, 'EVENT', $event['EVENT_NAME']); - $definition = 'DROP EVENT IF EXISTS ' . PMA_backquote($event['EVENT_NAME']) - . $delimiter . "\n" . $create_event . "\n"; - - $sqlDrop = 'DROP EVENT ' . PMA_backquote($event['EVENT_NAME']); - echo sprintf(' - - - - - - ', - ($ct%2 == 0) ? 'even' : 'odd', - $sqlDrop, - $event['EVENT_NAME'], - ! empty($definition) ? PMA_linkOrButton('db_sql.php?' . $url_query . '&sql_query=' . urlencode($definition) . '&show_query=1&db_query_force=1&delimiter=' . urlencode($delimiter), $titles['Edit']) : ' ', - $create_event, - '' . $titles['Export'] . '', - '' . $titles['Drop'] . '', - $event['EVENT_TYPE']); - $ct++; - } - echo '
%s%s%s
%s%s%s%s%s
'; -} -echo '
' . "\n"; - -/** - * If there has been a request to change the state - * of the event scheduler, process it now. - */ -if (! empty($_GET['toggle_scheduler'])) { - $new_scheduler_state = $_GET['toggle_scheduler']; - if ($new_scheduler_state === 'ON' || $new_scheduler_state === 'OFF') { - PMA_DBI_query("SET GLOBAL event_scheduler='$new_scheduler_state'"); - } -} - -/** - * Prepare to show the event scheduler fieldset, if necessary - */ -$tableStart = ''; -$schedulerFieldset = ''; -$es_state = PMA_DBI_fetch_value("SHOW GLOBAL VARIABLES LIKE 'event_scheduler'", 0, 1); -if ($es_state === 'ON' || $es_state === 'OFF') { - $es_change = ($es_state == 'ON') ? 'OFF' : 'ON'; - $tableStart = '
'; - $schedulerFieldset = '
' . "\n" - . PMA_getIcon('b_events.png') - . ($es_state === 'ON' ? __('The event scheduler is enabled') : __('The event scheduler is disabled')) . ':' - . ' ' - . ($es_change === 'ON' ? __('Turn it on') : __('Turn it off')) - . '' . "\n" - . '
' . "\n"; -} - -/** - * Display the form for adding a new event - */ -echo $tableStart . '
' . "\n" - . ' ' . "\n" - . PMA_getIcon('b_event_add.png') . __('Add an event') . '' . "\n" - . '
' . "\n"; - -/** - * Display the state of the event scheduler - * and offer an option to toggle it. - */ -echo $schedulerFieldset; - -?> diff --git a/libraries/db_links.inc.php b/libraries/db_links.inc.php index 6442185006..4e4059143e 100644 --- a/libraries/db_links.inc.php +++ b/libraries/db_links.inc.php @@ -125,12 +125,14 @@ if (! $db_is_information_schema) { $tabs[] =& $tab_routines; } if (PMA_MYSQL_INT_VERSION >= 50106 && ! PMA_DRIZZLE) { - // Temporarily hiding this unfinished feature - // $tabs[] =& $tab_events; + if (PMA_currentUserHasPrivilege('EVENT', $db)) { + $tabs[] =& $tab_events; + } } if (PMA_MYSQL_INT_VERSION >= 50002 && ! PMA_DRIZZLE) { - // Temporarily hiding this unfinished feature - // $tabs[] =& $tab_triggers; + if (PMA_currentUserHasPrivilege('TRIGGER', $db)) { + $tabs[] =& $tab_triggers; + } } } if (PMA_Tracker::isActive()) { diff --git a/libraries/db_routines.lib.php b/libraries/db_routines.lib.php deleted file mode 100644 index 7591d390b1..0000000000 --- a/libraries/db_routines.lib.php +++ /dev/null @@ -1,1204 +0,0 @@ - '', - 1 => '', - 2 => '', - 3 => '', - 4 => ''); - $parsed_param = PMA_SQP_parse($value); - $pos = 0; - if (in_array(strtoupper($parsed_param[$pos]['data']), $param_directions)) { - $retval[0] = strtoupper($parsed_param[0]['data']); - $pos++; - } - if ($parsed_param[$pos]['type'] == 'alpha_identifier' || $parsed_param[$pos]['type'] == 'quote_backtick') { - $retval[1] = PMA_unQuote($parsed_param[$pos]['data']); - $pos++; - } - $depth = 0; - $param_length = ''; - $param_opts = array(); - for ($i=$pos; $i<$parsed_param['len']; $i++) { - if (($parsed_param[$i]['type'] == 'alpha_columnType' - || $parsed_param[$i]['type'] == 'alpha_functionName') // "CHAR" seems to be mistaken for a function by the parser - && $depth == 0) { - $retval[2] = strtoupper($parsed_param[$i]['data']); - } else if ($parsed_param[$i]['type'] == 'punct_bracket_open_round' && $depth == 0) { - $depth = 1; - } else if ($parsed_param[$i]['type'] == 'punct_bracket_close_round' && $depth == 1) { - $depth = 0; - } else if ($depth == 1) { - $param_length .= $parsed_param[$i]['data']; - } else if ($parsed_param[$i]['type'] == 'alpha_reservedWord' && strtoupper($parsed_param[$i]['data']) == 'CHARSET' && $depth == 0) { - if ($parsed_param[$i+1]['type'] == 'alpha_charset' || $parsed_param[$i+1]['type'] == 'alpha_identifier') { - $param_opts[] = strtolower($parsed_param[$i+1]['data']); - } - } else if ($parsed_param[$i]['type'] == 'alpha_columnAttrib' && $depth == 0) { - $param_opts[] = strtoupper($parsed_param[$i]['data']); - } - } - $retval[3] = $param_length; - sort($param_opts); - $retval[4] = implode(' ', $param_opts); - - return $retval; -} // end PMA_RTN_parseOneParameter() - - -/** - * This function looks through the contents of a parsed - * SHOW CREATE [PROCEDURE | FUNCTION] query and extracts - * information about the routine's parameters. - * - * @param array $parsed_query Parsed query, returned by by PMA_SQP_parse() - * @param string $routine_type Routine type: 'PROCEDURE' or 'FUNCTION' - * - * @return array Information about the parameteres of a routine. - * - */ -function PMA_RTN_parseAllParameters($parsed_query, $routine_type) -{ - global $param_directions; - - $retval = array(); - $retval['num'] = 0; - - // First get the list of parameters from the query - $buffer = ''; - $params = array(); - $fetching = false; - $depth = 0; - for ($i=0; $i<$parsed_query['len']; $i++) { - if ($parsed_query[$i]['type'] == 'alpha_reservedWord' && $parsed_query[$i]['data'] == $routine_type) { - $fetching = true; - } else if ($fetching == true && $parsed_query[$i]['type'] == 'punct_bracket_open_round') { - $depth++; - if ($depth > 1) { - $buffer .= $parsed_query[$i]['data'] . ' '; - } - } else if ($fetching == true && $parsed_query[$i]['type'] == 'punct_bracket_close_round') { - $depth--; - if ($depth > 0) { - $buffer .= $parsed_query[$i]['data'] . ' '; - } else { - break; - } - } else if ($parsed_query[$i]['type'] == 'punct_listsep' && $depth == 1) { - $params[] = $buffer; - $retval['num']++; - $buffer = ''; - } else if ($fetching == true && $depth > 0) { - $buffer .= $parsed_query[$i]['data'] . ' '; - } - } - if (! empty($buffer)) { - $params[] = $buffer; - $retval['num']++; - } - // Now parse each parameter individually - foreach ($params as $key => $value) { - list($retval['dir'][], - $retval['name'][], - $retval['type'][], - $retval['length'][], - $retval['opts'][]) = PMA_RTN_parseOneParameter($value); - } - // Since some indices of $retval may be still undefined, we fill - // them each with an empty array to avoid E_ALL errors in PHP. - foreach (array('dir', 'name', 'type', 'length', 'opts') as $key => $index) { - if (! isset($retval[$index])) { - $retval[$index] = array(); - } - } - - return $retval; -} // end PMA_RTN_parseAllParameters() - -/** - * This function looks through the contents of a parsed - * SHOW CREATE [PROCEDURE | FUNCTION] query and extracts - * information about the routine's definer. - * - * @param array $parsed_query Parsed query, returned by PMA_SQP_parse() - * - * @return string The definer of a routine. - * - */ -function PMA_RTN_parseRoutineDefiner($parsed_query) -{ - $retval = ''; - $fetching = false; - for ($i=0; $i<$parsed_query['len']; $i++) { - if ($parsed_query[$i]['type'] == 'alpha_reservedWord' && $parsed_query[$i]['data'] == 'DEFINER') { - $fetching = true; - } else if ($fetching == true && - ($parsed_query[$i]['type'] != 'quote_backtick' && substr($parsed_query[$i]['type'], 0, 5) != 'punct')) { - break; - } else if ($fetching == true && $parsed_query[$i]['type'] == 'quote_backtick') { - $retval .= PMA_unQuote($parsed_query[$i]['data']); - } else if ($fetching == true && $parsed_query[$i]['type'] == 'punct_user') { - $retval .= $parsed_query[$i]['data']; - } - } - return $retval; -} // end PMA_RTN_parseRoutineDefiner() - -/** - * This function will generate the values that are required to complete - * the "Edit routine" form given the name of a routine. - * - * @param string $db The database that the routine belogs to. - * @param string $name The name of the routine. - * @param bool $all Whether to return all data or just - * the info about parameters. - * - * @return array Data necessary to create the routine editor. - * - */ -function PMA_RTN_getRoutineDataFromName($db, $name, $all = true) -{ - global $param_directions, $param_sqldataaccess; - - $retval = array(); - - // Build and execute the query - $fields = "SPECIFIC_NAME, ROUTINE_TYPE, DTD_IDENTIFIER, " - . "ROUTINE_DEFINITION, IS_DETERMINISTIC, SQL_DATA_ACCESS, " - . "ROUTINE_COMMENT, SECURITY_TYPE"; - $where = "ROUTINE_SCHEMA='" . PMA_sqlAddSlashes($db) . "' " - . "AND SPECIFIC_NAME='" . PMA_sqlAddSlashes($name) . "'"; - $query = "SELECT $fields FROM INFORMATION_SCHEMA.ROUTINES WHERE $where;"; - - $routine = PMA_DBI_fetch_single_row($query); - - if (! $routine) { - return false; - } - - // Get required data - $retval['name'] = $routine['SPECIFIC_NAME']; - $retval['type'] = $routine['ROUTINE_TYPE']; - $parsed_query = PMA_SQP_parse( - PMA_DBI_get_definition( - $db, - $routine['ROUTINE_TYPE'], - $routine['SPECIFIC_NAME'] - ) - ); - $params = PMA_RTN_parseAllParameters($parsed_query, $routine['ROUTINE_TYPE']); - $retval['num_params'] = $params['num']; - $retval['param_dir'] = $params['dir']; - $retval['param_name'] = $params['name']; - $retval['param_type'] = $params['type']; - $retval['param_length'] = $params['length']; - $retval['param_opts_num'] = $params['opts']; - $retval['param_opts_text'] = $params['opts']; - - // Get extra data - if ($all) { - if ($retval['type'] == 'FUNCTION') { - $retval['type_toggle'] = 'PROCEDURE'; - } else { - $retval['type_toggle'] = 'FUNCTION'; - } - $retval['returntype'] = ''; - $retval['returnlength'] = ''; - $retval['returnopts_num'] = ''; - $retval['returnopts_text'] = ''; - if (! empty($routine['DTD_IDENTIFIER'])) { - if (strlen($routine['DTD_IDENTIFIER']) > 63) { - // If the DTD_IDENTIFIER string from INFORMATION_SCHEMA is - // at least 64 characters, then it may actually have been - // chopped because that column is a varchar(64), so we will - // parse the output of SHOW CREATE query to get accurate - // information about the return variable. - $dtd = ''; - $fetching = false; - for ($i=0; $i<$parsed_query['len']; $i++) { - if ($parsed_query[$i]['type'] == 'alpha_reservedWord' - && strtoupper($parsed_query[$i]['data']) == 'RETURNS') { - $fetching = true; - } else if ($fetching == true - && $parsed_query[$i]['type'] == 'alpha_reservedWord') { - // We will not be looking for options such as UNSIGNED - // or ZEROFILL because there is no way that a numeric - // field's DTD_IDENTIFIER can be longer than 64 - // characters. We can safely assume that the return - // datatype is either ENUM or SET, so we only look - // for CHARSET. - $word = strtoupper($parsed_query[$i]['data']); - if ($word == 'CHARSET' - && ($parsed_query[$i+1]['type'] == 'alpha_charset' - || $parsed_query[$i+1]['type'] == 'alpha_identifier')) { - $dtd .= $word . ' ' . $parsed_query[$i+1]['data']; - } - break; - } else if ($fetching == true) { - $dtd .= $parsed_query[$i]['data'] . ' '; - } - } - $routine['DTD_IDENTIFIER'] = $dtd; - } - $returnparam = PMA_RTN_parseOneParameter($routine['DTD_IDENTIFIER']); - $retval['returntype'] = $returnparam[2]; - $retval['returnlength'] = $returnparam[3]; - $retval['returnopts_num'] = $returnparam[4]; - $retval['returnopts_text'] = $returnparam[4]; - } - $retval['definer'] = PMA_RTN_parseRoutineDefiner($parsed_query); - $retval['definition'] = $routine['ROUTINE_DEFINITION']; - $retval['isdeterministic'] = ''; - if ($routine['IS_DETERMINISTIC'] == 'YES') { - $retval['isdeterministic'] = " checked='checked'"; - } - $retval['securitytype_definer'] = ''; - $retval['securitytype_invoker'] = ''; - if ($routine['SECURITY_TYPE'] == 'DEFINER') { - $retval['securitytype_definer'] = " selected='selected'"; - } else if ($routine['SECURITY_TYPE'] == 'INVOKER') { - $retval['securitytype_invoker'] = " selected='selected'"; - } - $retval['sqldataaccess'] = $routine['SQL_DATA_ACCESS']; - $retval['comment'] = $routine['ROUTINE_COMMENT']; - } - - return $retval; -} // PMA_RTN_getRoutineDataFromName() - -/** - * This function will generate the values that are required to complete the "Add new routine" form - * It is especially necessary to handle the 'Add another parameter', 'Remove last parameter' - * and 'Change routine type' functionalities when JS is disabled. - * - * @return array Data necessary to create the routine editor. - * - */ -function PMA_RTN_getRoutineDataFromRequest() -{ - global $_REQUEST, $param_directions, $param_sqldataaccess; - - $retval = array(); - $retval['name'] = ''; - if (isset($_REQUEST['routine_name'])) { - $retval['name'] = $_REQUEST['routine_name']; - } - $retval['original_name'] = ''; - if (isset($_REQUEST['routine_original_name'])) { - $retval['original_name'] = $_REQUEST['routine_original_name']; - } - $retval['type'] = 'PROCEDURE'; - $retval['type_toggle'] = 'FUNCTION'; - if (isset($_REQUEST['routine_type']) && $_REQUEST['routine_type'] == 'FUNCTION') { - $retval['type'] = 'FUNCTION'; - $retval['type_toggle'] = 'PROCEDURE'; - } - $retval['original_type'] = 'PROCEDURE'; - if (isset($_REQUEST['routine_original_type']) && $_REQUEST['routine_original_type'] == 'FUNCTION') { - $retval['original_type'] = 'FUNCTION'; - } - $retval['num_params'] = 0; - $retval['param_dir'] = array(); - $retval['param_name'] = array(); - $retval['param_type'] = array(); - $retval['param_length'] = array(); - $retval['param_opts_num'] = array(); - $retval['param_opts_text'] = array(); - if (isset($_REQUEST['routine_param_name']) - && isset($_REQUEST['routine_param_type']) - && isset($_REQUEST['routine_param_length']) - && isset($_REQUEST['routine_param_opts_num']) - && isset($_REQUEST['routine_param_opts_text']) - && is_array($_REQUEST['routine_param_name']) - && is_array($_REQUEST['routine_param_type']) - && is_array($_REQUEST['routine_param_length']) - && is_array($_REQUEST['routine_param_opts_num']) - && is_array($_REQUEST['routine_param_opts_text'])) { - - if ($_REQUEST['routine_type'] == 'PROCEDURE') { - $temp_num_params = 0; - $retval['param_dir'] = $_REQUEST['routine_param_dir']; - foreach ($retval['param_dir'] as $key => $value) { - if (! in_array($value, $param_directions, true)) { - $retval['param_dir'][$key] = ''; - } - $retval['num_params']++; - } - if ($temp_num_params > $retval['num_params']) { - $retval['num_params'] = $temp_num_params; - } - } - $temp_num_params = 0; - $retval['param_name'] = $_REQUEST['routine_param_name']; - foreach ($retval['param_name'] as $key => $value) { - $retval['param_name'][$key] = $value; - $temp_num_params++; - } - if ($temp_num_params > $retval['num_params']) { - $retval['num_params'] = $temp_num_params; - } - $temp_num_params = 0; - $retval['param_type'] = $_REQUEST['routine_param_type']; - foreach ($retval['param_type'] as $key => $value) { - if (! in_array($value, PMA_getSupportedDatatypes(), true)) { - $retval['param_type'][$key] = ''; - } - $temp_num_params++; - } - if ($temp_num_params > $retval['num_params']) { - $retval['num_params'] = $temp_num_params; - } - $temp_num_params = 0; - $retval['param_length'] = $_REQUEST['routine_param_length']; - foreach ($retval['param_length'] as $key => $value) { - $retval['param_length'][$key] = $value; - $temp_num_params++; - } - if ($temp_num_params > $retval['num_params']) { - $retval['num_params'] = $temp_num_params; - } - $temp_num_params = 0; - $retval['param_opts_num'] = $_REQUEST['routine_param_opts_num']; - foreach ($retval['param_opts_num'] as $key => $value) { - $retval['param_opts_num'][$key] = $value; - $temp_num_params++; - } - if ($temp_num_params > $retval['num_params']) { - $retval['num_params'] = $temp_num_params; - } - $temp_num_params = 0; - $retval['param_opts_text'] = $_REQUEST['routine_param_opts_text']; - foreach ($retval['param_opts_text'] as $key => $value) { - $retval['param_opts_text'][$key] = $value; - $temp_num_params++; - } - if ($temp_num_params > $retval['num_params']) { - $retval['num_params'] = $temp_num_params; - } - } - $retval['returntype'] = ''; - if (isset($_REQUEST['routine_returntype']) && in_array($_REQUEST['routine_returntype'], PMA_getSupportedDatatypes(), true)) { - $retval['returntype'] = $_REQUEST['routine_returntype']; - } - $retval['returnlength'] = ''; - if (isset($_REQUEST['routine_returnlength'])) { - $retval['returnlength'] = $_REQUEST['routine_returnlength']; - } - $retval['returnopts_num'] = ''; - if (isset($_REQUEST['routine_returnopts_num'])) { - $retval['returnopts_num'] = $_REQUEST['routine_returnopts_num']; - } - $retval['returnopts_text'] = ''; - if (isset($_REQUEST['routine_returnopts_text'])) { - $retval['returnopts_text'] = $_REQUEST['routine_returnopts_text']; - } - $retval['definition'] = ''; - if (isset($_REQUEST['routine_definition'])) { - $retval['definition'] = $_REQUEST['routine_definition']; - } - $retval['isdeterministic'] = ''; - if (isset($_REQUEST['routine_isdeterministic']) && strtolower($_REQUEST['routine_isdeterministic']) == 'on') { - $retval['isdeterministic'] = " checked='checked'"; - } - $retval['definer'] = ''; - if (isset($_REQUEST['routine_definer'])) { - $retval['definer'] = $_REQUEST['routine_definer']; - } - $retval['securitytype_definer'] = ''; - $retval['securitytype_invoker'] = ''; - if (isset($_REQUEST['routine_securitytype'])) { - if ($_REQUEST['routine_securitytype'] === 'DEFINER') { - $retval['securitytype_definer'] = " selected='selected'"; - } else if ($_REQUEST['routine_securitytype'] === 'INVOKER') { - $retval['securitytype_invoker'] = " selected='selected'"; - } - } - $retval['sqldataaccess'] = ''; - if (isset($_REQUEST['routine_sqldataaccess']) && in_array($_REQUEST['routine_sqldataaccess'], $param_sqldataaccess, true)) { - $retval['sqldataaccess'] = $_REQUEST['routine_sqldataaccess']; - } - $retval['comment'] = ''; - if (isset($_REQUEST['routine_comment'])) { - $retval['comment'] = $_REQUEST['routine_comment']; - } - - return $retval; -} // end function PMA_RTN_getRoutineDataFromRequest() - -/** - * Creates one row for the parameter table used in the routine editor. - * - * @param array $routine Data for the routine returned by - * PMA_RTN_getRoutineDataFromRequest() or - * PMA_RTN_getRoutineDataFromName() - * @param mixed $index Either a numeric index of the row being processed - * or NULL to create a template row for AJAX request - * @param string $class Class used to hide the direction column, if the - * row is for a stored function. - * - * @return string HTML code of one row of parameter table for the routine editor. - * - */ -function PMA_RTN_getParameterRow($routine = array(), $index = null, $class = '') -{ - global $param_directions, $param_opts_num, $titles; - - if ($index === null) { - // template row for AJAX request - $i = 0; - $index = '%s'; - $drop_class = ''; - $routine = array( - 'param_dir' => array(0 => ''), - 'param_name' => array(0 => ''), - 'param_type' => array(0 => ''), - 'param_length' => array(0 => ''), - 'param_opts_num' => array(0 => ''), - 'param_opts_text' => array(0 => '') - ); - } else if (! empty($routine)) { - // regular row for routine editor - $drop_class = ' hide'; - $i = $index; - } else { - // No input data. This shouldn't happen, - // but better be safe than sorry. - return ''; - } - - // Create the output - $retval = ""; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " $value) { - $selected = ""; - if (! empty($routine['param_opts_num'][$i]) && $routine['param_opts_num'][$i] == $value) { - $selected = " selected='selected'"; - } - $retval .= "$value"; - } - $retval .= "\n \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " {$titles['Drop']}\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - - return $retval; -} // end PMA_RTN_getParameterRow() - -/** - * Displays a form used to add/edit a routine - * - * @param string $mode If the editor will be used edit a routine - * or add a new one: 'edit' or 'add'. - * @param string $operation If the editor was previously invoked with - * JS turned off, this will hold the name of - * the current operation: 'add', remove', 'change' - * @param array $routine Data for the routine returned by - * PMA_RTN_getRoutineDataFromRequest() or - * PMA_RTN_getRoutineDataFromName() - * @param array $errors If the editor was already invoked and there - * has been an error while processing the request - * this array will hold the errors. - * @param bool $is_ajax True, if called from an ajax request - * - * @return string HTML code for the routine editor. - * - */ -function PMA_RTN_getEditorForm($mode, $operation, $routine, $errors, $is_ajax) { - global $db, $titles, $param_directions, $param_sqldataaccess, $param_opts_num; - - // Escape special characters - $need_escape = array( - 'original_name', - 'name', - 'returnlength', - 'definition', - 'definer', - 'comment' - ); - foreach($need_escape as $key => $index) { - $routine[$index] = htmlentities($routine[$index], ENT_QUOTES); - } - for ($i=0; $i<$routine['num_params']; $i++) { - $routine['param_name'][$i] = htmlentities($routine['param_name'][$i], ENT_QUOTES); - $routine['param_length'][$i] = htmlentities($routine['param_length'][$i], ENT_QUOTES); - } - - // Handle some logic first - if ($operation == 'change') { - if ($routine['type'] == 'PROCEDURE') { - $routine['type'] = 'FUNCTION'; - $routine['type_toggle'] = 'PROCEDURE'; - } else { - $routine['type'] = 'PROCEDURE'; - $routine['type_toggle'] = 'FUNCTION'; - } - } else if ($operation == 'add' || ($routine['num_params'] == 0 && $mode == 'add' && ! $errors)) { - $routine['param_dir'][] = ''; - $routine['param_name'][] = ''; - $routine['param_type'][] = ''; - $routine['param_length'][] = ''; - $routine['param_opts_num'][] = ''; - $routine['param_opts_text'][] = ''; - $routine['num_params']++; - } else if ($operation == 'remove') { - unset($routine['param_dir'][$routine['num_params']-1]); - unset($routine['param_name'][$routine['num_params']-1]); - unset($routine['param_type'][$routine['num_params']-1]); - unset($routine['param_length'][$routine['num_params']-1]); - unset($routine['param_opts_num'][$routine['num_params']-1]); - unset($routine['param_opts_text'][$routine['num_params']-1]); - $routine['num_params']--; - } - $disable_remove_parameter = ''; - if (! $routine['num_params']) { - $disable_remove_parameter = " color: gray;' disabled='disabled"; - } - $original_routine = ''; - if ($mode == 'edit') { - $original_routine = "\n" - . "\n"; - } - $isfunction_class = ''; - $isprocedure_class = ''; - $isfunction_select = ''; - $isprocedure_select = ''; - if ($routine['type'] == 'PROCEDURE') { - $isfunction_class = ' hide'; - $isprocedure_select = " selected='selected'"; - } else { - $isprocedure_class = ' hide'; - $isfunction_select = " selected='selected'"; - } - - // Create the output - $retval = ""; - $retval .= "\n\n"; - $retval .= "
\n"; - $retval .= "\n"; - $retval .= $original_routine; - $retval .= PMA_generate_common_hidden_inputs($db) . "\n"; - $retval .= "
\n"; - $retval .= "" . __('Details') . "\n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - // parameter handling end - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "\n"; - $retval .= "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - return $retval; -} // end PMA_RTN_getRowForRoutinesList() - -/** - * Creates a list of available routines for the specified database - * - * @return string An HTML snippet with the list of routines. - * - */ -function PMA_RTN_getRoutinesList() -{ - global $db; - - /** - * Get the routines - */ - $columns = "`SPECIFIC_NAME`, `ROUTINE_NAME`, `ROUTINE_TYPE`, `DTD_IDENTIFIER`, `ROUTINE_DEFINITION`"; - $where = "ROUTINE_SCHEMA='" . PMA_sqlAddSlashes($db) . "'"; - $routines = PMA_DBI_fetch_result("SELECT $columns FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE $where;"); - /** - * Conditional classes switch the list on or off - */ - $class1 = 'hide'; - $class2 = ''; - if (! $routines) { - $class1 = ''; - $class2 = ' hide'; - } - - /** - * Generate output - */ - $retval = ""; - $retval .= "\n\n\n\n"; - $retval .= "\n"; - $retval .= "
\n"; - $retval .= " " . __('Routines') . "\n"; - $retval .= "
\n"; - $retval .= " " . __('There are no routines to display.') . "\n"; - $retval .= "
\n"; - $retval .= "
" . __('Routine name') . "
" . __('Type') . "\n"; - if ($is_ajax) { - $retval .= " \n"; - } else { - $retval .= " \n"; - $retval .= "
\n"; - $retval .= " {$routine['type']}\n"; - $retval .= "
\n"; - $retval .= " \n"; - } - $retval .= "
" . __('Parameters') . "\n"; - // parameter handling start - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " "; - for ($i=0; $i<$routine['num_params']; $i++) { // each parameter - $retval .= PMA_RTN_getParameterRow($routine, $i, $isprocedure_class); - } - $retval .= "
" . __('Direction') . "" . __('Name') . "" . __('Type') . "" . __('Length/Values') . "" . __('Options') . " 
\n"; - $retval .= "
 \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "
" . __('Return type') . "
" . __('Return length/values') . "\n"; - $retval .= "
\n"; - $retval .= PMA_generateCharsetDropdownBox(PMA_CSDROPDOWN_CHARSET, - "routine_returnopts_text", - null, - $routine['returnopts_text']) . "\n"; - $retval .= "
\n"; - $retval .= "
" . __('Definition') . "
" . __('Is deterministic') . "
" . __('Definer') . "\n"; - $retval .= "
" . __('SQL data access') . "
" . __('Comment') . "\n"; - $retval .= "\n"; - } - $retval .= "\n\n"; - $retval .= "\n\n"; - - return $retval; -} // end PMA_RTN_getEditorForm() - -/** - * Creates the HTML code that shows the routine execution dialog. - * - * @param array $routine Data for the routine returned by - * PMA_RTN_getRoutineDataFromName() - * @param bool $is_ajax True, if called from an ajax request - * - * @return string HTML code for the routine execution dialog. - * - */ -function PMA_RTN_getExecuteForm($routine, $is_ajax) -{ - global $db, $cfg; - - // Escape special characters - $routine['name'] = htmlentities($routine['name'], ENT_QUOTES); - for ($i=0; $i<$routine['num_params']; $i++) { - $routine['param_name'][$i] = htmlentities($routine['param_name'][$i], ENT_QUOTES); - } - - // Create the output - $retval = ""; - $retval .= "\n\n"; - $retval .= "
\n"; - $retval .= "\n"; - $retval .= PMA_generate_common_hidden_inputs($db) . "\n"; - $retval .= "
\n"; - if ($is_ajax != true) { - $retval .= "{$routine['name']}\n"; - $retval .= "\n"; - $retval .= "\n"; - } else { - $retval .= "" . __('Routine parameters') . "\n"; - $retval .= "
\n"; - $retval .= __('Routine parameters'); - $retval .= "
\n"; - } - $retval .= "\n"; - $retval .= "\n"; - $retval .= "\n"; - if ($cfg['ShowFunctionFields']) { - $retval .= "\n"; - } - $retval .= "\n"; - $retval .= "\n"; - for ($i=0; $i<$routine['num_params']; $i++) { // Each parameter - if ($routine['type'] == 'PROCEDURE' && $routine['param_dir'][$i] == 'OUT') { - continue; - } - $rowclass = ($i % 2 == 0) ? 'even' : 'odd'; - $retval .= "\n\n"; - $retval .= "\n"; - $retval .= "\n"; - if ($cfg['ShowFunctionFields']) { - $retval .= "\n"; - } - // Append a class to date/time fields so that - // jQuery can attach a datepicker to them - $class = ''; - if (in_array($routine['param_type'][$i], array('DATETIME', 'TIMESTAMP'))) { - $class = 'datetimefield'; - } else if ($routine['param_type'][$i] == 'DATE') { - $class = 'datefield'; - } - $retval .= "\n"; - $retval .= "\n"; - } - $retval .= "\n
" . __('Name') . "" . __('Type') . "" . __('Function') . "" . __('Value') . "
{$routine['param_name'][$i]}{$routine['param_type'][$i]}\n"; - // Get a list of data types that are not yet supported. - $no_support_types = PMA_unsupportedDatatypes(); - if (stristr($routine['param_type'][$i], 'enum') - || stristr($routine['param_type'][$i], 'set') - || in_array(strtolower($routine['param_type'][$i]), $no_support_types)) { - $retval .= "--\n"; - } else { - $field = array( - 'True_Type' => strtolower($routine['param_type'][$i]), - 'Type' => '', - 'Key' => '', - 'Field' => '', - 'Default' => '', - 'first_timestamp' => false - ); - $retval .= ""; - } - $retval .= "\n"; - if (in_array($routine['param_type'][$i], array('ENUM', 'SET'))) { - $tokens = PMA_SQP_parse($routine['param_length'][$i]); - if ($routine['param_type'][$i] == 'ENUM') { - $input_type = 'radio'; - } else { - $input_type = 'checkbox'; - } - for ($j=0; $j<$tokens['len']; $j++) { - if ($tokens[$j]['type'] != 'punct_listsep') { - $tokens[$j]['data'] = htmlentities(PMA_unquote($tokens[$j]['data']), ENT_QUOTES); - $retval .= "" - . "{$tokens[$j]['data']}
\n"; - } - } - } else if (in_array(strtolower($routine['param_type'][$i]), $no_support_types)) { - $retval .= "\n"; - } else { - $retval .= "\n"; - } - $retval .= "
\n"; - if ($is_ajax != true) { - $retval .= "
\n\n"; - $retval .= "
\n"; - $retval .= " \n"; - $retval .= "
\n"; - } else { - $retval .= ""; - $retval .= ""; - } - $retval .= "
\n\n"; - $retval .= "\n\n"; - - return $retval; -} // end PMA_RTN_getExecuteForm() - -/** - * Composes the query necessary to create a routine from an HTTP request. - * - * @return string The CREATE [ROUTINE | PROCEDURE] query. - * - */ -function PMA_RTN_getQueryFromRequest() { - global $_REQUEST, $cfg, $routine_errors, $param_sqldataaccess; - - $query = 'CREATE '; - if (! empty($_REQUEST['routine_definer']) && strpos($_REQUEST['routine_definer'], '@') !== false) { - $arr = explode('@', $_REQUEST['routine_definer']); - $query .= 'DEFINER=' . PMA_backquote($arr[0]) . '@' . PMA_backquote($arr[1]) . ' '; - } - if ($_REQUEST['routine_type'] == 'FUNCTION' || $_REQUEST['routine_type'] == 'PROCEDURE') { - $query .= $_REQUEST['routine_type'] . ' '; - } else { - $routine_errors[] = sprintf(__('Invalid routine type: "%s"'), htmlspecialchars($_REQUEST['routine_type'])); - } - if (! empty($_REQUEST['routine_name'])) { - $query .= PMA_backquote($_REQUEST['routine_name']) . ' '; - } else { - $routine_errors[] = __('You must provide a routine name'); - } - $params = ''; - $warned_about_dir = false; - $warned_about_name = false; - $warned_about_length = false; - if ( ! empty($_REQUEST['routine_param_name']) && ! empty($_REQUEST['routine_param_type']) - && ! empty($_REQUEST['routine_param_length']) && is_array($_REQUEST['routine_param_name']) - && is_array($_REQUEST['routine_param_type']) && is_array($_REQUEST['routine_param_length'])) { - - for ($i=0; $i' . $titles['Edit'] . ''; - } - if ($routine['ROUTINE_DEFINITION'] !== NULL && PMA_currentUserHasPrivilege('EXECUTE', $db)) { - // Check if he routine has any input parameters. If it does, - // we will show a dialog to get values for these parameters, - // otherwise we can execute it directly. - $routine_details = PMA_RTN_getRoutineDataFromName($db, $routine['SPECIFIC_NAME'], false); - if ($routine !== false) { - $execute_action = 'execute_routine'; - for ($i=0; $i<$routine_details['num_params']; $i++) { - if ($routine_details['type'] == 'PROCEDURE' && $routine_details['param_dir'][$i] == 'OUT') { - continue; - } - $execute_action = 'execute_dialog'; - break; - } - $execlink = '' . $titles['Execute'] . ''; - } - } - if ($routine['ROUTINE_DEFINITION'] !== NULL) { - $exprlink = '' . $titles['Export'] . ''; - } - if (PMA_currentUserHasPrivilege('ALTER ROUTINE', $db)) { - $droplink = '' . $titles['Drop'] . ''; - } - // Display a row of data - $retval = "
\n"; - $retval .= " $sql_drop\n"; - $retval .= " " . htmlspecialchars($routine['ROUTINE_NAME']) . "\n"; - $retval .= " $editlink$execlink$exprlink$droplink{$routine['ROUTINE_TYPE']}" . htmlspecialchars($routine['DTD_IDENTIFIER']) . "
\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $ct = 0; - // Display each routine - foreach ($routines as $routine) { - $retval .= PMA_RTN_getRowForRoutinesList($routine, $ct); - $ct++; - } - $retval .= "
" . __('Name') . "" . __('Action') . "" . __('Type') . "" . __('Return type') . "
\n"; - $retval .= "
\n"; - $retval .= "\n\n"; - - return $retval; -} // end PMA_RTN_getRoutinesList() - -/** - * Creates a fieldset for adding a new routine, if the user has the privileges. - * - * @return string An HTML snippet with the link to add a new routine. - * - */ -function PMA_RTN_getAddRoutineLink() -{ - global $db, $url_query, $ajax_class; - - $retval = ""; - $retval .= "\n"; - $retval .= "
\n"; - if (PMA_currentUserHasPrivilege('CREATE ROUTINE', $db)) { - $retval .= "\n"; - $retval .= PMA_getIcon('b_routine_add.png') . "\n"; - $retval .= __('Add routine') . "\n"; - } else { - $retval .= PMA_getIcon('b_routine_add.png') . "\n"; - $retval .= __('You do not have the necessary privileges to create a new routine') . "\n"; - } - $retval .= PMA_showMySQLDocu('SQL-Syntax', 'CREATE_PROCEDURE') . "\n"; - $retval .= "
\n"; - $retval .= "\n\n"; - - return $retval; -} // end PMA_RTN_getAddRoutineLink() - -?> diff --git a/libraries/display_triggers.inc.php b/libraries/display_triggers.inc.php deleted file mode 100644 index fcadfbaa57..0000000000 --- a/libraries/display_triggers.inc.php +++ /dev/null @@ -1,123 +0,0 @@ -' . $trigger['create'] . ''; - if (! empty($_REQUEST['ajax_request'])) { - $extra_data = array('title' => sprintf(__('Export of trigger %s'), $trigger_name)); - PMA_ajaxResponse($create_trig, true, $extra_data); - } else { - echo '
' . "\n" - . ' ' . sprintf(__('Export of trigger "%s"'), $trigger_name) . '' . "\n" - . $create_trig - . '
'; - } - } - } - if (! $success) { - $response = __('Error in Processing Request') . ' : ' - . sprintf(__('No trigger with name %s found'), $event_name); - $response = PMA_message::error($response); - if (! empty($_REQUEST['ajax_request'])) { - PMA_ajaxResponse($response, false); - } else { - $response->display(); - } - } -} - -/** - * Display a list of available triggers - */ -echo "\n\n\n\n"; -echo '
' . "\n"; -echo ' ' . __('Triggers') . '' . "\n"; -if (! $triggers) { - echo __('There are no triggers to display.'); -} else { - echo '
' . __('There are no triggers to display.') . '
'; - echo '' . "\n"; - - // Print table header - echo "\n\n"; - if (empty($table)) { - // if we don't have a table name, we will be showing the per-database list. - // so we must specify which table each trigger belongs to - echo "\n"; - } - echo "\n"; - echo "\n"; - echo "\n"; - echo ""; - - $ct=0; - $delimiter = '//'; - // Print table contents - foreach ($triggers as $trigger) { - $drop_and_create = $trigger['drop'] . $delimiter . "\n" . $trigger['create'] . "\n"; - $row = ($ct%2 == 0) ? 'even' : 'odd'; - $editlink = PMA_linkOrButton('tbl_sql.php?' . $url_query . '&sql_query=' - . urlencode($drop_and_create) . '&show_query=1&delimiter=' . urlencode($delimiter), $titles['Edit']); - $exprlink = '' . $titles['Export'] . ''; - $droplink = '' . $titles['Drop'] . ''; - - echo "\n"; - echo "\n"; - if (empty($table)) { - echo "\n"; - } - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - echo "\n"; - $ct++; - } - echo '
" . __('Name') . "" . __('Table') . "" . __('Action') . "" . __('Time') . "" . __('Event') . "
"; - echo "{$trigger['name']}"; - echo $trigger['table'] . "$editlink$exprlink$droplink{$trigger['action_timing']}{$trigger['event_manipulation']}
'; -} -echo '
'; - -/** - * Display the form for adding a new trigger - */ -echo '
' . "\n" - . ' ' . "\n" - . PMA_getIcon('b_trigger_add.png') . __('Add a trigger') . '' . "\n" - . '
' . "\n"; - -?> diff --git a/libraries/export/codegen.php b/libraries/export/codegen.php index bb4510a480..d60785c062 100644 --- a/libraries/export/codegen.php +++ b/libraries/export/codegen.php @@ -46,18 +46,6 @@ if (isset($plugin_list)) { * Set of functions used to build exports of tables */ -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) -{ - return true; -} - /** * Outputs export footer * @@ -85,8 +73,7 @@ function PMA_exportHeader() /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -99,8 +86,7 @@ function PMA_exportDBHeader($db) /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -111,10 +97,9 @@ function PMA_exportDBFooter($db) } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -127,12 +112,11 @@ function PMA_exportDBCreate($db) /** * Outputs the content of a table in NHibernate format * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data - * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/csv.php b/libraries/export/csv.php index 62b1537375..0240e9b396 100644 --- a/libraries/export/csv.php +++ b/libraries/export/csv.php @@ -35,17 +35,6 @@ if (isset($plugin_list)) { ); } else { -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return true; -} - /** * Outputs export footer * @@ -107,8 +96,7 @@ function PMA_exportHeader() { /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -120,8 +108,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -131,10 +118,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -146,12 +132,11 @@ function PMA_exportDBCreate($db) { /** * Outputs the content of a table in CSV format * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data - * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/htmlword.php b/libraries/export/htmlword.php index 420c919959..bc7c3df486 100644 --- a/libraries/export/htmlword.php +++ b/libraries/export/htmlword.php @@ -34,17 +34,6 @@ if (isset($plugin_list)) { ); } else { -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return true; -} - /** * Outputs export footer * @@ -80,8 +69,7 @@ xmlns="http://www.w3.org/TR/REC-html40"> /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -93,8 +81,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -104,10 +91,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -117,14 +103,13 @@ function PMA_exportDBCreate($db) { } /** - * Outputs the content of a table in CSV format - * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data + * Outputs the content of a table in HTML (Microsoft Word) format * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public @@ -182,7 +167,28 @@ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) return true; } -function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $dummy) +/** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column comments + * as comments in the structure; this is deprecated + * but the parameter is left here because export.php + * calls PMA_exportStructure() also for other export + * types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @return bool Whether it suceeded + * + * @access public + */ +function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $export_mode, $export_type) { global $cfgRelation; diff --git a/libraries/export/json.php b/libraries/export/json.php index 9c836e136f..86e2e89d31 100644 --- a/libraries/export/json.php +++ b/libraries/export/json.php @@ -34,19 +34,6 @@ if (isset($plugin_list)) { * Set of functions used to build exports of tables */ -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) -{ - PMA_exportOutputHandler('/* ' . $text . ' */' . $GLOBALS['crlf']); - return true; -} - /** * Outputs export footer * @@ -80,8 +67,7 @@ function PMA_exportHeader() /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -95,8 +81,7 @@ function PMA_exportDBHeader($db) /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -107,10 +92,9 @@ function PMA_exportDBFooter($db) } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -121,14 +105,13 @@ function PMA_exportDBCreate($db) } /** - * Outputs the content of a table in YAML format - * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data + * Outputs the content of a table in JSON format * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/latex.php b/libraries/export/latex.php index 04e6b18ecd..d3f233a958 100644 --- a/libraries/export/latex.php +++ b/libraries/export/latex.php @@ -100,17 +100,6 @@ function PMA_texEscape($string) { return $string; } -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return PMA_exportOutputHandler('% ' . $text . $GLOBALS['crlf']); -} - /** * Outputs export footer * @@ -143,7 +132,7 @@ function PMA_exportHeader() { } $head .= $crlf . '% ' . __('Generation Time') . ': ' . PMA_localisedDate() . $crlf - . '% ' . __('Server version') . ': ' . substr(PMA_MYSQL_INT_VERSION, 0, 1) . '.' . (int) substr(PMA_MYSQL_INT_VERSION, 1, 2) . '.' . (int) substr(PMA_MYSQL_INT_VERSION, 3) . $crlf + . '% ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . $crlf . '% ' . __('PHP Version') . ': ' . phpversion() . $crlf; return PMA_exportOutputHandler($head); } @@ -151,8 +140,7 @@ function PMA_exportHeader() { /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -168,8 +156,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -179,10 +166,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -194,12 +180,11 @@ function PMA_exportDBCreate($db) { /** * Outputs the content of a table in LaTeX table/sideways table environment * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data - * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public @@ -290,23 +275,27 @@ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) { } // end getTableLaTeX /** - * Returns $table's structure as LaTeX + * Outputs table's structure * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param boolean whether to include relation comments - * @param boolean whether to include column comments - * @param boolean whether to include mime comments - * @param string future feature: support view dependencies - * - * @return bool Whether it suceeded + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column comments + * as comments in the structure; this is deprecated + * but the parameter is left here because export.php + * calls PMA_exportStructure() also for other export + * types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @return bool Whether it suceeded * * @access public */ - // @@@ Table structure -function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $dummy) +function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $export_mode, $export_type) { global $cfgRelation; diff --git a/libraries/export/mediawiki.php b/libraries/export/mediawiki.php index 538c31c533..76c8b2a716 100644 --- a/libraries/export/mediawiki.php +++ b/libraries/export/mediawiki.php @@ -24,17 +24,6 @@ if (isset($plugin_list)) { ); } else { -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return true; -} - /** * Outputs export footer * @@ -60,8 +49,7 @@ function PMA_exportHeader() { /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -73,8 +61,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -84,10 +71,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -99,12 +85,11 @@ function PMA_exportDBCreate($db) { /** * Outputs the content of a table in MediaWiki format * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data - * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/ods.php b/libraries/export/ods.php index 699aa0fa2e..9d9ff1309b 100644 --- a/libraries/export/ods.php +++ b/libraries/export/ods.php @@ -33,17 +33,6 @@ if (isset($plugin_list)) { $GLOBALS['ods_buffer'] = ''; require_once './libraries/opendocument.lib.php'; -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return true; -} - /** * Outputs export footer * @@ -113,8 +102,7 @@ function PMA_exportHeader() { /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -126,8 +114,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -137,10 +124,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -150,14 +136,13 @@ function PMA_exportDBCreate($db) { } /** - * Outputs the content of a table in CSV format - * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data + * Outputs the content of a table in ODS format * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/odt.php b/libraries/export/odt.php index 81590f35ce..5baee50832 100644 --- a/libraries/export/odt.php +++ b/libraries/export/odt.php @@ -65,17 +65,6 @@ if (isset($plugin_list)) { $GLOBALS['odt_buffer'] = ''; require_once './libraries/opendocument.lib.php'; -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return true; -} - /** * Outputs export footer * @@ -111,8 +100,7 @@ function PMA_exportHeader() { /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -125,8 +113,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -136,10 +123,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -149,14 +135,13 @@ function PMA_exportDBCreate($db) { } /** - * Outputs the content of a table in CSV format - * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data + * Outputs the content of a table in ODT format * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public @@ -222,23 +207,27 @@ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) { } /** - * Returns $table's structure as Open Document Text + * Outputs table's structure * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param boolean whether to include relation comments - * @param boolean whether to include column comments - * @param boolean whether to include mime comments - * @param string future feature: support view dependencies - * - * @return bool Whether it suceeded + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column comments + * as comments in the structure; this is deprecated + * but the parameter is left here because export.php + * calls PMA_exportStructure() also for other export + * types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @return bool Whether it suceeded * * @access public */ - // @@@ Table structure -function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $dummy) +function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $export_mode, $export_type) { global $cfgRelation; diff --git a/libraries/export/pdf.php b/libraries/export/pdf.php index e864454b64..bb89fda34a 100644 --- a/libraries/export/pdf.php +++ b/libraries/export/pdf.php @@ -358,18 +358,6 @@ class PMA_PDF extends TCPDF $pdf = new PMA_PDF('L', 'pt', 'A3'); -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) -{ - return true; -} - /** * Finalize the pdf. * @@ -420,8 +408,7 @@ function PMA_exportHeader() /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -434,8 +421,7 @@ function PMA_exportDBHeader($db) /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -446,10 +432,9 @@ function PMA_exportDBFooter($db) } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -462,13 +447,11 @@ function PMA_exportDBCreate($db) /** * Outputs the content of a table in PDF format * - * @todo user-defined page orientation, paper size - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data - * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/php_array.php b/libraries/export/php_array.php index 66a0aa6070..1996e6fbfc 100644 --- a/libraries/export/php_array.php +++ b/libraries/export/php_array.php @@ -34,19 +34,6 @@ if (isset($plugin_list)) { * Set of functions used to build exports of tables */ -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) -{ - PMA_exportOutputHandler('// ' . $text . $GLOBALS['crlf']); - return true; -} - /** * Outputs export footer * @@ -81,8 +68,7 @@ function PMA_exportHeader() /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -96,8 +82,7 @@ function PMA_exportDBHeader($db) /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -108,10 +93,9 @@ function PMA_exportDBFooter($db) } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -122,14 +106,13 @@ function PMA_exportDBCreate($db) } /** - * Outputs the content of a table in YAML format - * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data + * Outputs the content of a table as a fragment of PHP code * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/sql.php b/libraries/export/sql.php index 37d3be1a00..ee37e0a6a4 100644 --- a/libraries/export/sql.php +++ b/libraries/export/sql.php @@ -297,9 +297,10 @@ if (! isset($sql_backquotes)) { /** * Exports routines (procedures and functions) * - * @param string $db + * @param string $db + * @return bool Whether it suceeded * - * @return bool Whether it suceeded + * @access public */ function PMA_exportRoutines($db) { global $crlf; @@ -357,9 +358,10 @@ function PMA_exportRoutines($db) { /** * Possibly outputs comment * - * @param string Text of comment - * + * @param string $text Text of comment * @return string The formatted comment + * + * @access private */ function PMA_exportComment($text = '') { @@ -375,10 +377,11 @@ function PMA_exportComment($text = '') * Possibly outputs CRLF * * @return string $crlf or nothing + * + * @access private */ function PMA_possibleCRLF() { - if (isset($GLOBALS['sql_include_comments']) && $GLOBALS['sql_include_comments']) { return $GLOBALS['crlf']; } else { @@ -457,7 +460,7 @@ function PMA_exportHeader() $head .= PMA_exportComment($host_string); $head .= PMA_exportComment(__('Generation Time') . ': ' . PMA_localisedDate()) - . PMA_exportComment(__('Server version') . ': ' . substr(PMA_MYSQL_INT_VERSION, 0, 1) . '.' . (int) substr(PMA_MYSQL_INT_VERSION, 1, 2) . '.' . (int) substr(PMA_MYSQL_INT_VERSION, 3)) + . PMA_exportComment(__('Server version') . ': ' . PMA_MYSQL_STR_VERSION) . PMA_exportComment(__('PHP Version') . ': ' . phpversion()) . PMA_possibleCRLF(); @@ -518,10 +521,9 @@ function PMA_exportHeader() } /** - * Outputs CREATE DATABASE database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -557,8 +559,7 @@ function PMA_exportDBCreate($db) /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -574,8 +575,7 @@ function PMA_exportDBHeader($db) /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -626,15 +626,13 @@ function PMA_exportDBFooter($db) return $result; } - /** * Returns a stand-in CREATE definition to resolve view dependencies * - * @param string the database name - * @param string the view name - * @param string the end of line sequence - * - * @return string resulting definition + * @param string $db the database name + * @param string $view the view name + * @param string $crlf the end of line sequence + * @return string resulting definition * * @access public */ @@ -662,20 +660,15 @@ function PMA_getTableDefStandIn($db, $view, $crlf) { /** * Returns $table's CREATE definition * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param boolean whether to include creation/update/check dates - * @param boolean whether to add semicolon and end-of-line at the end - * @param boolean whether we're handling view - * + * @param string $db the database name + * @param string $table the table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $show_dates whether to include creation/update/check dates + * @param bool $add_semicolon whether to add semicolon and end-of-line at the end + * @param bool $view whether we're handling a view * @return string resulting schema * - * @global boolean whether to add 'drop' statements or not - * @global boolean whether to use backquotes to allow the use of special - * characters in database, table and fields names or not - * * @access public */ function PMA_getTableDef($db, $table, $crlf, $error_url, $show_dates = false, $add_semicolon = true, $view = false) @@ -877,21 +870,19 @@ function PMA_getTableDef($db, $table, $crlf, $error_url, $show_dates = false, $a return $schema_create . ($add_semicolon ? ';' . $crlf : ''); } // end of the 'PMA_getTableDef()' function - /** * Returns $table's comments, relations etc. * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param boolean whether to include relation comments - * @param boolean whether to include mime comments - * + * @param string $db database name + * @param string $table table name + * @param string $crlf end of line sequence + * @param bool $do_relation whether to include relation comments + * @param bool $do_mime whether to include mime comments * @return string resulting comments * - * @access public + * @access private */ -function PMA_getTableComments($db, $table, $crlf, $do_relation = false, $do_mime = false) +function PMA_getTableComments($db, $table, $crlf, $do_relation = false, $do_mime = false) { global $cfgRelation; global $sql_backquotes; @@ -951,21 +942,21 @@ function PMA_getTableComments($db, $table, $crlf, $do_relation = false, $do_mim /** * Outputs table's structure * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param boolean whether to include relation comments - * @param boolean whether to include the pmadb-style column comments - * as comments in the structure; this is deprecated - * but the parameter is left here because export.php - * calls PMA_exportStructure() also for other export - * types which use this parameter - * @param boolean whether to include mime comments - * @param string 'stand_in', 'create_table', 'create_view' - * @param string 'server', 'database', 'table' - * - * @return bool Whether it suceeded + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $relation whether to include relation comments + * @param bool $comments whether to include the pmadb-style column comments + * as comments in the structure; this is deprecated + * but the parameter is left here because export.php + * calls PMA_exportStructure() also for other export + * types which use this parameter + * @param bool $mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @return bool Whether it suceeded * * @access public */ @@ -1027,26 +1018,16 @@ function PMA_exportStructure($db, $table, $crlf, $error_url, $relation = false, } /** - * Dispatches between the versions of 'getTableContent' to use depending - * on the php version - * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data + * Outputs the content of a table in SQL format * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * - * @global boolean whether to use backquotes to allow the use of special - * characters in database, table and fields names or not - * @global integer the number of records - * @global integer the current record position - * * @access public - * - * @see PMA_getTableContentFast(), PMA_getTableContentOld() - * */ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) { diff --git a/libraries/export/texytext.php b/libraries/export/texytext.php index 44b0eb4401..552a59a0b1 100644 --- a/libraries/export/texytext.php +++ b/libraries/export/texytext.php @@ -32,17 +32,6 @@ if (isset($plugin_list)) { ); } else { -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return true; -} - /** * Outputs export footer * @@ -68,8 +57,7 @@ function PMA_exportHeader() { /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -81,8 +69,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -92,10 +79,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -105,14 +91,13 @@ function PMA_exportDBCreate($db) { } /** - * Outputs the content of a table in CSV format - * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data + * Outputs the content of a table in Texy format * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public @@ -164,7 +149,28 @@ function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) return true; } -function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $dummy) +/** + * Outputs table's structure + * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param bool $do_relation whether to include relation comments + * @param bool $do_comments whether to include the pmadb-style column comments + * as comments in the structure; this is deprecated + * but the parameter is left here because export.php + * calls PMA_exportStructure() also for other export + * types which use this parameter + * @param bool $do_mime whether to include mime comments + * @param bool $dates whether to include creation/update/check dates + * @param string $export_mode 'create_table', 'triggers', 'create_view', 'stand_in' + * @param string $export_type 'server', 'database', 'table' + * @return bool Whether it suceeded + * + * @access public + */ +function PMA_exportStructure($db, $table, $crlf, $error_url, $do_relation = false, $do_comments = false, $do_mime = false, $dates = false, $export_mode, $export_type) { global $cfgRelation; diff --git a/libraries/export/xls.php b/libraries/export/xls.php index 2a1f2192a7..6116e2a2e1 100644 --- a/libraries/export/xls.php +++ b/libraries/export/xls.php @@ -36,17 +36,6 @@ set_include_path(get_include_path() . PATH_SEPARATOR . getcwd() . '/libraries/PH require_once './libraries/PHPExcel/PHPExcel.php'; require_once './libraries/PHPExcel/PHPExcel/Writer/Excel5.php'; -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return true; -} - /** * Outputs export footer * @@ -102,8 +91,7 @@ function PMA_exportHeader() { /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -117,8 +105,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -128,10 +115,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -143,12 +129,11 @@ function PMA_exportDBCreate($db) { /** * Outputs the content of a table in XLS format * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data - * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/xlsx.php b/libraries/export/xlsx.php index 487c2dfb59..758d98dffe 100644 --- a/libraries/export/xlsx.php +++ b/libraries/export/xlsx.php @@ -36,17 +36,6 @@ set_include_path(get_include_path() . PATH_SEPARATOR . getcwd() . '/libraries/PH require_once './libraries/PHPExcel/PHPExcel.php'; require_once './libraries/PHPExcel/PHPExcel/Writer/Excel2007.php'; -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return true; -} - /** * Outputs export footer * @@ -101,8 +90,7 @@ function PMA_exportHeader() { /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -116,8 +104,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -127,10 +114,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -142,12 +128,11 @@ function PMA_exportDBCreate($db) { /** * Outputs the content of a table in XLSX format * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data - * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/xml.php b/libraries/export/xml.php index ba1e4fa12f..26650513d2 100644 --- a/libraries/export/xml.php +++ b/libraries/export/xml.php @@ -48,17 +48,6 @@ if (isset($plugin_list)) { $plugin_list['xml']['options'][] = array('type' => 'end_group'); } else { -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) { - return PMA_exportOutputHandler('' . $GLOBALS['crlf']); -} - /** * Outputs export footer * @@ -108,7 +97,7 @@ function PMA_exportHeader() { } $head .= $crlf . '- ' . __('Generation Time') . ': ' . PMA_localisedDate() . $crlf - . '- ' . __('Server version') . ': ' . substr(PMA_MYSQL_INT_VERSION, 0, 1) . '.' . (int) substr(PMA_MYSQL_INT_VERSION, 1, 2) . '.' . (int) substr(PMA_MYSQL_INT_VERSION, 3) . $crlf + . '- ' . __('Server version') . ': ' . PMA_MYSQL_STR_VERSION . $crlf . '- ' . __('PHP Version') . ': ' . phpversion() . $crlf . '-->' . $crlf . $crlf; @@ -243,8 +232,7 @@ function PMA_exportHeader() { /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -270,8 +258,7 @@ function PMA_exportDBHeader($db) { /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -290,10 +277,9 @@ function PMA_exportDBFooter($db) { } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -302,16 +288,14 @@ function PMA_exportDBCreate($db) { return true; } - /** - * Outputs the content of a table - * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data + * Outputs the content of a table in XML format * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/export/yaml.php b/libraries/export/yaml.php index 8c3fad045d..017cae6d18 100644 --- a/libraries/export/yaml.php +++ b/libraries/export/yaml.php @@ -35,19 +35,6 @@ if (isset($plugin_list)) { * Set of functions used to build exports of tables */ -/** - * Outputs comment - * - * @param string Text of comment - * - * @return bool Whether it suceeded - */ -function PMA_exportComment($text) -{ - PMA_exportOutputHandler('# ' . $text . $GLOBALS['crlf']); - return true; -} - /** * Outputs export footer * @@ -77,8 +64,7 @@ function PMA_exportHeader() /** * Outputs database header * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -91,8 +77,7 @@ function PMA_exportDBHeader($db) /** * Outputs database footer * - * @param string Database name - * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -103,10 +88,9 @@ function PMA_exportDBFooter($db) } /** - * Outputs create database database - * - * @param string Database name + * Outputs CREATE DATABASE statement * + * @param string $db Database name * @return bool Whether it suceeded * * @access public @@ -119,12 +103,11 @@ function PMA_exportDBCreate($db) /** * Outputs the content of a table in YAML format * - * @param string the database name - * @param string the table name - * @param string the end of line sequence - * @param string the url to go back in case of error - * @param string SQL query for obtaining data - * + * @param string $db database name + * @param string $table table name + * @param string $crlf the end of line sequence + * @param string $error_url the url to go back in case of error + * @param string $sql_query SQL query for obtaining data * @return bool Whether it suceeded * * @access public diff --git a/libraries/rte/rte_events.lib.php b/libraries/rte/rte_events.lib.php new file mode 100644 index 0000000000..070dc20cf8 --- /dev/null +++ b/libraries/rte/rte_events.lib.php @@ -0,0 +1,567 @@ + __('Add event'), + 'docu' => 'EVENTS', + 'export' => __('Export of event %s'), + 'human' => __('event'), + 'no_create' => __('You do not have the necessary privileges to create a new event'), + 'not_found' => __('No event with name %1$s found in database %2$s'), + 'nothing' => __('There are no events to display.'), + 'title' => __('Events'), + ); + return isset($words[$index]) ? $words[$index] : ''; +} // end PMA_RTE_getWord() + +/** + * Main function for the events functionality + */ +function PMA_RTE_main() +{ + global $db; + + /** + * Process all requests + */ + PMA_EVN_handleEditor(); + PMA_EVN_handleExport(); + /** + * Display a list of available events + */ + $columns = "`EVENT_NAME`, `EVENT_TYPE`, `STATUS`"; + $where = "EVENT_SCHEMA='" . PMA_sqlAddSlashes($db) . "'"; + $query = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` " + . "WHERE $where ORDER BY `EVENT_NAME` ASC;"; + $items = PMA_DBI_fetch_result($query); + echo PMA_RTE_getList('event', $items); + /** + * Display a link for adding a new event, if + * the user has the privileges and a link to + * toggle the state of the event scheduler. + */ + echo PMA_EVN_getFooterLinks(); +} // end PMA_RTE_main() + +/** + * Handles editor requests for adding or editing an item + */ +function PMA_EVN_handleEditor() +{ + global $_REQUEST, $_POST, $errors, $db, $table; + + if (! empty($_REQUEST['editor_process_add']) + || ! empty($_REQUEST['editor_process_edit']) + ) { + $sql_query = ''; + + $item_query = PMA_EVN_getQueryFromRequest(); + + if (! count($errors)) { // set by PMA_RTN_getQueryFromRequest() + // Execute the created query + if (! empty($_REQUEST['editor_process_edit'])) { + // Backup the old trigger, in case something goes wrong + $create_item = PMA_DBI_get_definition( + $db, + 'EVENT', + $_REQUEST['item_original_name'] + ); + $drop_item = "DROP EVENT " . PMA_backquote($_REQUEST['item_original_name']) . ";\n"; + $result = PMA_DBI_try_query($drop_item); + if (! $result) { + $errors[] = sprintf(__('The following query has failed: "%s"'), $drop_item) . '
' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $result = PMA_DBI_try_query($item_query); + if (! $result) { + $errors[] = sprintf(__('The following query has failed: "%s"'), $item_query) . '
' + . __('MySQL said: ') . PMA_DBI_getError(null); + // We dropped the old item, but were unable to create the new one + // Try to restore the backup query + $result = PMA_DBI_try_query($create_item); + if (! $result) { + // OMG, this is really bad! We dropped the query, failed to create a new one + // and now even the backup query does not execute! + // This should not happen, but we better handle this just in case. + $errors[] = __('Sorry, we failed to restore the dropped event.') . '
' + . __('The backed up query was:') . "\"$create_item\"" . '
' + . __('MySQL said: ') . PMA_DBI_getError(null); + } + } else { + $message = PMA_Message::success(__('Event %1$s has been modified.')); + $message->addParam(PMA_backquote($_REQUEST['item_name'])); + $sql_query = $drop_item . $item_query; + } + } + } else { + // 'Add a new item' mode + $result = PMA_DBI_try_query($item_query); + if (! $result) { + $errors[] = sprintf(__('The following query has failed: "%s"'), $item_query) . '

' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $message = PMA_Message::success(__('Event %1$s has been created.')); + $message->addParam(PMA_backquote($_REQUEST['item_name'])); + $sql_query = $item_query; + } + } + } + + if (count($errors)) { + $message = PMA_Message::error(__('One or more errors have occured while processing your request:')); + $message->addString('
    '); + foreach ($errors as $num => $string) { + $message->addString('
  • ' . $string . '
  • '); + } + $message->addString('
'); + } + + $output = PMA_showMessage($message, $sql_query); + if ($GLOBALS['is_ajax_request']) { + $extra_data = array(); + if ($message->isSuccess()) { + $columns = "`EVENT_NAME`, `EVENT_TYPE`, `STATUS`"; + $where = "EVENT_SCHEMA='" . PMA_sqlAddSlashes($db) . "' " + . "AND EVENT_NAME='" . PMA_sqlAddSlashes($_REQUEST['item_name']) . "'"; + $query = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE $where;"; + $event = PMA_DBI_fetch_single_row($query); + $extra_data['name'] = htmlspecialchars(strtoupper($_REQUEST['item_name'])); + $extra_data['new_row'] = PMA_EVN_getRowForList($event); + $extra_data['insert'] = ! empty($event); + $response = $output; + } else { + $response = $message; + } + PMA_ajaxResponse($response, $message->isSuccess(), $extra_data); + } + } + /** + * Display a form used to add/edit a trigger, if necessary + */ + if (count($errors) || ( empty($_REQUEST['editor_process_add']) && empty($_REQUEST['editor_process_edit']) + && (! empty($_REQUEST['add_item']) || ! empty($_REQUEST['edit_item']) + || ! empty($_REQUEST['item_changetype']))) + ) { // FIXME: this must be simpler than that + $operation = ''; + if (! empty($_REQUEST['item_changetype'])) { + $operation = 'change'; + } + // Get the data for the form (if any) + if (! empty($_REQUEST['add_item'])) { + $title = __("Create event"); + $item = PMA_EVN_getDataFromRequest(); + $mode = 'add'; + } else if (! empty($_REQUEST['edit_item'])) { + $title = __("Edit event"); + if (! empty($_REQUEST['item_name']) + && empty($_REQUEST['editor_process_edit']) + && empty($_REQUEST['item_changetype']) + ) { + $item = PMA_EVN_getDataFromName($_REQUEST['item_name']); + if ($item !== false) { + $item['item_original_name'] = $item['item_name']; + } + } else { + $item = PMA_EVN_getDataFromRequest(); + } + $mode = 'edit'; + } + if ($item !== false) { + // Show form + $editor = PMA_EVN_getEditorForm($mode, $operation, $item); + if ($GLOBALS['is_ajax_request']) { + $extra_data = array('title' => $title); + PMA_ajaxResponse($editor, true, $extra_data); + } else { + echo "\n\n

$title

\n\n$editor"; + unset($_POST); + require './libraries/footer.inc.php'; + } + // exit; + } else { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_backquote($db)) + ); + $message = PMA_message::error($message); + if ($GLOBALS['is_ajax_request']) { + PMA_ajaxResponse($message, false); + } else { + $message->display(); + } + } + } +} // end PMA_EVN_handleEditor() + +/** + * This function will generate the values that are required to for the editor + * + * @return array Data necessary to create the editor. + */ +function PMA_EVN_getDataFromRequest() +{ + $retval = array(); + $indices = array('item_name', + 'item_original_name', + 'item_status', + 'item_execute_at', + 'item_interval_value', + 'item_interval_field', + 'item_starts', + 'item_ends', + 'item_definition', + 'item_preserve', + 'item_comment', + 'item_definer'); + foreach ($indices as $key => $index) { + $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : ''; + } + $retval['item_type'] = 'ONE TIME'; + $retval['item_type_toggle'] = 'RECURRING'; + if (isset($_REQUEST['item_type']) && $_REQUEST['item_type'] == 'RECURRING') { + $retval['item_type'] = 'RECURRING'; + $retval['item_type_toggle'] = 'ONE TIME'; + } + return $retval; +} // end PMA_EVN_getDataFromRequest() + +/** + * This function will generate the values that are required to complete + * the "Edit event" form given the name of a event. + * + * @param string $name The name of the event. + * + * @return array Data necessary to create the editor. + */ +function PMA_EVN_getDataFromName($name) +{ + global $db; + + $retval = array(); + $columns = "`EVENT_NAME`, `STATUS`, `EVENT_TYPE`, `EXECUTE_AT`, " + . "`INTERVAL_VALUE`, `INTERVAL_FIELD`, `STARTS`, `ENDS`, " + . "`EVENT_DEFINITION`, `ON_COMPLETION`, `DEFINER`, `EVENT_COMMENT`"; + $where = "EVENT_SCHEMA='" . PMA_sqlAddSlashes($db) . "' " + . "AND EVENT_NAME='" . PMA_sqlAddSlashes($name) . "'"; + $query = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE $where;"; + $item = PMA_DBI_fetch_single_row($query); + if (! $item) { + return false; + } + $retval['item_name'] = $item['EVENT_NAME']; + $retval['item_status'] = $item['STATUS']; + $retval['item_type'] = $item['EVENT_TYPE']; + if ($retval['item_type'] == 'RECURRING') { + $retval['item_type_toggle'] = 'ONE TIME'; + } else { + $retval['item_type_toggle'] = 'RECURRING'; + } + $retval['item_execute_at'] = $item['EXECUTE_AT']; + $retval['item_interval_value'] = $item['INTERVAL_VALUE']; + $retval['item_interval_field'] = $item['INTERVAL_FIELD']; + $retval['item_starts'] = $item['STARTS']; + $retval['item_ends'] = $item['ENDS']; + $retval['item_preserve'] = ''; + if ($item['ON_COMPLETION'] == 'PRESERVE') { + $retval['item_preserve'] = " checked='checked'"; + } + $retval['item_definition'] = $item['EVENT_DEFINITION']; + $retval['item_definer'] = $item['DEFINER']; + $retval['item_comment'] = $item['EVENT_COMMENT']; + + return $retval; +} // end PMA_EVN_getDataFromName() + +/** + * Displays a form used to add/edit an event + * + * @param string $mode If the editor will be used edit an event + * or add a new one: 'edit' or 'add'. + * @param string $operation If the editor was previously invoked with + * JS turned off, this will hold the name of + * the current operation + * @param array $item Data for the event returned by + * PMA_EVN_getDataFromRequest() or + * PMA_EVN_getDataFromName() + * + * @return string HTML code for the editor. + */ +function PMA_EVN_getEditorForm($mode, $operation, $item) +{ + global $db, $table, $titles, $event_status, $event_type, $event_interval; + + // Escape special characters + $need_escape = array( + 'item_original_name', + 'item_name', + 'item_type', + 'item_execute_at', + 'item_interval_value', + 'item_starts', + 'item_ends', + 'item_definition', + 'item_definer', + 'item_comment' + ); + foreach ($need_escape as $key => $index) { + $item[$index] = htmlentities($item[$index], ENT_QUOTES); + } + $original_data = ''; + if ($mode == 'edit') { + $original_data = "\n"; + } + // Handle some logic first + if ($operation == 'change') { + if ($item['item_type'] == 'RECURRING') { + $item['item_type'] = 'ONE TIME'; + $item['item_type_toggle'] = 'RECURRING'; + } else { + $item['item_type'] = 'RECURRING'; + $item['item_type_toggle'] = 'ONE TIME'; + } + } + if ($item['item_type'] == 'ONE TIME') { + $isrecurring_class = ' hide'; + $isonetime_class = ''; + } else { + $isrecurring_class = ''; + $isonetime_class = ' hide'; + } + // Create the output + $retval = ""; + $retval .= "\n\n"; + $retval .= "
\n"; + $retval .= "\n"; + $retval .= $original_data; + $retval .= PMA_generate_common_hidden_inputs($db, $table) . "\n"; + $retval .= "
\n"; + $retval .= "" . __('Details') . "\n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + + return $retval; +} // end PMA_RTN_getRowForList() + +/** + * Creates the contents for a row in the list of triggers + * + * @param array $trigger An array of routine data + * @param string $rowclass Empty or one of ['even'|'odd'] + * + * @return string HTML code of a cell for the list of triggers + */ +function PMA_TRI_getRowForList($trigger, $rowclass = '') +{ + global $ajax_class, $url_query, $db, $table, $titles; + + $retval = " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + + return $retval; +} // end PMA_TRI_getRowForList() + +/** + * Creates the contents for a row in the list of events + * + * @param array $event An array of routine data + * @param string $rowclass Empty or one of ['even'|'odd'] + * + * @return string HTML code of a cell for the list of events + */ +function PMA_EVN_getRowForList($event, $rowclass = '') +{ + global $ajax_class, $url_query, $db, $titles; + + $sql_drop = sprintf( + 'DROP EVENT IF EXISTS %s', + PMA_backquote($event['EVENT_NAME']) + ); + + $retval = " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + + return $retval; +} // end PMA_EVN_getRowForList() + +?> diff --git a/libraries/rte/rte_main.inc.php b/libraries/rte/rte_main.inc.php new file mode 100644 index 0000000000..deae1d273a --- /dev/null +++ b/libraries/rte/rte_main.inc.php @@ -0,0 +1,135 @@ + '', + 'edit' => '', + 'exec' => '', + 'drop' => '', + 'export' => ''); +if ($GLOBALS['cfg']['AjaxEnable']) { + $ajax_class = array('add' => 'class="ajax_add_anchor"', + 'edit' => 'class="ajax_edit_anchor"', + 'exec' => 'class="ajax_exec_anchor"', + 'drop' => 'class="ajax_drop_anchor"', + 'export' => 'class="ajax_export_anchor"'); +} + +/** + * Create labels for the list + */ +$titles = PMA_buildActionTitles(); + +/** + * Keep a list of errors that occured while + * processing an 'Add' or 'Edit' operation. + */ +$errors = array(); + +// Some definitions for triggers +$action_timings = array('BEFORE', + 'AFTER'); +$event_manipulations = array('INSERT', + 'UPDATE', + 'DELETE'); + +// Some definitions for routines +$param_directions = array('IN', + 'OUT', + 'INOUT'); +$param_opts_num = array('UNSIGNED', + 'ZEROFILL', + 'UNSIGNED ZEROFILL'); +$param_sqldataaccess = array('NO SQL', + 'CONTAINS SQL', + 'READS SQL DATA', + 'MODIFIES SQL DATA'); + +// Some definitions for events +$event_status = array( + 'query' => array('ENABLE', + 'DISABLE', + 'DISABLE ON SLAVE'), + 'display' => array('ENABLED', + 'DISABLED', + 'SLAVESIDE_DISABLED') + ); +$event_type = array('RECURRING', + 'ONE TIME'); +$event_interval = array('YEAR', + 'QUARTER', + 'MONTH', + 'DAY', + 'HOUR', + 'MINUTE', + 'WEEK', + 'SECOND', + 'YEAR_MONTH', + 'DAY_HOUR', + 'DAY_MINUTE', + 'DAY_SECOND', + 'HOUR_MINUTE', + 'HOUR_SECOND', + 'MINUTE_SECOND'); +/** + * The below function is defined in rte_routines.lib.php, + * rte_triggers.lib.php and rte_events.lib.php + * + * The appropriate function will now be called based on which one + * of these files was included earlier in the top-level folder + */ +PMA_RTE_main(); + +/** + * Display the footer, if necessary + */ +if ($GLOBALS['is_ajax_request'] != true) { + require './libraries/footer.inc.php'; +} + +?> diff --git a/libraries/rte/rte_routines.lib.php b/libraries/rte/rte_routines.lib.php new file mode 100644 index 0000000000..eb6ee4e93d --- /dev/null +++ b/libraries/rte/rte_routines.lib.php @@ -0,0 +1,1494 @@ + __('Add routine'), + 'docu' => 'STORED_ROUTINES', + 'export' => __('Export of routine %s'), + 'human' => __('routine'), + 'no_create' => __('You do not have the necessary privileges to create a new routine'), + 'not_found' => __('No routine with name %1$s found in database %2$s'), + 'nothing' => __('There are no routines to display.'), + 'title' => __('Routines'), + ); + return isset($words[$index]) ? $words[$index] : ''; +} // end PMA_RTE_getWord() + +/** + * Main function for the routines functionality + */ +function PMA_RTE_main() +{ + global $db; + + /** + * Process all requests + */ + PMA_RTN_handleEditor(); + PMA_RTN_handleExecute(); + PMA_RTN_handleExport(); + /** + * Display a list of available routines + */ + $columns = "`SPECIFIC_NAME`, `ROUTINE_NAME`, `ROUTINE_TYPE`, "; + $columns .= "`DTD_IDENTIFIER`, `ROUTINE_DEFINITION`"; + $where = "ROUTINE_SCHEMA='" . PMA_sqlAddSlashes($db) . "'"; + $items = PMA_DBI_fetch_result( + "SELECT $columns FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE $where;" + ); + echo PMA_RTE_getList('routine', $items); + /** + * Display the form for adding a new routine, if the user has the privileges. + */ + echo PMA_RTN_getFooterLinks(); + /** + * Display a warning for users with PHP's old "mysql" extension. + */ + if ($GLOBALS['cfg']['Server']['extension'] === 'mysql') { + trigger_error( + __('You are using PHP\'s deprecated \'mysql\' extension, ' + . 'which is not capable of handling multi queries. ' + . 'The execution of some stored routines may fail! ' + . 'Please use the improved \'mysqli\' extension to ' + . 'avoid any problems.'), + E_USER_WARNING + ); + } +} // end PMA_RTE_main() + +/** + * This function parses a string containing one parameter of a routine, + * as returned by PMA_RTN_parseAllParameters() and returns an array containing + * the information about this parameter. + * + * @param string $value A string containing one parameter of a routine + * + * @return array Parsed information about the input parameter + */ +function PMA_RTN_parseOneParameter($value) +{ + global $param_directions; + + $retval = array(0 => '', + 1 => '', + 2 => '', + 3 => '', + 4 => ''); + $parsed_param = PMA_SQP_parse($value); + $pos = 0; + if (in_array(strtoupper($parsed_param[$pos]['data']), $param_directions)) { + $retval[0] = strtoupper($parsed_param[0]['data']); + $pos++; + } + if ($parsed_param[$pos]['type'] == 'alpha_identifier' + || $parsed_param[$pos]['type'] == 'quote_backtick' + ) { + $retval[1] = PMA_unQuote($parsed_param[$pos]['data']); + $pos++; + } + $depth = 0; + $param_length = ''; + $param_opts = array(); + for ($i=$pos; $i<$parsed_param['len']; $i++) { + if (($parsed_param[$i]['type'] == 'alpha_columnType' + || $parsed_param[$i]['type'] == 'alpha_functionName') // "CHAR" seems to be mistaken for a function by the parser + && $depth == 0 + ) { + $retval[2] = strtoupper($parsed_param[$i]['data']); + } else if ($parsed_param[$i]['type'] == 'punct_bracket_open_round' && $depth == 0) { + $depth = 1; + } else if ($parsed_param[$i]['type'] == 'punct_bracket_close_round' && $depth == 1) { + $depth = 0; + } else if ($depth == 1) { + $param_length .= $parsed_param[$i]['data']; + } else if ($parsed_param[$i]['type'] == 'alpha_reservedWord' && strtoupper($parsed_param[$i]['data']) == 'CHARSET' && $depth == 0) { + if ($parsed_param[$i+1]['type'] == 'alpha_charset' || $parsed_param[$i+1]['type'] == 'alpha_identifier') { + $param_opts[] = strtolower($parsed_param[$i+1]['data']); + } + } else if ($parsed_param[$i]['type'] == 'alpha_columnAttrib' && $depth == 0) { + $param_opts[] = strtoupper($parsed_param[$i]['data']); + } + } + $retval[3] = $param_length; + sort($param_opts); + $retval[4] = implode(' ', $param_opts); + + return $retval; +} // end PMA_RTN_parseOneParameter() + +/** + * This function looks through the contents of a parsed + * SHOW CREATE [PROCEDURE | FUNCTION] query and extracts + * information about the routine's parameters. + * + * @param array $parsed_query Parsed query, returned by by PMA_SQP_parse() + * @param string $routine_type Routine type: 'PROCEDURE' or 'FUNCTION' + * + * @return array Information about the parameteres of a routine. + */ +function PMA_RTN_parseAllParameters($parsed_query, $routine_type) +{ + global $param_directions; + + $retval = array(); + $retval['num'] = 0; + + // First get the list of parameters from the query + $buffer = ''; + $params = array(); + $fetching = false; + $depth = 0; + for ($i=0; $i<$parsed_query['len']; $i++) { + if ($parsed_query[$i]['type'] == 'alpha_reservedWord' && $parsed_query[$i]['data'] == $routine_type) { + $fetching = true; + } else if ($fetching == true && $parsed_query[$i]['type'] == 'punct_bracket_open_round') { + $depth++; + if ($depth > 1) { + $buffer .= $parsed_query[$i]['data'] . ' '; + } + } else if ($fetching == true && $parsed_query[$i]['type'] == 'punct_bracket_close_round') { + $depth--; + if ($depth > 0) { + $buffer .= $parsed_query[$i]['data'] . ' '; + } else { + break; + } + } else if ($parsed_query[$i]['type'] == 'punct_listsep' && $depth == 1) { + $params[] = $buffer; + $retval['num']++; + $buffer = ''; + } else if ($fetching == true && $depth > 0) { + $buffer .= $parsed_query[$i]['data'] . ' '; + } + } + if (! empty($buffer)) { + $params[] = $buffer; + $retval['num']++; + } + // Now parse each parameter individually + foreach ($params as $key => $value) { + list($retval['dir'][], + $retval['name'][], + $retval['type'][], + $retval['length'][], + $retval['opts'][]) = PMA_RTN_parseOneParameter($value); + } + // Since some indices of $retval may be still undefined, we fill + // them each with an empty array to avoid E_ALL errors in PHP. + foreach (array('dir', 'name', 'type', 'length', 'opts') as $key => $index) { + if (! isset($retval[$index])) { + $retval[$index] = array(); + } + } + + return $retval; +} // end PMA_RTN_parseAllParameters() + +/** + * This function looks through the contents of a parsed + * SHOW CREATE [PROCEDURE | FUNCTION] query and extracts + * information about the routine's definer. + * + * @param array $parsed_query Parsed query, returned by PMA_SQP_parse() + * + * @return string The definer of a routine. + */ +function PMA_RTN_parseRoutineDefiner($parsed_query) +{ + $retval = ''; + $fetching = false; + for ($i=0; $i<$parsed_query['len']; $i++) { + if ($parsed_query[$i]['type'] == 'alpha_reservedWord' && $parsed_query[$i]['data'] == 'DEFINER') { + $fetching = true; + } else if ($fetching == true && ($parsed_query[$i]['type'] != 'quote_backtick' && substr($parsed_query[$i]['type'], 0, 5) != 'punct')) { + break; + } else if ($fetching == true && $parsed_query[$i]['type'] == 'quote_backtick') { + $retval .= PMA_unQuote($parsed_query[$i]['data']); + } else if ($fetching == true && $parsed_query[$i]['type'] == 'punct_user') { + $retval .= $parsed_query[$i]['data']; + } + } + return $retval; +} // end PMA_RTN_parseRoutineDefiner() + +/** + * Handles editor requests for adding or editing an item + */ +function PMA_RTN_handleEditor() +{ + global $_GET, $_POST, $_REQUEST, $GLOBALS, $db, $cfg, $errors; + + if (! empty($_REQUEST['editor_process_add']) + || ! empty($_REQUEST['editor_process_edit']) + ) { + /** + * Handle a request to create/edit a routine + */ + $sql_query = ''; + $routine_query = PMA_RTN_getQueryFromRequest(); + if (! count($errors)) { // set by PMA_RTN_getQueryFromRequest() + // Execute the created query + if (! empty($_REQUEST['editor_process_edit'])) { + if (! in_array($_REQUEST['item_original_type'], array('PROCEDURE', 'FUNCTION'))) { + $errors[] = sprintf(__('Invalid routine type: "%s"'), htmlspecialchars($_REQUEST['item_original_type'])); + } else { + // Backup the old routine, in case something goes wrong + $create_routine = PMA_DBI_get_definition($db, $_REQUEST['item_original_type'], $_REQUEST['item_original_name']); + $drop_routine = "DROP {$_REQUEST['item_original_type']} " . PMA_backquote($_REQUEST['item_original_name']) . ";\n"; + $result = PMA_DBI_try_query($drop_routine); + if (! $result) { + $errors[] = sprintf(__('The following query has failed: "%s"'), $drop_routine) . '
' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $result = PMA_DBI_try_query($routine_query); + if (! $result) { + $errors[] = sprintf(__('The following query has failed: "%s"'), $routine_query) . '
' + . __('MySQL said: ') . PMA_DBI_getError(null); + // We dropped the old routine, but were unable to create the new one + // Try to restore the backup query + $result = PMA_DBI_try_query($create_routine); + if (! $result) { + // OMG, this is really bad! We dropped the query, failed to create a new one + // and now even the backup query does not execute! + // This should not happen, but we better handle this just in case. + $errors[] = __('Sorry, we failed to restore the dropped routine.') . '
' + . __('The backed up query was:') . "\"$create_routine\"" . '
' + . __('MySQL said: ') . PMA_DBI_getError(null); + } + } else { + $message = PMA_Message::success(__('Routine %1$s has been modified.')); + $message->addParam(PMA_backquote($_REQUEST['item_name'])); + $sql_query = $drop_routine . $routine_query; + } + } + } + } else { + // 'Add a new routine' mode + $result = PMA_DBI_try_query($routine_query); + if (! $result) { + $errors[] = sprintf(__('The following query has failed: "%s"'), $routine_query) . '

' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $message = PMA_Message::success(__('Routine %1$s has been created.')); + $message->addParam(PMA_backquote($_REQUEST['item_name'])); + $sql_query = $routine_query; + } + } + } + + if (count($errors)) { + $message = PMA_Message::error(__('One or more errors have occured while processing your request:')); + $message->addString('
    '); + foreach ($errors as $num => $string) { + $message->addString('
  • ' . $string . '
  • '); + } + $message->addString('
'); + } + + $output = PMA_showMessage($message, $sql_query); + if ($GLOBALS['is_ajax_request']) { + $extra_data = array(); + if ($message->isSuccess()) { + $columns = "`SPECIFIC_NAME`, `ROUTINE_NAME`, `ROUTINE_TYPE`, `DTD_IDENTIFIER`, `ROUTINE_DEFINITION`"; + $where = "ROUTINE_SCHEMA='" . PMA_sqlAddSlashes($db) . "' AND ROUTINE_NAME='" . PMA_sqlAddSlashes($_REQUEST['item_name']) . "'"; + $routine = PMA_DBI_fetch_single_row("SELECT $columns FROM `INFORMATION_SCHEMA`.`ROUTINES` WHERE $where;"); + $extra_data['name'] = htmlspecialchars(strtoupper($_REQUEST['item_name'])); + $extra_data['new_row'] = PMA_RTN_getRowForList($routine); + $extra_data['insert'] = ! empty($routine); + $response = $output; + } else { + $response = $message; + } + PMA_ajaxResponse($response, $message->isSuccess(), $extra_data); + } + } + + /** + * Display a form used to add/edit a routine, if necessary + */ + if (count($errors) || ( empty($_REQUEST['editor_process_add']) && empty($_REQUEST['editor_process_edit']) + && (! empty($_REQUEST['add_item']) || ! empty($_REQUEST['edit_item']) + || ! empty($_REQUEST['routine_addparameter']) || ! empty($_REQUEST['routine_removeparameter']) + || ! empty($_REQUEST['routine_changetype']))) // FIXME: this must be simpler than that + ) { + // Handle requests to add/remove parameters and changing routine type + // This is necessary when JS is disabled + $operation = ''; + if (! empty($_REQUEST['routine_addparameter'])) { + $operation = 'add'; + } else if (! empty($_REQUEST['routine_removeparameter'])) { + $operation = 'remove'; + } else if (! empty($_REQUEST['routine_changetype'])) { + $operation = 'change'; + } + // Get the data for the form (if any) + if (! empty($_REQUEST['add_item'])) { + $title = __("Create routine"); + $routine = PMA_RTN_getDataFromRequest(); + $mode = 'add'; + } else if (! empty($_REQUEST['edit_item'])) { + $title = __("Edit routine"); + if (! $operation && ! empty($_REQUEST['item_name']) && empty($_REQUEST['editor_process_edit'])) { + $routine = PMA_RTN_getDataFromName($_REQUEST['item_name']); + if ($routine !== false) { + $routine['item_original_name'] = $routine['item_name']; + $routine['item_original_type'] = $routine['item_type']; + } + } else { + $routine = PMA_RTN_getDataFromRequest(); + } + $mode = 'edit'; + } + if ($routine !== false) { + // Show form + $editor = PMA_RTN_getEditorForm($mode, $operation, $routine); + if ($GLOBALS['is_ajax_request']) { + $template = PMA_RTN_getParameterRow(); + $extra_data = array('title' => $title, + 'param_template' => $template, + 'type' => $routine['item_type']); + PMA_ajaxResponse($editor, true, $extra_data); + } + echo "\n\n

$title

\n\n$editor"; + require './libraries/footer.inc.php'; + // exit; + } else { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_backquote($db)) + ); + $message = PMA_message::error($message); + if ($GLOBALS['is_ajax_request']) { + PMA_ajaxResponse($message, false); + } else { + $message->display(); + } + } + } +} // end PMA_RTN_handleEditor() + +/** + * This function will generate the values that are required to + * complete the editor form. It is especially necessary to handle + * the 'Add another parameter', 'Remove last parameter' and + * 'Change routine type' functionalities when JS is disabled. + * + * @return array Data necessary to create the routine editor. + */ +function PMA_RTN_getDataFromRequest() +{ + global $_REQUEST, $param_directions, $param_sqldataaccess; + + $retval = array(); + $indices = array('item_name', + 'item_original_name', + 'item_returnlength', + 'item_returnopts_num', + 'item_returnopts_text', + 'item_definition', + 'item_comment', + 'item_definer'); + foreach ($indices as $key => $index) { + $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : ''; + } + + $retval['item_type'] = 'PROCEDURE'; + $retval['item_type_toggle'] = 'FUNCTION'; + if (isset($_REQUEST['item_type']) && $_REQUEST['item_type'] == 'FUNCTION') { + $retval['item_type'] = 'FUNCTION'; + $retval['item_type_toggle'] = 'PROCEDURE'; + } + $retval['item_original_type'] = 'PROCEDURE'; + if (isset($_REQUEST['item_original_type']) + && $_REQUEST['item_original_type'] == 'FUNCTION' + ) { + $retval['item_original_type'] = 'FUNCTION'; + } + $retval['item_num_params'] = 0; + $retval['item_param_dir'] = array(); + $retval['item_param_name'] = array(); + $retval['item_param_type'] = array(); + $retval['item_param_length'] = array(); + $retval['item_param_opts_num'] = array(); + $retval['item_param_opts_text'] = array(); + if (isset($_REQUEST['item_param_name']) + && isset($_REQUEST['item_param_type']) + && isset($_REQUEST['item_param_length']) + && isset($_REQUEST['item_param_opts_num']) + && isset($_REQUEST['item_param_opts_text']) + && is_array($_REQUEST['item_param_name']) + && is_array($_REQUEST['item_param_type']) + && is_array($_REQUEST['item_param_length']) + && is_array($_REQUEST['item_param_opts_num']) + && is_array($_REQUEST['item_param_opts_text']) + ) { + if ($_REQUEST['item_type'] == 'PROCEDURE') { + $temp_num_params = 0; + $retval['item_param_dir'] = $_REQUEST['item_param_dir']; + foreach ($retval['item_param_dir'] as $key => $value) { + if (! in_array($value, $param_directions, true)) { + $retval['item_param_dir'][$key] = ''; + } + $retval['item_num_params']++; + } + if ($temp_num_params > $retval['item_num_params']) { + $retval['item_num_params'] = $temp_num_params; + } + } + $temp_num_params = 0; + $retval['item_param_name'] = $_REQUEST['item_param_name']; + foreach ($retval['item_param_name'] as $key => $value) { + $retval['item_param_name'][$key] = $value; + $temp_num_params++; + } + if ($temp_num_params > $retval['item_num_params']) { + $retval['item_num_params'] = $temp_num_params; + } + $temp_num_params = 0; + $retval['item_param_type'] = $_REQUEST['item_param_type']; + foreach ($retval['item_param_type'] as $key => $value) { + if (! in_array($value, PMA_getSupportedDatatypes(), true)) { + $retval['item_param_type'][$key] = ''; + } + $temp_num_params++; + } + if ($temp_num_params > $retval['item_num_params']) { + $retval['item_num_params'] = $temp_num_params; + } + $temp_num_params = 0; + $retval['item_param_length'] = $_REQUEST['item_param_length']; + foreach ($retval['item_param_length'] as $key => $value) { + $retval['item_param_length'][$key] = $value; + $temp_num_params++; + } + if ($temp_num_params > $retval['item_num_params']) { + $retval['item_num_params'] = $temp_num_params; + } + $temp_num_params = 0; + $retval['item_param_opts_num'] = $_REQUEST['item_param_opts_num']; + foreach ($retval['item_param_opts_num'] as $key => $value) { + $retval['item_param_opts_num'][$key] = $value; + $temp_num_params++; + } + if ($temp_num_params > $retval['item_num_params']) { + $retval['item_num_params'] = $temp_num_params; + } + $temp_num_params = 0; + $retval['item_param_opts_text'] = $_REQUEST['item_param_opts_text']; + foreach ($retval['item_param_opts_text'] as $key => $value) { + $retval['item_param_opts_text'][$key] = $value; + $temp_num_params++; + } + if ($temp_num_params > $retval['item_num_params']) { + $retval['item_num_params'] = $temp_num_params; + } + } + $retval['item_returntype'] = ''; + if (isset($_REQUEST['item_returntype']) + && in_array($_REQUEST['item_returntype'], PMA_getSupportedDatatypes()) + ) { + $retval['item_returntype'] = $_REQUEST['item_returntype']; + } + + $retval['item_isdeterministic'] = ''; + if (isset($_REQUEST['item_isdeterministic']) + && strtolower($_REQUEST['item_isdeterministic']) == 'on' + ) { + $retval['item_isdeterministic'] = " checked='checked'"; + } + $retval['item_securitytype_definer'] = ''; + $retval['item_securitytype_invoker'] = ''; + if (isset($_REQUEST['item_securitytype'])) { + if ($_REQUEST['item_securitytype'] === 'DEFINER') { + $retval['item_securitytype_definer'] = " selected='selected'"; + } else if ($_REQUEST['item_securitytype'] === 'INVOKER') { + $retval['item_securitytype_invoker'] = " selected='selected'"; + } + } + $retval['item_sqldataaccess'] = ''; + if (isset($_REQUEST['item_sqldataaccess']) + && in_array($_REQUEST['item_sqldataaccess'], $param_sqldataaccess, true) + ) { + $retval['item_sqldataaccess'] = $_REQUEST['item_sqldataaccess']; + } + + return $retval; +} // end function PMA_RTN_getDataFromRequest() + +/** + * This function will generate the values that are required to complete + * the "Edit routine" form given the name of a routine. + * + * @param string $name The name of the routine. + * @param bool $all Whether to return all data or just + * the info about parameters. + * + * @return array Data necessary to create the routine editor. + */ +function PMA_RTN_getDataFromName($name, $all = true) +{ + global $param_directions, $param_sqldataaccess, $db; + + $retval = array(); + + // Build and execute the query + $fields = "SPECIFIC_NAME, ROUTINE_TYPE, DTD_IDENTIFIER, " + . "ROUTINE_DEFINITION, IS_DETERMINISTIC, SQL_DATA_ACCESS, " + . "ROUTINE_COMMENT, SECURITY_TYPE"; + $where = "ROUTINE_SCHEMA='" . PMA_sqlAddSlashes($db) . "' " + . "AND SPECIFIC_NAME='" . PMA_sqlAddSlashes($name) . "'"; + $query = "SELECT $fields FROM INFORMATION_SCHEMA.ROUTINES WHERE $where;"; + + $routine = PMA_DBI_fetch_single_row($query); + + if (! $routine) { + return false; + } + + // Get required data + $retval['item_name'] = $routine['SPECIFIC_NAME']; + $retval['item_type'] = $routine['ROUTINE_TYPE']; + $parsed_query = PMA_SQP_parse( + PMA_DBI_get_definition( + $db, + $routine['ROUTINE_TYPE'], + $routine['SPECIFIC_NAME'] + ) + ); + $params = PMA_RTN_parseAllParameters($parsed_query, $routine['ROUTINE_TYPE']); + $retval['item_num_params'] = $params['num']; + $retval['item_param_dir'] = $params['dir']; + $retval['item_param_name'] = $params['name']; + $retval['item_param_type'] = $params['type']; + $retval['item_param_length'] = $params['length']; + $retval['item_param_opts_num'] = $params['opts']; + $retval['item_param_opts_text'] = $params['opts']; + + // Get extra data + if ($all) { + if ($retval['item_type'] == 'FUNCTION') { + $retval['item_type_toggle'] = 'PROCEDURE'; + } else { + $retval['item_type_toggle'] = 'FUNCTION'; + } + $retval['item_returntype'] = ''; + $retval['item_returnlength'] = ''; + $retval['item_returnopts_num'] = ''; + $retval['item_returnopts_text'] = ''; + if (! empty($routine['DTD_IDENTIFIER'])) { + if (strlen($routine['DTD_IDENTIFIER']) > 63) { + // If the DTD_IDENTIFIER string from INFORMATION_SCHEMA is + // at least 64 characters, then it may actually have been + // chopped because that column is a varchar(64), so we will + // parse the output of SHOW CREATE query to get accurate + // information about the return variable. + $dtd = ''; + $fetching = false; + for ($i=0; $i<$parsed_query['len']; $i++) { + if ($parsed_query[$i]['type'] == 'alpha_reservedWord' + && strtoupper($parsed_query[$i]['data']) == 'RETURNS' + ) { + $fetching = true; + } else if ($fetching == true && $parsed_query[$i]['type'] == 'alpha_reservedWord') { + // We will not be looking for options such as UNSIGNED + // or ZEROFILL because there is no way that a numeric + // field's DTD_IDENTIFIER can be longer than 64 + // characters. We can safely assume that the return + // datatype is either ENUM or SET, so we only look + // for CHARSET. + $word = strtoupper($parsed_query[$i]['data']); + if ($word == 'CHARSET' + && ($parsed_query[$i+1]['type'] == 'alpha_charset' + || $parsed_query[$i+1]['type'] == 'alpha_identifier') + ) { + $dtd .= $word . ' ' . $parsed_query[$i+1]['data']; + } + break; + } else if ($fetching == true) { + $dtd .= $parsed_query[$i]['data'] . ' '; + } + } + $routine['DTD_IDENTIFIER'] = $dtd; + } + $returnparam = PMA_RTN_parseOneParameter($routine['DTD_IDENTIFIER']); + $retval['item_returntype'] = $returnparam[2]; + $retval['item_returnlength'] = $returnparam[3]; + $retval['item_returnopts_num'] = $returnparam[4]; + $retval['item_returnopts_text'] = $returnparam[4]; + } + $retval['item_definer'] = PMA_RTN_parseRoutineDefiner($parsed_query); + $retval['item_definition'] = $routine['ROUTINE_DEFINITION']; + $retval['item_isdeterministic'] = ''; + if ($routine['IS_DETERMINISTIC'] == 'YES') { + $retval['item_isdeterministic'] = " checked='checked'"; + } + $retval['item_securitytype_definer'] = ''; + $retval['item_securitytype_invoker'] = ''; + if ($routine['SECURITY_TYPE'] == 'DEFINER') { + $retval['item_securitytype_definer'] = " selected='selected'"; + } else if ($routine['SECURITY_TYPE'] == 'INVOKER') { + $retval['item_securitytype_invoker'] = " selected='selected'"; + } + $retval['item_sqldataaccess'] = $routine['SQL_DATA_ACCESS']; + $retval['item_comment'] = $routine['ROUTINE_COMMENT']; + } + + return $retval; +} // PMA_RTN_getDataFromName() + +/** + * Creates one row for the parameter table used in the routine editor. + * + * @param array $routine Data for the routine returned by + * PMA_RTN_getDataFromRequest() or + * PMA_RTN_getDataFromName() + * @param mixed $index Either a numeric index of the row being processed + * or NULL to create a template row for AJAX request + * @param string $class Class used to hide the direction column, if the + * row is for a stored function. + * + * @return string HTML code of one row of parameter table for the editor. + */ +function PMA_RTN_getParameterRow($routine = array(), $index = null, $class = '') +{ + global $param_directions, $param_opts_num, $titles; + + if ($index === null) { + // template row for AJAX request + $i = 0; + $index = '%s'; + $drop_class = ''; + $routine = array( + 'item_param_dir' => array(0 => ''), + 'item_param_name' => array(0 => ''), + 'item_param_type' => array(0 => ''), + 'item_param_length' => array(0 => ''), + 'item_param_opts_num' => array(0 => ''), + 'item_param_opts_text' => array(0 => '') + ); + } else if (! empty($routine)) { + // regular row for routine editor + $drop_class = ' hide'; + $i = $index; + } else { + // No input data. This shouldn't happen, + // but better be safe than sorry. + return ''; + } + + // Create the output + $retval = ""; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + + return $retval; +} // end PMA_RTN_getParameterRow() + +/** + * Displays a form used to add/edit a routine + * + * @param string $mode If the editor will be used edit a routine + * or add a new one: 'edit' or 'add'. + * @param string $operation If the editor was previously invoked with + * JS turned off, this will hold the name of + * the current operation + * @param array $routine Data for the routine returned by + * PMA_RTN_getDataFromRequest() or + * PMA_RTN_getDataFromName() + * + * @return string HTML code for the editor. + */ +function PMA_RTN_getEditorForm($mode, $operation, $routine) +{ + global $db, $titles, $errors, $param_directions, $param_sqldataaccess, $param_opts_num; + + // Escape special characters + $need_escape = array( + 'item_original_name', + 'item_name', + 'item_returnlength', + 'item_definition', + 'item_definer', + 'item_comment' + ); + foreach ($need_escape as $key => $index) { + $routine[$index] = htmlentities($routine[$index], ENT_QUOTES); + } + for ($i=0; $i<$routine['item_num_params']; $i++) { + $routine['item_param_name'][$i] = htmlentities( + $routine['item_param_name'][$i], + ENT_QUOTES + ); + $routine['item_param_length'][$i] = htmlentities( + $routine['item_param_length'][$i], + ENT_QUOTES + ); + } + + // Handle some logic first + if ($operation == 'change') { + if ($routine['item_type'] == 'PROCEDURE') { + $routine['item_type'] = 'FUNCTION'; + $routine['item_type_toggle'] = 'PROCEDURE'; + } else { + $routine['item_type'] = 'PROCEDURE'; + $routine['item_type_toggle'] = 'FUNCTION'; + } + } else if ($operation == 'add' || ($routine['item_num_params'] == 0 && $mode == 'add' && ! $errors)) { + $routine['item_param_dir'][] = ''; + $routine['item_param_name'][] = ''; + $routine['item_param_type'][] = ''; + $routine['item_param_length'][] = ''; + $routine['item_param_opts_num'][] = ''; + $routine['item_param_opts_text'][] = ''; + $routine['item_num_params']++; + } else if ($operation == 'remove') { + unset($routine['item_param_dir'][$routine['item_num_params']-1]); + unset($routine['item_param_name'][$routine['item_num_params']-1]); + unset($routine['item_param_type'][$routine['item_num_params']-1]); + unset($routine['item_param_length'][$routine['item_num_params']-1]); + unset($routine['item_param_opts_num'][$routine['item_num_params']-1]); + unset($routine['item_param_opts_text'][$routine['item_num_params']-1]); + $routine['item_num_params']--; + } + $disable_remove_parameter = ''; + if (! $routine['item_num_params']) { + $disable_remove_parameter = " color: gray;' disabled='disabled"; + } + $original_routine = ''; + if ($mode == 'edit') { + $original_routine = "\n" + . "\n"; + } + $isfunction_class = ''; + $isprocedure_class = ''; + $isfunction_select = ''; + $isprocedure_select = ''; + if ($routine['item_type'] == 'PROCEDURE') { + $isfunction_class = ' hide'; + $isprocedure_select = " selected='selected'"; + } else { + $isprocedure_class = ' hide'; + $isfunction_select = " selected='selected'"; + } + + // Create the output + $retval = ""; + $retval .= "\n\n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= $original_routine; + $retval .= PMA_generate_common_hidden_inputs($db) . "\n"; + $retval .= "
\n"; + $retval .= "" . __('Details') . "\n"; + $retval .= "
" . __('Event name') . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
" . __('Event type') . "\n"; + if ($GLOBALS['is_ajax_request']) { + $retval .= " \n"; + } else { + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " $value) { + $selected = ""; + if (! empty($item['item_interval_field']) + && $item['item_interval_field'] == $value + ) { + $selected = " selected='selected'"; + } + $retval .= "$value"; + } + $retval .= " \n"; + $retval .= "
" . __('Start') . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
" . __('On completion preserve') . "
" . __('Definer') . "\n"; + $retval .= " \n"; + $retval .= "\n"; + } + $retval .= "\n\n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_EVN_getEditorForm() + +/** + * Composes the query necessary to create an event from an HTTP request. + * + * @return string The CREATE EVENT query. + */ +function PMA_EVN_getQueryFromRequest() +{ + global $_REQUEST, $db, $errors, $event_status, $event_type, $event_interval; + + $query = 'CREATE '; + if (! empty($_REQUEST['item_definer'])) { + if (strpos($_REQUEST['item_definer'], '@') !== false) { + $arr = explode('@', $_REQUEST['item_definer']); + $query .= 'DEFINER=' . PMA_backquote($arr[0]); + $query .= '@' . PMA_backquote($arr[1]) . ' '; + } else { + $errors[] = __('The definer must be in the "username@hostname" format'); + } + } + $query .= 'EVENT '; + if (! empty($_REQUEST['item_name'])) { + $query .= PMA_backquote($_REQUEST['item_name']) . ' '; + } else { + $errors[] = __('You must provide an event name'); + } + $query .= 'ON SCHEDULE '; + if (! empty($_REQUEST['item_type']) && in_array($_REQUEST['item_type'], $event_type)) { + if ($_REQUEST['item_type'] == 'RECURRING') { + if (! empty($_REQUEST['item_interval_value']) + && !empty($_REQUEST['item_interval_field']) + && in_array($_REQUEST['item_interval_field'], $event_interval) + ) { + $query .= 'EVERY ' . intval($_REQUEST['item_interval_value']) . ' '; + $query .= $_REQUEST['item_interval_field'] . ' '; + } else { + $errors[] = __('You must provide a valid interval value for the event.'); + } + if (! empty($_REQUEST['item_starts'])) { + $query .= "STARTS '" . PMA_sqlAddSlashes($_REQUEST['item_starts']) . "' "; + } + if (! empty($_REQUEST['item_ends'])) { + $query .= "ENDS '" . PMA_sqlAddSlashes($_REQUEST['item_ends']) . "' "; + } + } else { + if (! empty($_REQUEST['item_execute_at'])) { + $query .= "AT '" . PMA_sqlAddSlashes($_REQUEST['item_execute_at']) . "' "; + } else { + $errors[] = __('You must provide a valid execution time for the event.'); + } + } + } else { + $errors[] = __('You must provide a valid type for the event.'); + } + $query .= 'ON COMPLETION '; + if (empty($_REQUEST['item_preserve'])) { + $query .= 'NOT '; + } + $query .= 'PRESERVE '; + if (! empty($_REQUEST['item_status'])) { + foreach ($event_status['display'] as $key => $value) { + if ($value == $_REQUEST['item_status']) { + $query .= $event_status['query'][$key] . ' '; + break; + } + } + } + $query .= 'DO '; + if (! empty($_REQUEST['item_definition'])) { + $query .= $_REQUEST['item_definition']; + } else { + $errors[] = __('You must provide an event definition.'); + } + + return $query; +} // end PMA_EVN_getQueryFromRequest() + +?> diff --git a/libraries/rte/rte_export.lib.php b/libraries/rte/rte_export.lib.php new file mode 100644 index 0000000000..d4d8f99a2f --- /dev/null +++ b/libraries/rte/rte_export.lib.php @@ -0,0 +1,107 @@ +' + . htmlspecialchars(trim($export_data)) . ''; + $title = sprintf(PMA_RTE_getWord('export'), $item_name); + if ($GLOBALS['is_ajax_request'] == true) { + $extra_data = array('title' => $title); + PMA_ajaxResponse($export_data, true, $extra_data); + } else { + echo "
\n" + . "$title\n" + . $export_data + . "
\n"; + } + } else { + $_db = htmlspecialchars(PMA_backquote($db)); + $response = __('Error in Processing Request') . ' : ' + . sprintf(PMA_RTE_getWord('not_found'), $item_name, $_db); + $response = PMA_message::error($response); + if ($GLOBALS['is_ajax_request'] == true) { + PMA_ajaxResponse($response, false); + } else { + $response->display(); + } + } +} // end PMA_RTE_handleExport() + +/** + * If necessary, prepares event information and passes + * it to PMA_RTE_handleExport() for the actual export. + */ +function PMA_EVN_handleExport() +{ + global $_GET, $db; + + if (! empty($_GET['export_item']) && ! empty($_GET['item_name'])) { + $item_name = $_GET['item_name']; + $export_data = PMA_DBI_get_definition($db, 'EVENT', $item_name); + PMA_RTE_handleExport($item_name, $export_data); + } +} // end PMA_EVN_handleExport() + +/** + * If necessary, prepares routine information and passes + * it to PMA_RTE_handleExport() for the actual export. + */ +function PMA_RTN_handleExport() +{ + global $_GET, $db; + + if (! empty($_GET['export_item']) && ! empty($_GET['item_name'])) { + $item_name = $_GET['item_name']; + $type = PMA_DBI_fetch_value( + "SELECT ROUTINE_TYPE " . + "FROM INFORMATION_SCHEMA.ROUTINES " . + "WHERE ROUTINE_SCHEMA='" . PMA_sqlAddSlashes($db) . "' " . + "AND SPECIFIC_NAME='" . PMA_sqlAddSlashes($item_name) . "';" + ); + $export_data = PMA_DBI_get_definition($db, $type, $item_name); + PMA_RTE_handleExport($item_name, $export_data); + } +} // end PMA_RTN_handleExport() + +/** + * If necessary, prepares trigger information and passes + * it to PMA_RTE_handleExport() for the actual export. + */ +function PMA_TRI_handleExport() +{ + global $_GET, $db, $table; + + if (! empty($_GET['export_item']) && ! empty($_GET['item_name'])) { + $item_name = $_GET['item_name']; + $triggers = PMA_DBI_get_triggers($db, $table, ''); + $export_data = false; + foreach ($triggers as $trigger) { + if ($trigger['name'] === $item_name) { + $export_data = $trigger['create']; + break; + } + } + PMA_RTE_handleExport($item_name, $export_data); + } +} // end PMA_TRI_handleExport() +?> diff --git a/libraries/rte/rte_footer.lib.php b/libraries/rte/rte_footer.lib.php new file mode 100644 index 0000000000..22e414b97b --- /dev/null +++ b/libraries/rte/rte_footer.lib.php @@ -0,0 +1,127 @@ +\n"; + $retval .= "
\n"; + $retval .= " " . __('New'). "\n"; + $retval .= " \n"; + $retval .= "
\n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_RTE_getFooterLinks() + +/** + * Creates a fieldset for adding a new routine, if the user has the privileges. + * + * @return string HTML code with containing the fotter fieldset + */ +function PMA_RTN_getFooterLinks() +{ + return PMA_RTE_getFooterLinks('CREATE_PROCEDURE', 'CREATE ROUTINE', 'ROUTINE'); +}// end PMA_RTN_getFooterLinks() + +/** + * Creates a fieldset for adding a new trigger, if the user has the privileges. + * + * @return string HTML code with containing the fotter fieldset + */ +function PMA_TRI_getFooterLinks() +{ + return PMA_RTE_getFooterLinks('CREATE_TRIGGER', 'TRIGGER', 'TRIGGER'); +} // end PMA_TRI_getFooterLinks() + +/** + * Creates a fieldset for adding a new event, if the user has the privileges. + * + * @return string HTML code with containing the fotter fieldset + */ +function PMA_EVN_getFooterLinks() +{ + global $db, $url_query, $ajax_class; + + /** + * For events, we show the usual 'Add event' form and also + * a form for toggling the state of the event scheduler + */ + // Init options for the event scheduler toggle functionality + $es_state = PMA_DBI_fetch_value( + "SHOW GLOBAL VARIABLES LIKE 'event_scheduler'", + 0, + 1 + ); + $es_state = strtolower($es_state); + $options = array( + 0 => array( + 'label' => __('OFF'), + 'value' => "SET GLOBAL event_scheduler=\"OFF\"", + 'selected' => ($es_state != 'on') + ), + 1 => array( + 'label' => __('ON'), + 'value' => "SET GLOBAL event_scheduler=\"ON\"", + 'selected' => ($es_state == 'on') + ) + ); + // Generate output + $retval = "\n"; + $retval .= "
\n"; + // show the usual footer + $retval .= PMA_RTE_getFooterLinks('CREATE_EVENT', 'EVENT', 'EVENT'); + $retval .= "
\n"; + $retval .= " \n"; + $retval .= " " . __('Event scheduler status') . "\n"; + $retval .= " \n"; + $retval .= "
\n"; + // show the toggle button + $retval .= PMA_toggleButton( + "sql.php?$url_query&goto=db_events.php" . urlencode("?db=$db"), + 'sql_query', + $options, + 'PMA_slidingMessage(data.sql_query);' + ); + $retval .= "
\n"; + $retval .= "
\n"; + $retval .= "
\n"; + $retval .= "
"; + $retval .= "\n"; + + return $retval; +} // end PMA_EVN_getFooterLinks() + +?> diff --git a/libraries/rte/rte_list.lib.php b/libraries/rte/rte_list.lib.php new file mode 100644 index 0000000000..91cbbbc3bc --- /dev/null +++ b/libraries/rte/rte_list.lib.php @@ -0,0 +1,338 @@ +\n"; + $retval .= "
\n"; + $retval .= " \n"; + $retval .= " " . PMA_RTE_getWord('title') . "\n"; + $retval .= " " . PMA_showMySQLDocu('SQL-Syntax', PMA_RTE_getWord('docu')) . "\n"; + $retval .= " \n"; + $retval .= "
\n"; + $retval .= " " . PMA_RTE_getWord('nothing') . "\n"; + $retval .= "
\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + switch ($type) { + case 'routine': + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + break; + case 'trigger': + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + break; + case 'event': + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + break; + default: + break; + } + $retval .= " \n"; + $retval .= " \n"; + $ct = 0; + foreach ($items as $item) { + $rowclass = ($ct % 2 == 0) ? 'even' : 'odd'; + if ($GLOBALS['is_ajax_request']) { + $rowclass .= ' ajaxInsert hide'; + } + // Get each row from the correct function + switch ($type) { + case 'routine': + $retval .= PMA_RTN_getRowForList($item, $rowclass); + break; + case 'trigger': + $retval .= PMA_TRI_getRowForList($item, $rowclass); + break; + case 'event': + $retval .= PMA_EVN_getRowForList($item, $rowclass); + break; + default: + break; + } + $ct++; + } + $retval .= "
" . __('Name') . "" . __('Action') . "" . __('Type') . "" . __('Returns') . "" . __('Name') . "" . __('Table') . "" . __('Action') . "" . __('Time') . "" . __('Event') . "" . __('Name') . "" . __('Status') . "" . __('Action') . "" . __('Type') . "
\n"; + $retval .= "
\n"; + $retval .= "\n"; + + return $retval; +} // end PMA_RTE_getList() + +/** + * Creates the contents for a row in the list of routines + * + * @param array $routine An array of routine data + * @param string $rowclass Empty or one of ['even'|'odd'] + * + * @return string HTML code of a row for the list of routines + */ +function PMA_RTN_getRowForList($routine, $rowclass = '') +{ + global $ajax_class, $url_query, $db, $titles; + + $sql_drop = sprintf('DROP %s IF EXISTS %s', + $routine['ROUTINE_TYPE'], + PMA_backquote($routine['SPECIFIC_NAME'])); + + + $retval = "
\n"; + $retval .= " $sql_drop\n"; + $retval .= " \n"; + $retval .= " " . htmlspecialchars($routine['SPECIFIC_NAME']) . "\n"; + $retval .= " \n"; + $retval .= " \n"; + if ($routine['ROUTINE_DEFINITION'] !== null + && PMA_currentUserHasPrivilege('ALTER ROUTINE', $db) + && PMA_currentUserHasPrivilege('CREATE ROUTINE', $db) + ) { + $retval .= ' ' . $titles['Edit'] . "\n"; + } else { + $retval .= " {$titles['NoEdit']}\n"; + } + $retval .= " \n"; + if ($routine['ROUTINE_DEFINITION'] !== null + && PMA_currentUserHasPrivilege('EXECUTE', $db) + ) { + // Check if he routine has any input parameters. If it does, + // we will show a dialog to get values for these parameters, + // otherwise we can execute it directly. + $routine_details = PMA_RTN_getDataFromName( + $routine['SPECIFIC_NAME'], + false + ); + if ($routine !== false) { + $execute_action = 'execute_routine'; + for ($i=0; $i<$routine_details['item_num_params']; $i++) { + if ($routine_details['item_type'] == 'PROCEDURE' + && $routine_details['item_param_dir'][$i] == 'OUT' + ) { + continue; + } + $execute_action = 'execute_dialog'; + break; + } + $retval .= ' ' . $titles['Execute'] . "\n"; + } + } else { + $retval .= " {$titles['NoExecute']}\n"; + } + $retval .= " \n"; + $retval .= ' ' . $titles['Export'] . "\n"; + $retval .= " \n"; + if (PMA_currentUserHasPrivilege('EVENT', $db)) { + $retval .= ' ' . $titles['Drop'] . "\n"; + } else { + $retval .= " {$titles['NoDrop']}\n"; + } + $retval .= " \n"; + $retval .= " {$routine['ROUTINE_TYPE']}\n"; + $retval .= " \n"; + $retval .= " " . htmlspecialchars($routine['DTD_IDENTIFIER']) . "\n"; + $retval .= "
\n"; + $retval .= " {$trigger['drop']}\n"; + $retval .= " \n"; + $retval .= " " . htmlspecialchars($trigger['name']) . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " " + . $trigger['table'] . "\n"; + $retval .= " \n"; + if (PMA_currentUserHasPrivilege('TRIGGER', $db, $table)) { + $retval .= ' ' . $titles['Edit'] . "\n"; + } else { + $retval .= " {$titles['NoEdit']}\n"; + } + $retval .= " \n"; + $retval .= ' ' . $titles['Export'] . "\n"; + $retval .= " \n"; + if (PMA_currentUserHasPrivilege('TRIGGER', $db)) { + $retval .= ' ' . $titles['Drop'] . "\n"; + } else { + $retval .= " {$titles['NoDrop']}\n"; + } + $retval .= " \n"; + $retval .= " {$trigger['action_timing']}\n"; + $retval .= " \n"; + $retval .= " {$trigger['event_manipulation']}\n"; + $retval .= "
\n"; + $retval .= " $sql_drop\n"; + $retval .= " \n"; + $retval .= " " . htmlspecialchars($event['EVENT_NAME']) . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " {$event['STATUS']}\n"; + $retval .= " \n"; + if (PMA_currentUserHasPrivilege('EVENT', $db)) { + $retval .= ' ' . $titles['Edit'] . "\n"; + } else { + $retval .= " {$titles['NoEdit']}\n"; + } + $retval .= " \n"; + $retval .= ' ' . $titles['Export'] . "\n"; + $retval .= " \n"; + if (PMA_currentUserHasPrivilege('EVENT', $db)) { + $retval .= ' ' . $titles['Drop'] . "\n"; + } else { + $retval .= " {$titles['NoDrop']}\n"; + } + $retval .= " \n"; + $retval .= " {$event['EVENT_TYPE']}\n"; + $retval .= "
\n"; + $retval .= " \n"; + $retval .= " $value) { + $selected = ""; + if (! empty($routine['item_param_opts_num'][$i]) + && $routine['item_param_opts_num'][$i] == $value + ) { + $selected = " selected='selected'"; + } + $retval .= "$value"; + } + $retval .= "\n \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " {$titles['Drop']}\n"; + $retval .= " \n"; + $retval .= "
\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + // parameter handling end + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= "
" . __('Routine name') . "\n"; + $retval .= " \n"; + if ($GLOBALS['is_ajax_request']) { + $retval .= " \n"; + } else { + $retval .= " \n"; + $retval .= "
\n"; + $retval .= " {$routine['item_type']}\n"; + $retval .= "
\n"; + $retval .= " \n"; + } + $retval .= "
" . __('Parameters') . "\n"; + // parameter handling start + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " "; + for ($i=0; $i<$routine['item_num_params']; $i++) { // each parameter + $retval .= PMA_RTN_getParameterRow($routine, $i, $isprocedure_class); + } + $retval .= "
" . __('Direction') . "" . __('Name') . "" . __('Type') . "" . __('Length/Values') . "" . __('Options') . " 
\n"; + $retval .= "
 \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
" . __('Return type') . "
" . __('Return length/values') . "\n"; + $retval .= "
\n"; + $retval .= PMA_generateCharsetDropdownBox( + PMA_CSDROPDOWN_CHARSET, + "item_returnopts_text", + null, + $routine['item_returnopts_text'] + ); + $retval .= "\n
\n"; + $retval .= "
\n"; + $retval .= "
---
\n"; + $retval .= "
" . __('Definition') . "
" . __('Is deterministic') . "
" . __('Definer') . "\n"; + $retval .= "
" . __('SQL data access') . "
" . __('Comment') . "\n"; + $retval .= "\n"; + } + $retval .= "\n\n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_RTN_getEditorForm() + +/** + * Composes the query necessary to create a routine from an HTTP request. + * + * @return string The CREATE [ROUTINE | PROCEDURE] query. + */ +function PMA_RTN_getQueryFromRequest() +{ + global $_REQUEST, $cfg, $errors, $param_sqldataaccess, $param_opts_num; + + $query = 'CREATE '; + if (! empty($_REQUEST['item_definer'])) { + if (strpos($_REQUEST['item_definer'], '@') !== false) { + $arr = explode('@', $_REQUEST['item_definer']); + $query .= 'DEFINER=' . PMA_backquote($arr[0]); + $query .= '@' . PMA_backquote($arr[1]) . ' '; + } else { + $errors[] = __('The definer must be in the "username@hostname" format'); + } + } + if ($_REQUEST['item_type'] == 'FUNCTION' + || $_REQUEST['item_type'] == 'PROCEDURE' + ) { + $query .= $_REQUEST['item_type'] . ' '; + } else { + $errors[] = sprintf(__('Invalid routine type: "%s"'), htmlspecialchars($_REQUEST['item_type'])); + } + if (! empty($_REQUEST['item_name'])) { + $query .= PMA_backquote($_REQUEST['item_name']) . ' '; + } else { + $errors[] = __('You must provide a routine name'); + } + $params = ''; + $warned_about_dir = false; + $warned_about_name = false; + $warned_about_length = false; + if (! empty($_REQUEST['item_param_name']) + && ! empty($_REQUEST['item_param_type']) + && ! empty($_REQUEST['item_param_length']) + && is_array($_REQUEST['item_param_name']) + && is_array($_REQUEST['item_param_type']) + && is_array($_REQUEST['item_param_length']) + ) { + for ($i=0; $i $query) { + $resource = PMA_DBI_try_query($query); + if ($resource === false) { + $outcome = false; + break; + } + while (true) { + if (! PMA_DBI_more_results()) { + break; + } + PMA_DBI_next_result(); + } + if (substr($query, 0, 6) == 'SELECT') { + $result = $resource; + } else if (substr($query, 0, 4) == 'CALL') { + $affected = PMA_DBI_affected_rows() - PMA_DBI_num_rows($resource); + } + } + // Generate output + if ($outcome) { + $message = __('Your SQL query has been executed successfully'); + if ($routine['item_type'] == 'PROCEDURE') { + $message .= '
'; + $message .= sprintf( + _ngettext( + '%d row affected by the last statement inside the procedure', + '%d rows affected by the last statement inside the procedure', + $affected + ), + $affected + ); + } + $message = PMA_message::success($message); + // Pass the SQL queries through the "pretty printer" + $output = ''; + $output .= PMA_SQP_formatHtml(PMA_SQP_parse(implode($queries))); + $output .= ''; + // Display results + if ($result) { + $output .= "
"; + $output .= sprintf( + __('Execution results of routine %s'), + PMA_backquote(htmlspecialchars($routine['item_name'])) + ); + $output .= ""; + $output .= ""; + foreach (PMA_DBI_get_fields_meta($result) as $key => $field) { + $output .= ""; + } + $output .= ""; + // Stored routines can only ever return ONE ROW. + $data = PMA_DBI_fetch_single_row($result); + foreach ($data as $key => $value) { + if ($value === null) { + $value = 'NULL'; + } else { + $value = htmlspecialchars($value); + } + $output .= ""; + } + $output .= "
"; + $output .= htmlspecialchars($field->name); + $output .= "
" . $value . "
"; + } else { + $notice = __('MySQL returned an empty result set (i.e. zero rows).'); + $output .= PMA_message::notice($notice)->getDisplay(); + } + } else { + $output = ''; + $message = PMA_message::error(sprintf(__('The following query has failed: "%s"'), $query) . '

' + . __('MySQL said: ') . PMA_DBI_getError(null)); + } + // Print/send output + if ($GLOBALS['is_ajax_request']) { + $extra_data = array('dialog' => false); + PMA_ajaxResponse( + $message->getDisplay() . $output, + $message->isSuccess(), + $extra_data + ); + } else { + echo $message->getDisplay() . $output; + if ($message->isError()) { + // At least one query has failed, so shouldn't + // execute any more queries, so we quit. + exit; + } + unset($_POST); + // Now deliberately fall through to displaying the routines list + } + } else { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_backquote($db)) + ); + $message = PMA_message::error($message); + if ($GLOBALS['is_ajax_request']) { + PMA_ajaxResponse($message, $message->isSuccess()); + } else { + echo $message->getDisplay(); + unset($_POST); + } + } + } else if (! empty($_GET['execute_dialog']) && ! empty($_GET['item_name'])) { + /** + * Display the execute form for a routine. + */ + $routine = PMA_RTN_getDataFromName($_GET['item_name'], false); + if ($routine !== false) { + $form = PMA_RTN_getExecuteForm($routine); + if ($GLOBALS['is_ajax_request'] == true) { + $extra_data = array(); + $extra_data['dialog'] = true; + $extra_data['title'] = __("Execute routine") . " "; + $extra_data['title'] .= PMA_backquote( + htmlentities($_GET['item_name'], ENT_QUOTES) + ); + PMA_ajaxResponse($form, true, $extra_data); + } else { + echo "\n\n

" . __("Execute routine") . "

\n\n"; + echo $form; + require './libraries/footer.inc.php'; + // exit; + } + } else if (($GLOBALS['is_ajax_request'] == true)) { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_backquote($db)) + ); + $message = PMA_message::error($message); + PMA_ajaxResponse($message, false); + } + } +} + +/** + * Creates the HTML code that shows the routine execution dialog. + * + * @param array $routine Data for the routine returned by + * PMA_RTN_getDataFromName() + * + * @return string HTML code for the routine execution dialog. + */ +function PMA_RTN_getExecuteForm($routine) +{ + global $db, $cfg; + + // Escape special characters + $routine['item_name'] = htmlentities($routine['item_name'], ENT_QUOTES); + for ($i=0; $i<$routine['item_num_params']; $i++) { + $routine['item_param_name'][$i] = htmlentities( + $routine['item_param_name'][$i], + ENT_QUOTES + ); + } + + // Create the output + $retval = ""; + $retval .= "\n\n"; + $retval .= "
\n"; + $retval .= "\n"; + $retval .= "\n"; + } + $retval .= "\n"; + $retval .= "\n"; + $retval .= "\n"; + if ($cfg['ShowFunctionFields']) { + $retval .= "\n"; + } + $retval .= "\n"; + $retval .= "\n"; + for ($i=0; $i<$routine['item_num_params']; $i++) { // Each parameter + if ($routine['item_type'] == 'PROCEDURE' + && $routine['item_param_dir'][$i] == 'OUT' + ) { + continue; + } + $rowclass = ($i % 2 == 0) ? 'even' : 'odd'; + $retval .= "\n\n"; + $retval .= "\n"; + $retval .= "\n"; + if ($cfg['ShowFunctionFields']) { + $retval .= "\n"; + } + // Append a class to date/time fields so that + // jQuery can attach a datepicker to them + $class = ''; + if ($routine['item_param_type'][$i] == 'DATETIME' + || $routine['item_param_type'][$i] == 'TIMESTAMP' + ) { + $class = 'datetimefield'; + } else if ($routine['item_param_type'][$i] == 'DATE') { + $class = 'datefield'; + } + $retval .= "\n"; + $retval .= "\n"; + } + $retval .= "\n
" . __('Name') . "" . __('Type') . "" . __('Function') . "" . __('Value') . "
{$routine['item_param_name'][$i]}{$routine['item_param_type'][$i]}\n"; + // Get a list of data types that are not yet supported. + $no_support_types = PMA_unsupportedDatatypes(); + if (stristr($routine['item_param_type'][$i], 'enum') + || stristr($routine['item_param_type'][$i], 'set') + || in_array(strtolower($routine['item_param_type'][$i]), $no_support_types) + ) { + $retval .= "--\n"; + } else { + $field = array( + 'True_Type' => strtolower($routine['item_param_type'][$i]), + 'Type' => '', + 'Key' => '', + 'Field' => '', + 'Default' => '', + 'first_timestamp' => false + ); + $retval .= ""; + } + $retval .= "\n"; + if (in_array($routine['item_param_type'][$i], array('ENUM', 'SET'))) { + $tokens = PMA_SQP_parse($routine['item_param_length'][$i]); + if ($routine['item_param_type'][$i] == 'ENUM') { + $input_type = 'radio'; + } else { + $input_type = 'checkbox'; + } + for ($j=0; $j<$tokens['len']; $j++) { + if ($tokens[$j]['type'] != 'punct_listsep') { + $tokens[$j]['data'] = htmlentities( + PMA_unquote($tokens[$j]['data']), + ENT_QUOTES + ); + $retval .= "" + . "{$tokens[$j]['data']}
\n"; + } + } + } else if (in_array(strtolower($routine['item_param_type'][$i]), $no_support_types)) { + $retval .= "\n"; + } else { + $retval .= "\n"; + } + $retval .= "
\n"; + if ($GLOBALS['is_ajax_request'] != true) { + $retval .= "\n\n"; + $retval .= "
\n"; + $retval .= " \n"; + $retval .= "
\n"; + } else { + $retval .= ""; + $retval .= ""; + } + $retval .= "
\n\n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_RTN_getExecuteForm() + +?> diff --git a/libraries/rte/rte_triggers.lib.php b/libraries/rte/rte_triggers.lib.php new file mode 100644 index 0000000000..a80fca0876 --- /dev/null +++ b/libraries/rte/rte_triggers.lib.php @@ -0,0 +1,435 @@ + __('Add trigger'), + 'docu' => 'TRIGGERS', + 'export' => __('Export of trigger %s'), + 'human' => __('trigger'), + 'no_create' => __('You do not have the necessary privileges to create a new trigger'), + 'not_found' => __('No trigger with name %1$s found in database %2$s'), + 'nothing' => __('There are no triggers to display.'), + 'title' => __('Triggers'), + ); + return isset($words[$index]) ? $words[$index] : ''; +} // end PMA_RTE_getWord() + +/** + * Main function for the triggers functionality + */ +function PMA_RTE_main() +{ + global $db, $table; + + /** + * Process all requests + */ + PMA_TRI_handleEditor(); + PMA_TRI_handleExport(); + /** + * Display a list of available triggers + */ + $items = PMA_DBI_get_triggers($db, $table); + echo PMA_RTE_getList('trigger', $items); + /** + * Display a link for adding a new trigger, + * if the user has the necessary privileges + */ + echo PMA_TRI_getFooterLinks(); +} // end PMA_RTE_main() + +/** + * Handles editor requests for adding or editing an item + */ +function PMA_TRI_handleEditor() +{ + global $_REQUEST, $_POST, $errors, $db, $table; + + if (! empty($_REQUEST['editor_process_add']) + || ! empty($_REQUEST['editor_process_edit']) + ) { + $sql_query = ''; + + $item_query = PMA_TRI_getQueryFromRequest(); + + if (! count($errors)) { // set by PMA_RTN_getQueryFromRequest() + // Execute the created query + if (! empty($_REQUEST['editor_process_edit'])) { + // Backup the old trigger, in case something goes wrong + $trigger = PMA_TRI_getDataFromName($_REQUEST['item_original_name']); + $create_item = $trigger['create']; + $drop_item = $trigger['drop'] . ';'; + $result = PMA_DBI_try_query($drop_item); + if (! $result) { + $errors[] = sprintf(__('The following query has failed: "%s"'), $drop_item) . '
' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $result = PMA_DBI_try_query($item_query); + if (! $result) { + $errors[] = sprintf(__('The following query has failed: "%s"'), $item_query) . '
' + . __('MySQL said: ') . PMA_DBI_getError(null); + // We dropped the old item, but were unable to create the new one + // Try to restore the backup query + $result = PMA_DBI_try_query($create_item); + if (! $result) { + // OMG, this is really bad! We dropped the query, failed to create a new one + // and now even the backup query does not execute! + // This should not happen, but we better handle this just in case. + $errors[] = __('Sorry, we failed to restore the dropped trigger.') . '
' + . __('The backed up query was:') . "\"$create_item\"" . '
' + . __('MySQL said: ') . PMA_DBI_getError(null); + } + } else { + $message = PMA_Message::success(__('Trigger %1$s has been modified.')); + $message->addParam(PMA_backquote($_REQUEST['item_name'])); + $sql_query = $drop_item . $item_query; + } + } + } else { + // 'Add a new item' mode + $result = PMA_DBI_try_query($item_query); + if (! $result) { + $errors[] = sprintf(__('The following query has failed: "%s"'), $item_query) . '

' + . __('MySQL said: ') . PMA_DBI_getError(null); + } else { + $message = PMA_Message::success(__('Trigger %1$s has been created.')); + $message->addParam(PMA_backquote($_REQUEST['item_name'])); + $sql_query = $item_query; + } + } + } + + if (count($errors)) { + $message = PMA_Message::error(__('One or more errors have occured while processing your request:')); + $message->addString('
    '); + foreach ($errors as $num => $string) { + $message->addString('
  • ' . $string . '
  • '); + } + $message->addString('
'); + } + + $output = PMA_showMessage($message, $sql_query); + if ($GLOBALS['is_ajax_request']) { + $extra_data = array(); + if ($message->isSuccess()) { + $items = PMA_DBI_get_triggers($db, $table, ''); + $trigger = false; + foreach ($items as $key => $value) { + if ($value['name'] == $_REQUEST['item_name']) { + $trigger = $value; + } + } + $extra_data['insert'] = false; + if (empty($table) || ($trigger !== false && $table == $trigger['table'])) { + $extra_data['insert'] = true; + $extra_data['new_row'] = PMA_TRI_getRowForList($trigger); + $extra_data['name'] = htmlspecialchars( + strtoupper($_REQUEST['item_name']) + ); + } + $response = $output; + } else { + $response = $message; + } + PMA_ajaxResponse($response, $message->isSuccess(), $extra_data); + } + } + + /** + * Display a form used to add/edit a trigger, if necessary + */ + if (count($errors) || ( empty($_REQUEST['editor_process_add']) && empty($_REQUEST['editor_process_edit']) + && (! empty($_REQUEST['add_item']) || ! empty($_REQUEST['edit_item']))) // FIXME: this must be simpler than that + ) { + // Get the data for the form (if any) + if (! empty($_REQUEST['add_item'])) { + $title = __("Create trigger"); + $item = PMA_TRI_getDataFromRequest(); + $mode = 'add'; + } else if (! empty($_REQUEST['edit_item'])) { + $title = __("Edit trigger"); + if (! empty($_REQUEST['item_name']) + && empty($_REQUEST['editor_process_edit']) + ) { + $item = PMA_TRI_getDataFromName($_REQUEST['item_name']); + if ($item !== false) { + $item['item_original_name'] = $item['item_name']; + } + } else { + $item = PMA_TRI_getDataFromRequest(); + } + $mode = 'edit'; + } + if ($item !== false) { + // Show form + $editor = PMA_TRI_getEditorForm($mode, $item); + if ($GLOBALS['is_ajax_request']) { + $extra_data = array('title' => $title); + PMA_ajaxResponse($editor, true, $extra_data); + } else { + echo "\n\n

$title

\n\n$editor"; + unset($_POST); + require './libraries/footer.inc.php'; + } + // exit; + } else { + $message = __('Error in processing request') . ' : '; + $message .= sprintf( + PMA_RTE_getWord('not_found'), + htmlspecialchars(PMA_backquote($_REQUEST['item_name'])), + htmlspecialchars(PMA_backquote($db)) + ); + $message = PMA_message::error($message); + if ($GLOBALS['is_ajax_request']) { + PMA_ajaxResponse($message, false); + } else { + $message->display(); + } + } + } +} // end PMA_TRI_handleEditor() + +/** + * This function will generate the values that are required to for the editor + * + * @return array Data necessary to create the editor. + */ +function PMA_TRI_getDataFromRequest() +{ + $retval = array(); + $indices = array('item_name', + 'item_table', + 'item_original_name', + 'item_action_timing', + 'item_event_manipulation', + 'item_definition', + 'item_definer'); + foreach ($indices as $key => $index) { + $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : ''; + } + return $retval; +} // end PMA_TRI_getDataFromRequest() + +/** + * This function will generate the values that are required to complete + * the "Edit trigger" form given the name of a trigger. + * + * @param string $name The name of the trigger. + * + * @return array Data necessary to create the editor. + */ +function PMA_TRI_getDataFromName($name) +{ + global $db, $table, $_REQUEST; + + $temp = array(); + $items = PMA_DBI_get_triggers($db, $table, ''); + foreach ($items as $key => $value) { + if ($value['name'] == $name) { + $temp = $value; + } + } + if (empty($temp)) { + return false; + } else { + $retval = array(); + $retval['create'] = $temp['create']; + $retval['drop'] = $temp['drop']; + $retval['item_name'] = $temp['name']; + $retval['item_table'] = $temp['table']; + $retval['item_action_timing'] = $temp['action_timing']; + $retval['item_event_manipulation'] = $temp['event_manipulation']; + $retval['item_definition'] = $temp['definition']; + $retval['item_definer'] = $temp['definer']; + return $retval; + } +} // end PMA_TRI_getDataFromName() + +/** + * Displays a form used to add/edit a trigger + * + * @param string $mode If the editor will be used edit a trigger + * or add a new one: 'edit' or 'add'. + * @param array $item Data for the trigger returned by + * PMA_TRI_getDataFromRequest() or + * PMA_TRI_getDataFromName() + * + * @return string HTML code for the editor. + */ +function PMA_TRI_getEditorForm($mode, $item) +{ + global $db, $table, $titles, $event_manipulations, $action_timings; + + // Escape special characters + $need_escape = array( + 'item_original_name', + 'item_name', + 'item_definition', + 'item_definer' + ); + foreach ($need_escape as $key => $index) { + $item[$index] = htmlentities($item[$index], ENT_QUOTES); + } + $original_data = ''; + if ($mode == 'edit') { + $original_data = "\n"; + } + + // Create the output + $retval = ""; + $retval .= "\n\n"; + $retval .= "
\n"; + $retval .= "\n"; + $retval .= $original_data; + $retval .= PMA_generate_common_hidden_inputs($db, $table) . "\n"; + $retval .= "
\n"; + $retval .= "" . __('Details') . "\n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= "
" . __('Trigger name') . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
" . __('Time') . "
" . __('Event') . "
" . __('Definition') . "
" . __('Definer') . "\n"; + $retval .= "\n"; + } + $retval .= "\n\n"; + $retval .= "\n\n"; + + return $retval; +} // end PMA_TRI_getEditorForm() + +/** + * Composes the query necessary to create a trigger from an HTTP request. + * + * @return string The CREATE TRIGGER query. + */ +function PMA_TRI_getQueryFromRequest() +{ + global $_REQUEST, $db, $errors, $action_timings, $event_manipulations; + + $query = 'CREATE '; + if (! empty($_REQUEST['item_definer'])) { + if (strpos($_REQUEST['item_definer'], '@') !== false) { + $arr = explode('@', $_REQUEST['item_definer']); + $query .= 'DEFINER=' . PMA_backquote($arr[0]); + $query .= '@' . PMA_backquote($arr[1]) . ' '; + } else { + $errors[] = __('The definer must be in the "username@hostname" format'); + } + } + $query .= 'TRIGGER '; + if (! empty($_REQUEST['item_name'])) { + $query .= PMA_backquote($_REQUEST['item_name']) . ' '; + } else { + $errors[] = __('You must provide a trigger name'); + } + if (! empty($_REQUEST['item_timing']) && in_array($_REQUEST['item_timing'], $action_timings)) { + $query .= $_REQUEST['item_timing'] . ' '; + } else { + $errors[] = __('You must provide a valid timing for the trigger'); + } + if (! empty($_REQUEST['item_event']) && in_array($_REQUEST['item_event'], $event_manipulations)) { + $query .= $_REQUEST['item_event'] . ' '; + } else { + $errors[] = __('You must provide a valid event for the trigger'); + } + $query .= 'ON '; + if (! empty($_REQUEST['item_table']) && in_array($_REQUEST['item_table'], PMA_DBI_get_tables($db))) { + $query .= PMA_backQuote($_REQUEST['item_table']); + } else { + $errors[] = __('You must provide a valid table name'); + } + $query .= ' FOR EACH ROW '; + if (! empty($_REQUEST['item_definition'])) { + $query .= $_REQUEST['item_definition']; + } else { + $errors[] = __('You must provide a trigger definition.'); + } + + return $query; +} // end PMA_TRI_getQueryFromRequest() + +?> diff --git a/libraries/tbl_links.inc.php b/libraries/tbl_links.inc.php index 6282097507..5f24800f8d 100644 --- a/libraries/tbl_links.inc.php +++ b/libraries/tbl_links.inc.php @@ -98,10 +98,11 @@ if(PMA_Tracker::isActive()) { $tabs['tracking']['link'] = 'tbl_tracking.php'; } if (! $db_is_information_schema && PMA_MYSQL_INT_VERSION >= 50002 && ! PMA_DRIZZLE) { - // Temporarily hiding this unfinished feature - // $tabs['triggers']['link'] = 'tbl_triggers.php'; - // $tabs['triggers']['text'] = __('Triggers'); - // $tabs['triggers']['icon'] = 'b_triggers.png'; + if (PMA_currentUserHasPrivilege('TRIGGER', $db, $table)) { + $tabs['triggers']['link'] = 'tbl_triggers.php'; + $tabs['triggers']['text'] = __('Triggers'); + $tabs['triggers']['icon'] = 'b_triggers.png'; + } } /** diff --git a/po/br.po b/po/br.po index 6d92660791..a501c6e488 100644 --- a/po/br.po +++ b/po/br.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: phpMyAdmin 3.5.0-dev\n" "Report-Msgid-Bugs-To: phpmyadmin-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2011-07-07 15:16+0200\n" -"PO-Revision-Date: 2011-07-10 19:45+0200\n" +"PO-Revision-Date: 2011-07-11 20:39+0200\n" "Last-Translator: \n" "Language-Team: LANGUAGE \n" "Language: br\n" @@ -2825,7 +2825,7 @@ msgstr "Bannoù gronnet gant" #: libraries/config/messages.inc.php:249 libraries/import/csv.php:81 #: libraries/import/ldi.php:43 msgid "Columns escaped by" -msgstr "" +msgstr "Arouezenn dec'hout" #: libraries/config/messages.inc.php:77 libraries/config/messages.inc.php:83 #: libraries/config/messages.inc.php:90 libraries/config/messages.inc.php:99 @@ -2833,38 +2833,38 @@ msgstr "" #: libraries/config/messages.inc.php:142 libraries/config/messages.inc.php:145 #: libraries/config/messages.inc.php:147 libraries/export/texytext.php:27 msgid "Replace NULL by" -msgstr "" +msgstr "Erlec'hiañ NULL gant" #: libraries/config/messages.inc.php:78 libraries/config/messages.inc.php:84 msgid "Remove CRLF characters within columns" -msgstr "" +msgstr "Tennañ an arouezennoù dibenn linenn e dibarzh ar bannoù" #: libraries/config/messages.inc.php:79 libraries/config/messages.inc.php:245 #: libraries/config/messages.inc.php:253 libraries/import/csv.php:63 #: libraries/import/ldi.php:41 msgid "Columns terminated by" -msgstr "" +msgstr "Bannoù a echu gant" #: libraries/config/messages.inc.php:80 libraries/config/messages.inc.php:240 #: libraries/import/csv.php:86 libraries/import/ldi.php:44 msgid "Lines terminated by" -msgstr "" +msgstr "Linennoù a echu gant" #: libraries/config/messages.inc.php:82 msgid "Excel edition" -msgstr "" +msgstr "Stumm Excel" #: libraries/config/messages.inc.php:85 msgid "Database name template" -msgstr "" +msgstr "Patrom anv diaz roadennoù" #: libraries/config/messages.inc.php:86 msgid "Server name template" -msgstr "" +msgstr "Patrom anv servijer" #: libraries/config/messages.inc.php:87 msgid "Table name template" -msgstr "" +msgstr "Patrom anv taolenn" #: libraries/config/messages.inc.php:91 libraries/config/messages.inc.php:104 #: libraries/config/messages.inc.php:113 libraries/config/messages.inc.php:137 @@ -2872,74 +2872,74 @@ msgstr "" #: libraries/export/latex.php:40 libraries/export/odt.php:32 #: libraries/export/sql.php:116 libraries/export/texytext.php:23 msgid "Dump table" -msgstr "" +msgstr "Ezporzhiañ an daolenn" #: libraries/config/messages.inc.php:92 libraries/export/latex.php:32 msgid "Include table caption" -msgstr "" +msgstr "Enklozañ an istitloù" #: libraries/config/messages.inc.php:95 libraries/config/messages.inc.php:101 #: libraries/export/latex.php:50 libraries/export/latex.php:74 msgid "Table caption" -msgstr "" +msgstr "Istitl eus an daolenn" #: libraries/config/messages.inc.php:96 libraries/config/messages.inc.php:102 msgid "Continued table caption" -msgstr "" +msgstr "Enklozañ an istitloù" #: libraries/config/messages.inc.php:97 libraries/config/messages.inc.php:103 #: libraries/export/latex.php:54 libraries/export/latex.php:78 msgid "Label key" -msgstr "" +msgstr "Alc'hwez an dikedenn" #: libraries/config/messages.inc.php:98 libraries/config/messages.inc.php:110 #: libraries/config/messages.inc.php:134 libraries/export/odt.php:326 #: libraries/tbl_properties.inc.php:145 msgid "MIME type" -msgstr "" +msgstr "Seurt MIME" #: libraries/config/messages.inc.php:100 libraries/config/messages.inc.php:112 #: libraries/config/messages.inc.php:136 tbl_relation.php:396 msgid "Relations" -msgstr "" +msgstr "Darempredoù" #: libraries/config/messages.inc.php:105 msgid "Export method" -msgstr "" +msgstr "Doare ezporzhiañ" #: libraries/config/messages.inc.php:114 libraries/config/messages.inc.php:116 msgid "Save on server" -msgstr "" +msgstr "Enrollañ war ar servijer" #: libraries/config/messages.inc.php:115 libraries/config/messages.inc.php:117 #: libraries/display_export.lib.php:188 libraries/display_export.lib.php:214 msgid "Overwrite existing file(s)" -msgstr "" +msgstr "Frikañ ar restroù zo c'hoazh" #: libraries/config/messages.inc.php:118 msgid "Remember file name template" -msgstr "" +msgstr "Derc'hel soñj eus patrom anv ar restr" #: libraries/config/messages.inc.php:120 msgid "Enclose table and column names with backquotes" -msgstr "" +msgstr "Lakaat krochedoù stouet a bep tu da anvioù an taolennoù hag ar bannoù" #: libraries/config/messages.inc.php:121 libraries/config/messages.inc.php:260 #: libraries/display_export.lib.php:346 msgid "SQL compatibility mode" -msgstr "" +msgstr "Mod kenglotañ gant SQL" #: libraries/config/messages.inc.php:122 libraries/export/sql.php:176 msgid "CREATE TABLE options:" -msgstr "" +msgstr "Dibarzhioù evit CREATE TABLE :" #: libraries/config/messages.inc.php:123 msgid "Creation/Update/Check dates" -msgstr "" +msgstr "Deiziad krouiñ/hizivaat/gwiriañ" #: libraries/config/messages.inc.php:124 msgid "Use delayed inserts" -msgstr "" +msgstr "Ensoc'hadennoù gant dale" #: libraries/config/messages.inc.php:125 libraries/export/sql.php:79 msgid "Disable foreign key checks" diff --git a/po/da.po b/po/da.po index 6ee49126ff..65f4e7f5a4 100644 --- a/po/da.po +++ b/po/da.po @@ -4,7 +4,7 @@ msgstr "" "Project-Id-Version: phpMyAdmin 3.5.0-dev\n" "Report-Msgid-Bugs-To: phpmyadmin-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2011-07-07 15:16+0200\n" -"PO-Revision-Date: 2011-07-11 14:02+0200\n" +"PO-Revision-Date: 2011-07-11 15:49+0200\n" "Last-Translator: \n" "Language-Team: danish \n" "Language: da\n" @@ -2373,7 +2373,7 @@ msgstr "Der er ikke nogen filer at uploade" #: libraries/common.lib.php:2849 libraries/common.lib.php:2850 msgid "Execute" -msgstr "" +msgstr "Udfør" #: libraries/config.values.php:45 libraries/config.values.php:47 #: libraries/config.values.php:51 @@ -2411,12 +2411,11 @@ msgstr "struktur" #: libraries/export/latex.php:42 libraries/export/odt.php:34 #: libraries/export/sql.php:123 libraries/export/texytext.php:24 msgid "data" -msgstr "" +msgstr "data" #: libraries/config.values.php:98 libraries/export/htmlword.php:25 #: libraries/export/latex.php:42 libraries/export/odt.php:34 #: libraries/export/sql.php:124 libraries/export/texytext.php:24 -#, fuzzy #| msgid "Structure and data" msgid "structure and data" msgstr "Struktur og data" @@ -2622,7 +2621,7 @@ msgstr "" #: libraries/config/messages.inc.php:31 msgid "Bzip2" -msgstr "" +msgstr "Bzip2" #: libraries/config/messages.inc.php:32 msgid "" @@ -2830,7 +2829,6 @@ msgstr "Komprimering" #: libraries/export/latex.php:72 libraries/export/ods.php:25 #: libraries/export/odt.php:58 libraries/export/texytext.php:28 #: libraries/export/xls.php:25 libraries/export/xlsx.php:25 -#, fuzzy #| msgid "Put fields names in the first row" msgid "Put columns names in the first row" msgstr "Indsæt feltnavne i første række" @@ -2844,10 +2842,9 @@ msgstr "Felter skal adskilles med" #: libraries/config/messages.inc.php:76 libraries/config/messages.inc.php:242 #: libraries/config/messages.inc.php:249 libraries/import/csv.php:81 #: libraries/import/ldi.php:43 -#, fuzzy #| msgid "Fields escaped by" msgid "Columns escaped by" -msgstr "Felter escaped med" +msgstr "Kolonner escapes med" #: libraries/config/messages.inc.php:77 libraries/config/messages.inc.php:83 #: libraries/config/messages.inc.php:90 libraries/config/messages.inc.php:99 @@ -2859,21 +2856,20 @@ msgstr "Erstat NULL med" #: libraries/config/messages.inc.php:78 libraries/config/messages.inc.php:84 msgid "Remove CRLF characters within columns" -msgstr "Fjern karakterer for linjeskift i felterne" +msgstr "Fjern CRLF-karakterer i kolonnerne" #: libraries/config/messages.inc.php:79 libraries/config/messages.inc.php:245 #: libraries/config/messages.inc.php:253 libraries/import/csv.php:63 #: libraries/import/ldi.php:41 msgid "Columns terminated by" -msgstr "Felter afsluttes med" +msgstr "Kolonner afsluttes med" #: libraries/config/messages.inc.php:80 libraries/config/messages.inc.php:240 #: libraries/import/csv.php:86 libraries/import/ldi.php:44 msgid "Lines terminated by" -msgstr "Linjer afsluttet med" +msgstr "Linjer afsluttes med" #: libraries/config/messages.inc.php:82 -#, fuzzy #| msgid "Excel edition" msgid "Excel edition" msgstr "Excel-udgave" @@ -2884,11 +2880,11 @@ msgstr "Skabelon for databasenavn" #: libraries/config/messages.inc.php:86 msgid "Server name template" -msgstr "Maske for servernavn" +msgstr "Skabelon for servernavn" #: libraries/config/messages.inc.php:87 msgid "Table name template" -msgstr "Maske for tabelnavn" +msgstr "Skabelon for tabelnavn" #: libraries/config/messages.inc.php:91 libraries/config/messages.inc.php:104 #: libraries/config/messages.inc.php:113 libraries/config/messages.inc.php:137 @@ -2900,7 +2896,7 @@ msgstr "Dump tabel" #: libraries/config/messages.inc.php:92 libraries/export/latex.php:32 msgid "Include table caption" -msgstr "Inkluder tabeloverskrift" +msgstr "Inkludér tabeloverskrift" #: libraries/config/messages.inc.php:95 libraries/config/messages.inc.php:101 #: libraries/export/latex.php:50 libraries/export/latex.php:74 @@ -2913,6 +2909,7 @@ msgstr "Fortsat tabeloverskrift" #: libraries/config/messages.inc.php:97 libraries/config/messages.inc.php:103 #: libraries/export/latex.php:54 libraries/export/latex.php:78 +#, fuzzy msgid "Label key" msgstr "Mærke nøgle" @@ -2928,10 +2925,9 @@ msgid "Relations" msgstr "Relationer" #: libraries/config/messages.inc.php:105 -#, fuzzy #| msgid "Export type" msgid "Export method" -msgstr "Eksporttype" +msgstr "Eksport-type" #: libraries/config/messages.inc.php:114 libraries/config/messages.inc.php:116 msgid "Save on server" @@ -2944,7 +2940,7 @@ msgstr "Overskriv eksisterende fil(er)" #: libraries/config/messages.inc.php:118 msgid "Remember file name template" -msgstr "Husk maske for filnavn" +msgstr "Husk skabelon for filnavn" #: libraries/config/messages.inc.php:120 msgid "Enclose table and column names with backquotes" @@ -2953,11 +2949,11 @@ msgstr "Brug \"backquotes\" omkring tabel -og feltnavne" #: libraries/config/messages.inc.php:121 libraries/config/messages.inc.php:260 #: libraries/display_export.lib.php:346 msgid "SQL compatibility mode" -msgstr "SQL-kompatibilitetsmodus" +msgstr "SQL-kompatibilitets-tilstand" #: libraries/config/messages.inc.php:122 libraries/export/sql.php:176 msgid "CREATE TABLE options:" -msgstr "Muligheder for CREATE TABLE:" +msgstr "Indstillinger til CREATE TABLE:" #: libraries/config/messages.inc.php:123 msgid "Creation/Update/Check dates" @@ -2981,7 +2977,7 @@ msgstr "Brug ignorér inserts" #: libraries/config/messages.inc.php:132 msgid "Syntax to use when inserting data" -msgstr "Syntaks som skal bruges, når der indsættes data" +msgstr "Syntaks der bruges, når der indsættes data" #: libraries/config/messages.inc.php:133 libraries/export/sql.php:268 msgid "Maximal length of created query" @@ -3012,16 +3008,16 @@ msgid "" "Sort order for items in a foreign-key dropdown box; [kbd]content[/kbd] is " "the referenced data, [kbd]id[/kbd] is the key value" msgstr "" -"Sorteringsrækkefølge for elementer i valgboks med fremmede nøgler; [kbd]" -"content[/kbd] er de refererede data, [kbd]id[/kbd] er nøglens værdi" +"Sorteringsrækkefølge for elementer i valgboks med fremmede nøgler; " +"[kbd]content[/kbd] er de refererede data, [kbd]id[/kbd] er nøglens værdi" #: libraries/config/messages.inc.php:151 msgid "Foreign key dropdown order" -msgstr "Sortër fremmede nøgler i valgboks på:" +msgstr "Sortér fremmede nøgler i valgboks" #: libraries/config/messages.inc.php:152 msgid "A dropdown will be used if fewer items are present" -msgstr "Der vil blive brugt en valgboks, hvis der er færre elementer til stede" +msgstr "Der vil blive brugt en valgboks, hvis der er få elementer til stede" #: libraries/config/messages.inc.php:153 msgid "Foreign key limit" @@ -3064,7 +3060,7 @@ msgstr "Redigeringstilstand" #: libraries/config/messages.inc.php:163 msgid "Customize edit mode" -msgstr "Tilpas redigerinstilstand" +msgstr "Tilpas redigeringstilstand" #: libraries/config/messages.inc.php:165 msgid "Export defaults" @@ -3091,7 +3087,7 @@ msgstr "Bestem indstillinger for nogle af de mest anvendte valgmuligheder" #: libraries/server_links.inc.php:69 libraries/tbl_links.inc.php:89 #: prefs_manage.php:231 setup/frames/menu.inc.php:20 msgid "Import" -msgstr "Import" +msgstr "Importér" #: libraries/config/messages.inc.php:171 msgid "Import defaults" @@ -3146,13 +3142,12 @@ msgstr "Hovedramme" #: libraries/config/messages.inc.php:186 msgid "Microsoft Office" -msgstr "" +msgstr "Microsoft Office" #: libraries/config/messages.inc.php:188 -#, fuzzy #| msgid "Open Document Text" msgid "Open Document" -msgstr "Open Document tekst" +msgstr "Open Document" #: libraries/config/messages.inc.php:190 msgid "Other core settings" @@ -3171,14 +3166,17 @@ msgid "" "Specify browser's title bar text. Refer to [a@Documentation." "html#cfg_TitleTable]documentation[/a] for magic strings that can be used to " "get special values." -msgstr "Angiv browserens titeltekst. " +msgstr "" +"Angiv browserens tekst i titelbaren. Se " +"[a@Documentation.html#cfg_TitleTable]dokumentationen[/a] for tekststrenge " +"der indeholder særlige værdier." #: libraries/config/messages.inc.php:194 #: libraries/navigation_header.inc.php:83 #: libraries/navigation_header.inc.php:86 #: libraries/navigation_header.inc.php:89 msgid "Query window" -msgstr "Foresp. vindue" +msgstr "Forespørgselsvindue" #: libraries/config/messages.inc.php:195 msgid "Customize query window options" @@ -3193,8 +3191,8 @@ msgid "" "Please note that phpMyAdmin is just a user interface and its features do not " "limit MySQL" msgstr "" -"Bemærk venligst at phpMyAdmin blot er en brugerflade, hvis egenskaber ikke " -"begrænser MySQL" +"Bemærk venligst at phpMyAdmin blot er en brugerflade og at den ikke " +"begrænser mulighederne i MySQL" #: libraries/config/messages.inc.php:198 msgid "Basic settings" @@ -3218,7 +3216,7 @@ msgid "" "what they are for" msgstr "" "Avanceret serverkonfiguration. Lad være med at ændre disse indstillinger med " -"mindre, du ved, hvad de betyder" +"mindre du ved hvad de betyder" #: libraries/config/messages.inc.php:203 msgid "Enter server connection parameters" @@ -3234,16 +3232,21 @@ msgid "" "features, see [a@Documentation.html#linked-tables]phpMyAdmin configuration " "storage[/a] in documentation" msgstr "" +"Konfigurér phpMyAdmin configuration storage for at få adgang til flere " +"funktioner. Se dokumentationen for [a@Documentation.html#linked-" +"tables]phpMyAdmin configuration storage[/a]." #: libraries/config/messages.inc.php:206 msgid "Changes tracking" -msgstr "" +msgstr "Ændrer sporing" #: libraries/config/messages.inc.php:207 msgid "" "Tracking of changes made in database. Requires the phpMyAdmin configuration " "storage." msgstr "" +"Sporing af ændringer i databasen er udført. phpMyAdmin configuration storage " +"er krævet." #: libraries/config/messages.inc.php:208 msgid "Customize export options" @@ -3264,11 +3267,11 @@ msgstr "" #: libraries/config/messages.inc.php:213 libraries/config/messages.inc.php:218 #: setup/frames/menu.inc.php:17 msgid "SQL queries" -msgstr "" +msgstr "SQL-forespørgsler" #: libraries/config/messages.inc.php:215 msgid "SQL Query box" -msgstr "" +msgstr "SQL Query-boks" #: libraries/config/messages.inc.php:216 msgid "Customize links shown in SQL Query boxes" @@ -3296,7 +3299,7 @@ msgstr "" #: libraries/config/messages.inc.php:222 msgid "Startup" -msgstr "" +msgstr "Opstart" #: libraries/config/messages.inc.php:223 msgid "Customize startup page" @@ -3304,7 +3307,7 @@ msgstr "" #: libraries/config/messages.inc.php:224 msgid "Tabs" -msgstr "" +msgstr "Faner" #: libraries/config/messages.inc.php:225 msgid "Choose how you want tabs to work" @@ -3328,7 +3331,7 @@ msgstr "" #: libraries/config/messages.inc.php:230 msgid "Warnings" -msgstr "" +msgstr "Advarsler" #: libraries/config/messages.inc.php:231 msgid "Disable some of the warnings shown by phpMyAdmin" diff --git a/po/de.po b/po/de.po index c75838e48d..ba4c35bfee 100644 --- a/po/de.po +++ b/po/de.po @@ -4,7 +4,7 @@ msgstr "" "Project-Id-Version: phpMyAdmin 3.5.0-dev\n" "Report-Msgid-Bugs-To: phpmyadmin-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2011-07-07 15:16+0200\n" -"PO-Revision-Date: 2011-07-11 09:26+0200\n" +"PO-Revision-Date: 2011-07-12 23:07+0200\n" "Last-Translator: \n" "Language-Team: german \n" "Language: de\n" @@ -957,10 +957,11 @@ msgstr "" msgid "The web server does not have permission to save the file %s." msgstr "Der Webserver hat keine Schreibrechte um die Datei %s zu speichern." +# Schema is not the right word for it, because a dump contains also data, and NOT just the scheme. #: export.php:673 #, php-format msgid "Dump has been saved to file %s." -msgstr "Dump (Schema) wurde in Datei %s gespeichert." +msgstr "Dump wurde in Datei %s gespeichert." #: import.php:57 #, php-format @@ -3411,7 +3412,7 @@ msgstr "Prozentwerte als Dezimalzahlen importieren (12.00% wird zu 0.12)" #: libraries/config/messages.inc.php:258 msgid "Number of queries to skip from start" -msgstr "Anzahl der am Anfang zu überspringenden Einträge (Abfragen)" +msgstr "Anzahl der am Anfang zu überspringenden Abfragen" #: libraries/config/messages.inc.php:259 msgid "Partial import: skip queries" @@ -4056,10 +4057,10 @@ msgid "" "alphabetical order." msgstr "" "MySQL Wildcard-Symbole (% und _) sind möglich, mit \\ wird die urspüngliche " -"Bedeutung wiederhergestellt, d.h. 'my\\_db' und nicht 'my_db'. Mit dieser " -"Optionen können Datenbanklisten sortiert werden; geben Sie ihre Namen " -"sortiert ein und nutzen Sie am Ende [kbd]*[/kbd], um die übrigen in " -"alphabetischer Reihenfolge anzuzeigen." +"Bedeutung wiederhergestellt, d.h. [kbd]'my\\_db'[/kbd] und nicht " +"[kbd]'my_db'[/kbd]. Mit dieser Optionen können Datenbanklisten sortiert " +"werden; geben Sie ihre Namen sortiert ein und nutzen Sie am Ende " +"[kbd]*[/kbd], um die übrigen in alphabetischer Reihenfolge anzuzeigen." #: libraries/config/messages.inc.php:400 msgid "Show only listed databases" @@ -5561,7 +5562,7 @@ msgstr "Unbenutzte Seiten" #: libraries/engines/innodb.lib.php:176 msgid "Dirty pages" -msgstr "Inkonsistente Seiten ("dirty")" +msgstr "Inkonsistente Seiten" #: libraries/engines/innodb.lib.php:182 msgid "Pages containing data" @@ -7298,7 +7299,7 @@ msgstr "" "können. In der ersten Möglichkeit benennen Sie den Dateinamen. Als zweite " "Option wird ein Spaltenname durch den Dateinamen gesetzt. Sollte die zweite " "Option gesetzt sein, ist es notwendig, die erste Option auf einen Leerstring " -"zu setzen ('')." +"zu setzen." #: libraries/transformations/application_octetstream__hex.inc.php:9 msgid "" @@ -7315,8 +7316,8 @@ msgid "" "Displays a clickable thumbnail. The options are the maximum width and height " "in pixels. The original aspect ratio is preserved." msgstr "" -"Ein klickbares Vorschaubild anzeigen. Optionen: Breite, Höhe in Pixeln " -"(berücksichtigt das ursprüngliche Seitenverhältnis)." +"Ein klickbares Vorschaubild anzeigen. Optionen: Breite und Höhe in Pixeln, " +"wobei das ursprüngliche Seitenverhältnis berücksichtigt wird." #: libraries/transformations/image_jpeg__link.inc.php:9 msgid "Displays a link to download this image." @@ -8704,7 +8705,7 @@ msgstr "Transaktions-Koordinator" #: server_status.php:285 msgid "Flush (close) all tables" -msgstr "Alle Tabellen aktualisieren und schließen" +msgstr "Alle Tabellen aktualisieren (und schließen)" #: server_status.php:287 msgid "Show open tables" @@ -8826,8 +8827,8 @@ msgid "" "On a busy server, the byte counters may overrun, so those statistics as " "reported by the MySQL server may be incorrect." msgstr "" -"Auf stark frequentierten Server können die Byte-Zähler überlaufen (wieder " -"bei 0 beginnen), deshalb können diese Werte, wie sie vom MySQL Server " +"Auf stark frequentierten Server können die Byte-Zähler überlaufen, d.h. " +"wieder bei 0 beginnen, deshalb können diese Werte, wie sie vom MySQL Server " "ausgegeben werden, falsch sein." #: server_status.php:681 diff --git a/po/el.po b/po/el.po index 6ad5b3e058..0e34a18589 100644 --- a/po/el.po +++ b/po/el.po @@ -4,7 +4,7 @@ msgstr "" "Project-Id-Version: phpMyAdmin 3.5.0-dev\n" "Report-Msgid-Bugs-To: phpmyadmin-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2011-07-07 15:16+0200\n" -"PO-Revision-Date: 2011-07-07 12:37+0200\n" +"PO-Revision-Date: 2011-07-13 09:17+0200\n" "Last-Translator: Panagiotis Papazoglou \n" "Language-Team: greek \n" "Language: el\n" @@ -5375,10 +5375,10 @@ msgid "vertical" msgstr "κάθετη" #: libraries/display_tbl.lib.php:452 -#, fuzzy, php-format +#, php-format #| msgid "Headers every" msgid "Headers every %s rows" -msgstr "Κεφαλίδες κάθε" +msgstr "Κεφαλίδες κάθε %s εγγραφές" #: libraries/display_tbl.lib.php:546 msgid "Sort by key" diff --git a/po/sl.po b/po/sl.po index fa62c87e5b..c960c51c83 100644 --- a/po/sl.po +++ b/po/sl.po @@ -4,15 +4,15 @@ msgstr "" "Project-Id-Version: phpMyAdmin 3.5.0-dev\n" "Report-Msgid-Bugs-To: phpmyadmin-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2011-07-07 15:16+0200\n" -"PO-Revision-Date: 2011-07-07 11:50+0200\n" +"PO-Revision-Date: 2011-07-11 21:13+0200\n" "Last-Translator: Domen \n" "Language-Team: slovenian \n" "Language: sl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" -"%100==4 ? 2 : 3);\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || " +"n%100==4 ? 2 : 3);\n" "X-Generator: Pootle 2.0.5\n" #: browse_foreigners.php:35 browse_foreigners.php:53 @@ -5319,10 +5319,10 @@ msgid "vertical" msgstr "navpičnem" #: libraries/display_tbl.lib.php:452 -#, fuzzy, php-format +#, php-format #| msgid "Headers every" msgid "Headers every %s rows" -msgstr "Glave vsakih" +msgstr "Glave vsakih %s vrstic" #: libraries/display_tbl.lib.php:546 msgid "Sort by key" diff --git a/tbl_triggers.php b/tbl_triggers.php index bf9cbbc632..a5d8a3e70a 100644 --- a/tbl_triggers.php +++ b/tbl_triggers.php @@ -1,35 +1 @@ - + diff --git a/themes/original/css/theme_right.css.php b/themes/original/css/theme_right.css.php index 8c5e53e479..4f21c7ec50 100644 --- a/themes/original/css/theme_right.css.php +++ b/themes/original/css/theme_right.css.php @@ -1860,6 +1860,10 @@ fieldset .disabled-field td { vertical-align: middle; } +.rte_table tr td:nth-child(1) { + font-weight: bold; +} + .rte_table input, .rte_table select, .rte_table textarea { width: 100%; margin: 0; @@ -1868,6 +1872,11 @@ fieldset .disabled-field td { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; } + +.rte_table .routine_params_table { + width: 100%; +} + #placeholder .button { position: absolute; cursor: pointer; @@ -1880,6 +1889,56 @@ fieldset .disabled-field td { padding: 2px; } +.wrapper { + float: ; + margin-bottom: 0.5em; +} +.toggleButton { + position: relative; + cursor: pointer; + font-size: 0.8em; + text-align: center; + line-height: 1.55em; + height: 1.55em; + overflow: hidden; + border-right: 0.1em solid #888; + border-left: 0.1em solid #888; +} +.toggleButton table, +.toggleButton td, +.toggleButton img { + padding: 0; + position: relative; +} +.toggleButton .container { + position: absolute; +} +.toggleButton .toggleOn { + color: white; + padding: 0 1em; +} +.toggleButton .toggleOff { + padding: 0 1em; +} + +.doubleFieldset fieldset { + width: 48%; + float: ; + padding: 0; +} +.doubleFieldset fieldset.left { + margin-: 1%; +} +.doubleFieldset fieldset.right { + margin-: 1%; +} +.doubleFieldset legend { + margin-: 0.5em; +} +.doubleFieldset div.wrap { + padding: 0.5em; +} + #table_columns input, #table_columns select { width: 14em; box-sizing: border-box; diff --git a/themes/original/img/toggle-ltr.png b/themes/original/img/toggle-ltr.png new file mode 100644 index 0000000000..bc312a9e39 Binary files /dev/null and b/themes/original/img/toggle-ltr.png differ diff --git a/themes/original/img/toggle-rtl.png b/themes/original/img/toggle-rtl.png new file mode 100644 index 0000000000..e81640e916 Binary files /dev/null and b/themes/original/img/toggle-rtl.png differ diff --git a/themes/pmahomme/css/theme_right.css.php b/themes/pmahomme/css/theme_right.css.php index a84159ca9b..3e2b5ed6b4 100644 --- a/themes/pmahomme/css/theme_right.css.php +++ b/themes/pmahomme/css/theme_right.css.php @@ -2222,6 +2222,10 @@ fieldset .disabled-field td { vertical-align: middle; } +.rte_table tr td:nth-child(1) { + font-weight: bold; +} + .rte_table input, .rte_table select, .rte_table textarea { width: 100%; margin: 0; @@ -2231,6 +2235,10 @@ fieldset .disabled-field td { -webkit-box-sizing: border-box; } +.rte_table .routine_params_table { + width: 100%; +} + #placeholder .button { position: absolute; cursor: pointer; @@ -2243,6 +2251,60 @@ fieldset .disabled-field td { padding: 2px; } +.wrapper { + float: ; + margin-bottom: 1.5em; +} +.toggleButton { + position: relative; + cursor: pointer; + font-size: 0.8em; + text-align: center; + line-height: 1.55em; + height: 1.55em; + overflow: hidden; + border-right: 0.1em solid #888; + border-left: 0.1em solid #888; + -webkit-border-radius: 0.3em; + -moz-border-radius: 0.3em; + border-radius: 0.3em; +} +.toggleButton table, +.toggleButton td, +.toggleButton img { + padding: 0; + position: relative; +} +.toggleButton .container { + position: absolute; +} +.toggleButton .toggleOn { + color: white; + padding: 0 1em; + text-shadow: 0px 0px 0.2em #000; +} +.toggleButton .toggleOff { + padding: 0 1em; +} + +.doubleFieldset fieldset { + width: 48%; + float: ; + padding: 0; +} +.doubleFieldset fieldset.left { + margin-: 1%; +} +.doubleFieldset fieldset.right { + margin-: 1%; +} +.doubleFieldset legend { + margin-: 1.5em; +} +.doubleFieldset div.wrap { + padding: 1.5em; +} + #table_columns input, #table_columns select { width: 14em; box-sizing: border-box; diff --git a/themes/pmahomme/img/toggle-ltr.png b/themes/pmahomme/img/toggle-ltr.png new file mode 100644 index 0000000000..6dce09c51c Binary files /dev/null and b/themes/pmahomme/img/toggle-ltr.png differ diff --git a/themes/pmahomme/img/toggle-rtl.png b/themes/pmahomme/img/toggle-rtl.png new file mode 100644 index 0000000000..5b14cefa37 Binary files /dev/null and b/themes/pmahomme/img/toggle-rtl.png differ