From 2e52c0f1f816c2a528aec7b795232ab4ad121eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Fri, 8 Sep 2017 13:09:13 -0300 Subject: [PATCH] Refactor rte_events functions to static methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MaurĂ­cio Meneghini Fauth --- db_events.php | 5 - libraries/classes/Rte/Events.php | 622 ++++++++++++++++++ libraries/rte/rte_events.lib.php | 615 ----------------- libraries/rte/rte_general.lib.php | 3 +- libraries/rte/rte_main.inc.php | 4 +- test/classes/Rte/EventsTest.php | 527 +++++++++++++++ .../rte/PMA_EVN_getDataFromRequest_test.php | 120 ---- .../rte/PMA_EVN_getEditorForm_test.php | 283 -------- .../rte/PMA_EVN_getQueryFromRequest_test.php | 175 ----- 9 files changed, 1153 insertions(+), 1201 deletions(-) create mode 100644 libraries/classes/Rte/Events.php delete mode 100644 libraries/rte/rte_events.lib.php create mode 100644 test/classes/Rte/EventsTest.php delete mode 100644 test/libraries/rte/PMA_EVN_getDataFromRequest_test.php delete mode 100644 test/libraries/rte/PMA_EVN_getEditorForm_test.php delete mode 100644 test/libraries/rte/PMA_EVN_getQueryFromRequest_test.php diff --git a/db_events.php b/db_events.php index 606b5d22fe..e13935fc68 100644 --- a/db_events.php +++ b/db_events.php @@ -11,11 +11,6 @@ */ require_once 'libraries/common.inc.php'; -/** - * Include all other files - */ -require_once 'libraries/rte/rte_events.lib.php'; - /** * Do the magic */ diff --git a/libraries/classes/Rte/Events.php b/libraries/classes/Rte/Events.php new file mode 100644 index 0000000000..b88ce3a9f5 --- /dev/null +++ b/libraries/classes/Rte/Events.php @@ -0,0 +1,622 @@ + 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'); + } + + /** + * Main function for the events functionality + * + * @return void + */ + public static function main() + { + global $db; + + self::setGlobals(); + /** + * Process all requests + */ + self::handleEditor(); + PMA_EVN_handleExport(); + /** + * Display a list of available events + */ + $items = $GLOBALS['dbi']->getEvents($db); + 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 self::main() + + /** + * Handles editor requests for adding or editing an item + * + * @return void + */ + public static function handleEditor() + { + global $_REQUEST, $_POST, $errors, $db; + + if (! empty($_REQUEST['editor_process_add']) + || ! empty($_REQUEST['editor_process_edit']) + ) { + $sql_query = ''; + + $item_query = self::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 = $GLOBALS['dbi']->getDefinition( + $db, + 'EVENT', + $_REQUEST['item_original_name'] + ); + $drop_item = "DROP EVENT " + . Util::backquote($_REQUEST['item_original_name']) + . ";\n"; + $result = $GLOBALS['dbi']->tryQuery($drop_item); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($drop_item) + ) + . '
' + . __('MySQL said: ') . $GLOBALS['dbi']->getError(null); + } else { + $result = $GLOBALS['dbi']->tryQuery($item_query); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($item_query) + ) + . '
' + . __('MySQL said: ') . $GLOBALS['dbi']->getError(null); + // We dropped the old item, but were unable to create + // the new one. Try to restore the backup query + $result = $GLOBALS['dbi']->tryQuery($create_item); + $errors = checkResult( + $result, + __( + 'Sorry, we failed to restore the dropped event.' + ), + $create_item, + $errors + ); + } else { + $message = Message::success( + __('Event %1$s has been modified.') + ); + $message->addParam( + Util::backquote($_REQUEST['item_name']) + ); + $sql_query = $drop_item . $item_query; + } + } + } else { + // 'Add a new item' mode + $result = $GLOBALS['dbi']->tryQuery($item_query); + if (! $result) { + $errors[] = sprintf( + __('The following query has failed: "%s"'), + htmlspecialchars($item_query) + ) + . '

