diff --git a/db_events.php b/db_events.php index 3bd6a05b05..92454807ed 100644 --- a/db_events.php +++ b/db_events.php @@ -16,7 +16,9 @@ require_once './libraries/common.lib.php'; * Include JavaScript libraries */ $GLOBALS['js_include'][] = 'jquery/jquery-ui-1.8.custom.js'; +$GLOBALS['js_include'][] = 'jquery/timepicker.js'; $GLOBALS['js_include'][] = 'db_events.js'; +$GLOBALS['js_include'][] = 'db_routines.js'; // FIXME /** * Include all other files diff --git a/js/db_routines.js b/js/db_routines.js index 4491df9713..3d1812b01d 100644 --- a/js/db_routines.js +++ b/js/db_routines.js @@ -479,6 +479,16 @@ $(document).ready(function() { $('.routine_return_row, .routine_direction_cell').toggle(); }); // end $.live() + /** + * Attach Ajax event handlers for the "Change event type" functionality. + * + * @see $cfg['AjaxEnable'] + * TODO: merge with above + */ + $('select[name=item_type]').live('change', function() { + $('.recurring_event_row, .onetime_event_row').toggle(); + }); // end $.live() + /** * Attach Ajax event handlers for the "Change parameter type" functionality. * diff --git a/libraries/rte/rte_events.lib.php b/libraries/rte/rte_events.lib.php index cf6046791d..d54805af7d 100644 --- a/libraries/rte/rte_events.lib.php +++ b/libraries/rte/rte_events.lib.php @@ -8,7 +8,7 @@ if (! defined('PHPMYADMIN')) { } /** - * Main function for the routines functionality + * Main function for the events functionality */ function PMA_EVN_main() { @@ -18,10 +18,11 @@ function PMA_EVN_main() * Here we define some data that will be used to create the list events */ $human_name = __('event'); - $columns = "`EVENT_NAME`, `EVENT_TYPE`"; + $columns = "`EVENT_NAME`, `EVENT_TYPE`, `STATUS`"; $where = "EVENT_SCHEMA='" . PMA_sqlAddSlashes($db) . "'"; $items = PMA_DBI_fetch_result("SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE $where ORDER BY `EVENT_NAME` ASC;"); $cols = array(array('label' => __('Name'), 'colspan' => 1, 'field' => 'name'), + array('label' => __('Status'), 'colspan' => 1, 'field' => 'status'), array('label' => __('Action'), 'colspan' => 3, 'field' => 'edit'), array( 'field' => 'export'), array( 'field' => 'drop'), @@ -33,6 +34,7 @@ function PMA_EVN_main() /** * Process all requests */ + PMA_EVN_handleEditor(); PMA_EVN_handleExport(); /** * Display a list of available events @@ -46,4 +48,449 @@ function PMA_EVN_main() echo PMA_EVN_getFooterLinks(); } // end PMA_EVN_main() +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(''); + } + + $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_RTE_getRowForList('event', $event, 0); + $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['original_name'] = $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, + 'editor' => 'event'); + 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') . ' : ' + . sprintf(__('No event with name %1$s found in database %2$s'), + 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(); + } + } + } +} + +function PMA_EVN_getDataFromRequest() +{ + $retval = array(); + + $retval['name'] = ''; + if (isset($_REQUEST['item_name'])) { + $retval['name'] = $_REQUEST['item_name']; + } + $retval['original_name'] = ''; + if (isset($_REQUEST['item_original_name'])) { + $retval['original_name'] = $_REQUEST['item_original_name']; + } + $retval['status'] = ''; + if (isset($_REQUEST['item_status'])) { + $retval['status'] = $_REQUEST['item_status']; + } + $retval['type'] = 'ONE TIME'; + $retval['type_toggle'] = 'RECURRING'; + if (isset($_REQUEST['item_type']) && $_REQUEST['item_type'] == 'RECURRING') { + $retval['type'] = 'RECURRING'; + $retval['type_toggle'] = 'ONE TIME'; + } + $retval['execute_at'] = ''; + if (isset($_REQUEST['item_execute_at'])) { + $retval['execute_at'] = $_REQUEST['item_execute_at']; + } + $retval['interval_value'] = ''; + if (isset($_REQUEST['item_interval_value'])) { + $retval['interval_value'] = $_REQUEST['item_interval_value']; + } + $retval['interval_field'] = ''; + if (isset($_REQUEST['item_interval_field'])) { + $retval['interval_field'] = $_REQUEST['item_interval_field']; + } + $retval['starts'] = ''; + if (isset($_REQUEST['item_starts'])) { + $retval['starts'] = $_REQUEST['item_starts']; + } + $retval['ends'] = ''; + if (isset($_REQUEST['item_ends'])) { + $retval['ends'] = $_REQUEST['item_ends']; + } + $retval['definition'] = ''; + if (isset($_REQUEST['item_definition'])) { + $retval['definition'] = $_REQUEST['item_definition']; + } + $retval['preserve'] = ''; + if (isset($_REQUEST['item_preserve'])) { + $retval['preserve'] = $_REQUEST['item_preserve']; + } + $retval['definer'] = ''; + if (isset($_REQUEST['item_definer'])) { + $retval['definer'] = $_REQUEST['item_definer']; + } + $retval['comment'] = ''; + if (isset($_REQUEST['item_comment'])) { + $retval['comment'] = $_REQUEST['item_comment']; + } + + return $retval; +} + +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['name'] = $item['EVENT_NAME']; + $retval['status'] = $item['STATUS']; + $retval['type'] = $item['EVENT_TYPE']; + if ($retval['type'] == 'RECURRING') { + $retval['type_toggle'] = 'ONE TIME'; + } else { + $retval['type_toggle'] = 'RECURRING'; + } + $retval['execute_at'] = $item['EXECUTE_AT']; + $retval['interval_value'] = $item['INTERVAL_VALUE']; + $retval['interval_field'] = $item['INTERVAL_FIELD']; + $retval['starts'] = $item['STARTS']; + $retval['ends'] = $item['ENDS']; + $retval['preserve'] = ''; + if ($item['ON_COMPLETION'] == 'PRESERVE') { + $retval['preserve'] = " checked='checked'"; + } + $retval['definition'] = $item['EVENT_DEFINITION']; + $retval['definer'] = $item['DEFINER']; + $retval['comment'] = $item['EVENT_COMMENT']; + + return $retval; +} + +function PMA_EVN_getEditorForm($mode, $operation, $item) +{ + global $db, $table, $titles, $event_status, $event_type, $event_interval; + + // Escape special characters + $need_escape = array( + 'original_name', + 'name', + 'type', + 'execute_at', + 'interval_value', + 'starts', + 'ends', + 'definition', + 'definer', + '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['type'] == 'RECURRING') { + $item['type'] = 'ONE TIME'; + $item['type_toggle'] = 'RECURRING'; + } else { + $item['type'] = 'RECURRING'; + $item['type_toggle'] = 'ONE TIME'; + } + } + if ($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"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "\n"; + $retval .= "\n"; + $retval .= " \n"; + $retval .= "
" . __('Event name') . "
" . __('Status') . "\n"; + $retval .= " \n"; + $retval .= "
" . __('Event type') . "\n"; + if ($GLOBALS['is_ajax_request']) { + $retval .= " \n"; + } else { + $retval .= " \n"; + $retval .= "
\n"; + $retval .= " {$item['type']}\n"; + $retval .= "
\n"; + $retval .= " \n"; + } + $retval .= "
" . __('Execute at') . "\n"; + $retval .= " \n"; + $retval .= "
" . __('Execute every') . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
" . __('Start') . "
" . __('End') . "
" . __('Definition') . "
" . __('On completion preserve') . "
" . __('Definer') . "\n"; + $retval .= " \n"; + $retval .= "\n"; + } + $retval .= "\n\n"; + $retval .= "\n\n"; + + return $retval; +} + +function PMA_EVN_getQueryFromRequest() // FIXME: need better error checking here +{ + global $_REQUEST, $cfg, $db, $errors, $event_status; + + $query = 'CREATE '; + if (! empty($_REQUEST['item_definer']) && strpos($_REQUEST['item_definer'], '@') !== false) { + $arr = explode('@', $_REQUEST['item_definer']); + $query .= 'DEFINER=' . PMA_backquote($arr[0]) . '@' . PMA_backquote($arr[1]) . ' '; + } + $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 ($_REQUEST['item_type'] == 'RECURRING') { + $query .= 'EVERY ' . $_REQUEST['item_interval_value'] . ' '; + $query .= $_REQUEST['item_interval_field'] . ' '; + if (! empty($_REQUEST['item_starts'])) { + $query .= "STARTS '" . $_REQUEST['item_starts'] . "' "; + } + if (! empty($_REQUEST['item_ends'])) { + $query .= "ENDS '" . $_REQUEST['item_ends'] . "' "; + } + } else { + $query .= "AT '" . $_REQUEST['item_execute_at'] . "' "; + } + $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; +} + ?> diff --git a/libraries/rte/rte_list.lib.php b/libraries/rte/rte_list.lib.php index fffd2a447f..a9adf6b12b 100644 --- a/libraries/rte/rte_list.lib.php +++ b/libraries/rte/rte_list.lib.php @@ -257,8 +257,17 @@ function PMA_EVN_getCellForList($field, $event) $retval = "$sql_drop" . "" . htmlspecialchars($event['EVENT_NAME']) . ""; break; + case 'status': + $retval = $event['STATUS']; + break; case 'edit': $retval = $titles['NoEdit']; + if (PMA_currentUserHasPrivilege('EVENT', $db)) { + $retval = '' . $titles['Edit'] . ''; + } break; case 'export': $retval = '" . __('Details') . "\n"; $retval .= "\n"; $retval .= "\n"; - $retval .= " \n"; + $retval .= " \n"; $retval .= " \n"; $retval .= "\n"; $retval .= "\n"; diff --git a/libraries/rte/rte_triggers.lib.php b/libraries/rte/rte_triggers.lib.php index ef6d6c5ceb..c6edccf70a 100644 --- a/libraries/rte/rte_triggers.lib.php +++ b/libraries/rte/rte_triggers.lib.php @@ -272,7 +272,7 @@ function PMA_TRI_getEditorForm($mode, $item) $retval .= "" . __('Details') . "\n"; $retval .= "
" . __('Routine name') . "" . __('Routine name') . "
\n"; $retval .= "\n"; - $retval .= " \n"; + $retval .= " \n"; $retval .= " \n"; $retval .= "\n"; $retval .= "\n";
" . __('Trigger name') . "" . __('Trigger name') . "