' + . __('MySQL said: ') . $GLOBALS['dbi']->getError(null); + } else { + $message = Message::success( + __('Event %1$s has been created.') + ); + $message->addParam( + Util::backquote($_REQUEST['item_name']) + ); + $sql_query = $item_query; + } + } + } + + if (count($errors)) { + $message = Message::error( + '' + . __( + 'One or more errors have occurred while processing your request:' + ) + . '' + ); + $message->addHtml(''); + } + + $output = Util::getMessage($message, $sql_query); + $response = Response::getInstance(); + if ($response->isAjax()) { + if ($message->isSuccess()) { + $events = $GLOBALS['dbi']->getEvents($db, $_REQUEST['item_name']); + $event = $events[0]; + $response->addJSON( + 'name', + htmlspecialchars( + mb_strtoupper($_REQUEST['item_name']) + ) + ); + $response->addJSON('new_row', PMA_EVN_getRowForList($event)); + $response->addJSON('insert', ! empty($event)); + $response->addJSON('message', $output); + } else { + $response->setRequestStatus(false); + $response->addJSON('message', $message); + } + exit; + } + } + /** + * 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 = PMA_RTE_getWord('add'); + $item = self::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 = self::getDataFromName($_REQUEST['item_name']); + if ($item !== false) { + $item['item_original_name'] = $item['item_name']; + } + } else { + $item = self::getDataFromRequest(); + } + $mode = 'edit'; + } + PMA_RTE_sendEditor('EVN', $mode, $item, $title, $db, $operation); + } + } // end self::handleEditor() + + /** + * This function will generate the values that are required to for the editor + * + * @return array Data necessary to create the editor. + */ + public static function 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 $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 self::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. + */ + public static function 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 " . Util::getCollateForIS() . "=" + . "'" . $GLOBALS['dbi']->escapeString($db) . "' " + . "AND EVENT_NAME='" . $GLOBALS['dbi']->escapeString($name) . "'"; + $query = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE $where;"; + $item = $GLOBALS['dbi']->fetchSingleRow($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 self::getDataFromName() + + /** + * Displays a form used to add/edit an event + * + * @param string $mode If the editor will be used to 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 + * self::getDataFromRequest() or + * self::getDataFromName() + * + * @return string HTML code for the editor. + */ + public static function getEditorForm($mode, $operation, $item) + { + global $db, $table, $event_status, $event_type, $event_interval; + + $modeToUpper = mb_strtoupper($mode); + + $response = Response::getInstance(); + + // 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 $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 .= Url::getHiddenInputs($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 .= "
" . __('Event name') . "\n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
" . __('Event type') . "\n"; + if ($response->isAjax()) { + $retval .= " \n"; + } else { + $retval .= " \n"; + $retval .= " {$item['item_type']}\n"; + $retval .= " \n"; + $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 .= "
" . _pgettext('Start of recurring event', 'Start'); + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= " \n"; + $retval .= "
" . __('On completion preserve') . "\n"; + $retval .= " \n"; + $retval .= " isAjax()) { + $retval .= "\n"; + $retval .= "\n"; + } + $retval .= "\n\n"; + $retval .= "\n\n"; + + return $retval; + } // end self::getEditorForm() + + /** + * Composes the query necessary to create an event from an HTTP request. + * + * @return string The CREATE EVENT query. + */ + public static function getQueryFromRequest() + { + global $_REQUEST, $errors, $event_status, $event_type, $event_interval; + + $query = 'CREATE '; + if (! empty($_REQUEST['item_definer'])) { + if (mb_strpos($_REQUEST['item_definer'], '@') !== false + ) { + $arr = explode('@', $_REQUEST['item_definer']); + $query .= 'DEFINER=' . Util::backquote($arr[0]); + $query .= '@' . Util::backquote($arr[1]) . ' '; + } else { + $errors[] = __('The definer must be in the "username@hostname" format!'); + } + } + $query .= 'EVENT '; + if (! empty($_REQUEST['item_name'])) { + $query .= Util::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 '" + . $GLOBALS['dbi']->escapeString($_REQUEST['item_starts']) + . "' "; + } + if (! empty($_REQUEST['item_ends'])) { + $query .= "ENDS '" + . $GLOBALS['dbi']->escapeString($_REQUEST['item_ends']) + . "' "; + } + } else { + if (! empty($_REQUEST['item_execute_at'])) { + $query .= "AT '" + . $GLOBALS['dbi']->escapeString($_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; + } + } + } + if (! empty($_REQUEST['item_comment'])) { + $query .= "COMMENT '" . $GLOBALS['dbi']->escapeString( + $_REQUEST['item_comment'] + ) . "' "; + } + $query .= 'DO '; + if (! empty($_REQUEST['item_definition'])) { + $query .= $_REQUEST['item_definition']; + } else { + $errors[] = __('You must provide an event definition.'); + } + + return $query; + } // end self::getQueryFromRequest() +} diff --git a/libraries/rte/rte_events.lib.php b/libraries/rte/rte_events.lib.php deleted file mode 100644 index 8204db63d1..0000000000 --- a/libraries/rte/rte_events.lib.php +++ /dev/null @@ -1,615 +0,0 @@ - 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'); -} - -/** - * Main function for the events functionality - * - * @return void - */ -function PMA_EVN_main() -{ - global $db; - - PMA_EVN_setGlobals(); - /** - * Process all requests - */ - PMA_EVN_handleEditor(); - PMA_EVN_handleExport(); - /** - * Display a list of available events - */ - $items = $GLOBALS['dbi']->getEvents($db); - 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_EVN_main() - -/** - * Handles editor requests for adding or editing an item - * - * @return void - */ -function PMA_EVN_handleEditor() -{ - global $_REQUEST, $_POST, $errors, $db; - - 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 = $GLOBALS['dbi']->getDefinition( - $db, - 'EVENT', - $_REQUEST['item_original_name'] - ); - $drop_item = "DROP EVENT " - . PhpMyAdmin\Util::backquote($_REQUEST['item_original_name']) - . ";\n"; - $result = $GLOBALS['dbi']->tryQuery($drop_item); - if (! $result) { - $errors[] = sprintf( - __('The following query has failed: "%s"'), - htmlspecialchars($drop_item) - ) - . '
' - . __('MySQL said: ') . $GLOBALS['dbi']->getError(null); - } else { - $result = $GLOBALS['dbi']->tryQuery($item_query); - if (! $result) { - $errors[] = sprintf( - __('The following query has failed: "%s"'), - htmlspecialchars($item_query) - ) - . '
' - . __('MySQL said: ') . $GLOBALS['dbi']->getError(null); - // We dropped the old item, but were unable to create - // the new one. Try to restore the backup query - $result = $GLOBALS['dbi']->tryQuery($create_item); - $errors = checkResult( - $result, - __( - 'Sorry, we failed to restore the dropped event.' - ), - $create_item, - $errors - ); - } else { - $message = PhpMyAdmin\Message::success( - __('Event %1$s has been modified.') - ); - $message->addParam( - PhpMyAdmin\Util::backquote($_REQUEST['item_name']) - ); - $sql_query = $drop_item . $item_query; - } - } - } else { - // 'Add a new item' mode - $result = $GLOBALS['dbi']->tryQuery($item_query); - if (! $result) { - $errors[] = sprintf( - __('The following query has failed: "%s"'), - htmlspecialchars($item_query) - ) - . '

' - . __('MySQL said: ') . $GLOBALS['dbi']->getError(null); - } else { - $message = PhpMyAdmin\Message::success( - __('Event %1$s has been created.') - ); - $message->addParam( - PhpMyAdmin\Util::backquote($_REQUEST['item_name']) - ); - $sql_query = $item_query; - } - } - } - - if (count($errors)) { - $message = PhpMyAdmin\Message::error( - '' - . __( - 'One or more errors have occurred while processing your request:' - ) - . '' - ); - $message->addHtml('
    '); - foreach ($errors as $string) { - $message->addHtml('
  • ' . $string . '
  • '); - } - $message->addHtml('
'); - } - - $output = PhpMyAdmin\Util::getMessage($message, $sql_query); - $response = Response::getInstance(); - if ($response->isAjax()) { - if ($message->isSuccess()) { - $events = $GLOBALS['dbi']->getEvents($db, $_REQUEST['item_name']); - $event = $events[0]; - $response->addJSON( - 'name', - htmlspecialchars( - mb_strtoupper($_REQUEST['item_name']) - ) - ); - $response->addJSON('new_row', PMA_EVN_getRowForList($event)); - $response->addJSON('insert', ! empty($event)); - $response->addJSON('message', $output); - } else { - $response->setRequestStatus(false); - $response->addJSON('message', $message); - } - exit; - } - } - /** - * 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 = PMA_RTE_getWord('add'); - $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'; - } - PMA_RTE_sendEditor('EVN', $mode, $item, $title, $db, $operation); - } -} // 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 $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 " . PhpMyAdmin\Util::getCollateForIS() . "=" - . "'" . $GLOBALS['dbi']->escapeString($db) . "' " - . "AND EVENT_NAME='" . $GLOBALS['dbi']->escapeString($name) . "'"; - $query = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE $where;"; - $item = $GLOBALS['dbi']->fetchSingleRow($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 to 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, $event_status, $event_type, $event_interval; - - $modeToUpper = mb_strtoupper($mode); - - $response = Response::getInstance(); - - // 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 $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 .= Url::getHiddenInputs($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 .= "
" . __('Event name') . "\n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "
" . __('Event type') . "\n"; - if ($response->isAjax()) { - $retval .= " \n"; - } else { - $retval .= " \n"; - $retval .= " {$item['item_type']}\n"; - $retval .= " \n"; - $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 .= "
" . _pgettext('Start of recurring event', 'Start'); - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= " \n"; - $retval .= "
" . __('On completion preserve') . "\n"; - $retval .= " \n"; - $retval .= " isAjax()) { - $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, $errors, $event_status, $event_type, $event_interval; - - $query = 'CREATE '; - if (! empty($_REQUEST['item_definer'])) { - if (mb_strpos($_REQUEST['item_definer'], '@') !== false - ) { - $arr = explode('@', $_REQUEST['item_definer']); - $query .= 'DEFINER=' . PhpMyAdmin\Util::backquote($arr[0]); - $query .= '@' . PhpMyAdmin\Util::backquote($arr[1]) . ' '; - } else { - $errors[] = __('The definer must be in the "username@hostname" format!'); - } - } - $query .= 'EVENT '; - if (! empty($_REQUEST['item_name'])) { - $query .= PhpMyAdmin\Util::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 '" - . $GLOBALS['dbi']->escapeString($_REQUEST['item_starts']) - . "' "; - } - if (! empty($_REQUEST['item_ends'])) { - $query .= "ENDS '" - . $GLOBALS['dbi']->escapeString($_REQUEST['item_ends']) - . "' "; - } - } else { - if (! empty($_REQUEST['item_execute_at'])) { - $query .= "AT '" - . $GLOBALS['dbi']->escapeString($_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; - } - } - } - if (! empty($_REQUEST['item_comment'])) { - $query .= "COMMENT '" . $GLOBALS['dbi']->escapeString( - $_REQUEST['item_comment'] - ) . "' "; - } - $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_general.lib.php b/libraries/rte/rte_general.lib.php index ec6f42b460..6b3ea4a1b8 100644 --- a/libraries/rte/rte_general.lib.php +++ b/libraries/rte/rte_general.lib.php @@ -7,6 +7,7 @@ */ use PhpMyAdmin\Message; use PhpMyAdmin\Response; +use PhpMyAdmin\Rte\Events; if (! defined('PHPMYADMIN')) { exit; @@ -61,7 +62,7 @@ function PMA_RTE_sendEditor($type, $mode, $item, $title, $db, $operation = null) if ($type == 'TRI') { $editor = PMA_TRI_getEditorForm($mode, $item); } else { // EVN - $editor = PMA_EVN_getEditorForm($mode, $operation, $item); + $editor = Events::getEditorForm($mode, $operation, $item); } if ($response->isAjax()) { $response->addJSON('message', $editor); diff --git a/libraries/rte/rte_main.inc.php b/libraries/rte/rte_main.inc.php index 52f764b012..85e52d56bf 100644 --- a/libraries/rte/rte_main.inc.php +++ b/libraries/rte/rte_main.inc.php @@ -7,6 +7,7 @@ */ use PhpMyAdmin\Url; use PhpMyAdmin\Response; +use PhpMyAdmin\Rte\Events; if (! defined('PHPMYADMIN')) { exit; @@ -103,7 +104,6 @@ case 'TRI': PMA_TRI_main(); break; case 'EVN': - PMA_EVN_main(); + Events::main(); break; } - diff --git a/test/classes/Rte/EventsTest.php b/test/classes/Rte/EventsTest.php new file mode 100644 index 0000000000..0e7cea2d73 --- /dev/null +++ b/test/classes/Rte/EventsTest.php @@ -0,0 +1,527 @@ + $value) { + if ($value !== '') { + $_REQUEST[$key] = $value; + } + } + $this->assertEquals($out, Events::getDataFromRequest()); + } + + /** + * Data provider for testGetDataFromRequestEmpty + * + * @return array + */ + public function providerGetDataFromRequest() + { + return array( + array( + array( + 'item_name' => '', + 'item_type' => '', + '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' => '' + ), + array( + 'item_name' => '', + 'item_type' => 'ONE TIME', + 'item_type_toggle' => 'RECURRING', + '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' => '' + ) + ), + array( + array( + 'item_name' => 'foo', + 'item_type' => 'RECURRING', + 'item_original_name' => 'foo', + 'item_status' => 'foo', + 'item_execute_at' => 'foo', + 'item_interval_value' => 'foo', + 'item_interval_field' => 'foo', + 'item_starts' => 'foo', + 'item_ends' => 'foo', + 'item_definition' => 'foo', + 'item_preserve' => 'foo', + 'item_comment' => 'foo', + 'item_definer' => 'foo' + ), + array( + 'item_name' => 'foo', + 'item_type' => 'RECURRING', + 'item_type_toggle' => 'ONE TIME', + 'item_original_name' => 'foo', + 'item_status' => 'foo', + 'item_execute_at' => 'foo', + 'item_interval_value' => 'foo', + 'item_interval_field' => 'foo', + 'item_starts' => 'foo', + 'item_ends' => 'foo', + 'item_definition' => 'foo', + 'item_preserve' => 'foo', + 'item_comment' => 'foo', + 'item_definer' => 'foo' + ) + ), + ); + } + + /** + * Test for Events::getEditorForm + * + * @param array $data Data for routine + * @param array $matcher Matcher + * + * @return void + * + * @dataProvider providerGetEditorFormAdd + */ + public function testGetEditorFormAdd($data, $matcher) + { + Events::setGlobals(); + $this->assertContains( + $matcher, + Events::getEditorForm('add', 'change', $data) + ); + } + + /** + * Data provider for testGetEditorFormAdd + * + * @return array + */ + public function providerGetEditorFormAdd() + { + $data = array( + 'item_name' => '', + 'item_type' => 'ONE TIME', + 'item_type_toggle' => 'RECURRING', + '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' => '' + ); + + return array( + array( + $data, + "assertContains( + $matcher, + Events::getEditorForm('edit', 'change', $data) + ); + } + + /** + * Data provider for testGetEditorFormEdit + * + * @return array + */ + public function providerGetEditorFormEdit() + { + $data = array( + 'item_name' => 'foo', + 'item_type' => 'RECURRING', + 'item_type_toggle' => 'ONE TIME', + 'item_original_name' => 'bar', + 'item_status' => 'ENABLED', + 'item_execute_at' => '', + 'item_interval_value' => '1', + 'item_interval_field' => 'DAY', + 'item_starts' => '', + 'item_ends' => '', + 'item_definition' => 'SET @A=1;', + 'item_preserve' => '', + 'item_comment' => '', + 'item_definer' => '' + ); + + return array( + array( + $data, + "setAjax(true); + Events::setGlobals(); + $this->assertContains( + $matcher, + Events::getEditorForm('edit', 'change', $data) + ); + Response::getInstance()->setAjax(false); + } + + /** + * Data provider for testGetEditorFormAjax + * + * @return array + */ + public function providerGetEditorFormAjax() + { + $data = array( + 'item_name' => '', + 'item_type' => 'RECURRING', + 'item_type_toggle' => 'ONE TIME', + 'item_original_name' => '', + 'item_status' => 'ENABLED', + 'item_execute_at' => '', + 'item_interval_value' => '', + 'item_interval_field' => 'DAY', + 'item_starts' => '', + 'item_ends' => '', + 'item_definition' => '', + 'item_preserve' => '', + 'item_comment' => '', + 'item_definer' => '' + ); + + return array( + array( + $data, + "assertContains( - $matcher, - PMA_EVN_getEditorForm('edit', 'change', $data) - ); - } - - /** - * Data provider for testgetEditorForm_edit - * - * @return array - */ - public function providerEdit() - { - $data = array( - 'item_name' => 'foo', - 'item_type' => 'RECURRING', - 'item_type_toggle' => 'ONE TIME', - 'item_original_name' => 'bar', - 'item_status' => 'ENABLED', - 'item_execute_at' => '', - 'item_interval_value' => '1', - 'item_interval_field' => 'DAY', - 'item_starts' => '', - 'item_ends' => '', - 'item_definition' => 'SET @A=1;', - 'item_preserve' => '', - 'item_comment' => '', - 'item_definer' => '' - ); - - return array( - array( - $data, - "setAjax(true); - PMA_EVN_setGlobals(); - $this->assertContains( - $matcher, - PMA_EVN_getEditorForm('edit', 'change', $data) - ); - Response::getInstance()->setAjax(false); - } - - /** - * Data provider for testgetEditorForm_ajax - * - * @return array - */ - public function providerAjax() - { - $data = array( - 'item_name' => '', - 'item_type' => 'RECURRING', - 'item_type_toggle' => 'ONE TIME', - 'item_original_name' => '', - 'item_status' => 'ENABLED', - 'item_execute_at' => '', - 'item_interval_value' => '', - 'item_interval_field' => 'DAY', - 'item_starts' => '', - 'item_ends' => '', - 'item_definition' => '', - 'item_preserve' => '', - 'item_comment' => '', - 'item_definer' => '' - ); - - return array( - array( - $data, - "