Upgraded phpmyadmin to 4.0.4 (All Languages) - No modifications yet
[openemr.git] / phpmyadmin / libraries / rte / rte_events.lib.php
blob7d4ce6cf37992bb55430aba805ba9bf4db9b1e35
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Functions for event management.
6 * @package PhpMyAdmin
7 */
8 if (! defined('PHPMYADMIN')) {
9 exit;
12 /**
13 * Sets required globals
15 * @return void
17 function PMA_EVN_setGlobals()
19 global $event_status, $event_type, $event_interval;
21 $event_status = array(
22 'query' => array('ENABLE',
23 'DISABLE',
24 'DISABLE ON SLAVE'),
25 'display' => array('ENABLED',
26 'DISABLED',
27 'SLAVESIDE_DISABLED')
29 $event_type = array('RECURRING',
30 'ONE TIME');
31 $event_interval = array('YEAR',
32 'QUARTER',
33 'MONTH',
34 'DAY',
35 'HOUR',
36 'MINUTE',
37 'WEEK',
38 'SECOND',
39 'YEAR_MONTH',
40 'DAY_HOUR',
41 'DAY_MINUTE',
42 'DAY_SECOND',
43 'HOUR_MINUTE',
44 'HOUR_SECOND',
45 'MINUTE_SECOND');
48 /**
49 * Main function for the events functionality
51 * @return void
53 function PMA_EVN_main()
55 global $db;
57 PMA_EVN_setGlobals();
58 /**
59 * Process all requests
61 PMA_EVN_handleEditor();
62 PMA_EVN_handleExport();
63 /**
64 * Display a list of available events
66 $columns = "`EVENT_NAME`, `EVENT_TYPE`, `STATUS`";
67 $where = "EVENT_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "'";
68 $query = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` "
69 . "WHERE $where ORDER BY `EVENT_NAME` ASC;";
70 $items = PMA_DBI_fetch_result($query);
71 echo PMA_RTE_getList('event', $items);
72 /**
73 * Display a link for adding a new event, if
74 * the user has the privileges and a link to
75 * toggle the state of the event scheduler.
77 echo PMA_EVN_getFooterLinks();
78 } // end PMA_EVN_main()
80 /**
81 * Handles editor requests for adding or editing an item
83 * @return void
85 function PMA_EVN_handleEditor()
87 global $_REQUEST, $_POST, $errors, $db;
89 if (! empty($_REQUEST['editor_process_add'])
90 || ! empty($_REQUEST['editor_process_edit'])
91 ) {
92 $sql_query = '';
94 $item_query = PMA_EVN_getQueryFromRequest();
96 if (! count($errors)) { // set by PMA_RTN_getQueryFromRequest()
97 // Execute the created query
98 if (! empty($_REQUEST['editor_process_edit'])) {
99 // Backup the old trigger, in case something goes wrong
100 $create_item = PMA_DBI_get_definition(
101 $db,
102 'EVENT',
103 $_REQUEST['item_original_name']
105 $drop_item = "DROP EVENT "
106 . PMA_Util::backquote($_REQUEST['item_original_name']) . ";\n";
107 $result = PMA_DBI_try_query($drop_item);
108 if (! $result) {
109 $errors[] = sprintf(
110 __('The following query has failed: "%s"'),
111 htmlspecialchars($drop_item)
113 . '<br />'
114 . __('MySQL said: ') . PMA_DBI_getError(null);
115 } else {
116 $result = PMA_DBI_try_query($item_query);
117 if (! $result) {
118 $errors[] = sprintf(
119 __('The following query has failed: "%s"'),
120 htmlspecialchars($item_query)
122 . '<br />'
123 . __('MySQL said: ') . PMA_DBI_getError(null);
124 // We dropped the old item, but were unable to create
125 // the new one. Try to restore the backup query
126 $result = PMA_DBI_try_query($create_item);
127 if (! $result) {
128 // OMG, this is really bad! We dropped the query,
129 // failed to create a new one
130 // and now even the backup query does not execute!
131 // This should not happen, but we better handle
132 // this just in case.
133 $errors[] = __(
134 'Sorry, we failed to restore the dropped event.'
136 . '<br />'
137 . __('The backed up query was:')
138 . "\"" . htmlspecialchars($create_item) . "\""
139 . '<br />'
140 . __('MySQL said: ') . PMA_DBI_getError(null);
142 } else {
143 $message = PMA_Message::success(
144 __('Event %1$s has been modified.')
146 $message->addParam(
147 PMA_Util::backquote($_REQUEST['item_name'])
149 $sql_query = $drop_item . $item_query;
152 } else {
153 // 'Add a new item' mode
154 $result = PMA_DBI_try_query($item_query);
155 if (! $result) {
156 $errors[] = sprintf(
157 __('The following query has failed: "%s"'),
158 htmlspecialchars($item_query)
160 . '<br /><br />'
161 . __('MySQL said: ') . PMA_DBI_getError(null);
162 } else {
163 $message = PMA_Message::success(
164 __('Event %1$s has been created.')
166 $message->addParam(
167 PMA_Util::backquote($_REQUEST['item_name'])
169 $sql_query = $item_query;
174 if (count($errors)) {
175 $message = PMA_Message::error(__('<b>One or more errors have occured while processing your request:</b>'));
176 $message->addString('<ul>');
177 foreach ($errors as $string) {
178 $message->addString('<li>' . $string . '</li>');
180 $message->addString('</ul>');
183 $output = PMA_Util::getMessage($message, $sql_query);
184 if ($GLOBALS['is_ajax_request']) {
185 $response = PMA_Response::getInstance();
186 if ($message->isSuccess()) {
187 $columns = "`EVENT_NAME`, `EVENT_TYPE`, `STATUS`";
188 $where = "EVENT_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' "
189 . "AND EVENT_NAME='"
190 . PMA_Util::sqlAddSlashes($_REQUEST['item_name']) . "'";
191 $query = "SELECT " . $columns
192 . " FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE " . $where. ";";
193 $event = PMA_DBI_fetch_single_row($query);
194 $response->addJSON(
195 'name',
196 htmlspecialchars(strtoupper($_REQUEST['item_name']))
198 $response->addJSON('new_row', PMA_EVN_getRowForList($event));
199 $response->addJSON('insert', ! empty($event));
200 $response->addJSON('message', $output);
201 } else {
202 $response->isSuccess(false);
203 $response->addJSON('message', $message);
205 exit;
209 * Display a form used to add/edit a trigger, if necessary
211 if (count($errors)
212 || (empty($_REQUEST['editor_process_add'])
213 && empty($_REQUEST['editor_process_edit'])
214 && (! empty($_REQUEST['add_item'])
215 || ! empty($_REQUEST['edit_item'])
216 || ! empty($_REQUEST['item_changetype'])))
217 ) { // FIXME: this must be simpler than that
218 $operation = '';
219 if (! empty($_REQUEST['item_changetype'])) {
220 $operation = 'change';
222 // Get the data for the form (if any)
223 if (! empty($_REQUEST['add_item'])) {
224 $title = PMA_RTE_getWord('add');
225 $item = PMA_EVN_getDataFromRequest();
226 $mode = 'add';
227 } else if (! empty($_REQUEST['edit_item'])) {
228 $title = __("Edit event");
229 if (! empty($_REQUEST['item_name'])
230 && empty($_REQUEST['editor_process_edit'])
231 && empty($_REQUEST['item_changetype'])
233 $item = PMA_EVN_getDataFromName($_REQUEST['item_name']);
234 if ($item !== false) {
235 $item['item_original_name'] = $item['item_name'];
237 } else {
238 $item = PMA_EVN_getDataFromRequest();
240 $mode = 'edit';
242 if ($item !== false) {
243 // Show form
244 $editor = PMA_EVN_getEditorForm($mode, $operation, $item);
245 if ($GLOBALS['is_ajax_request']) {
246 $response = PMA_Response::getInstance();
247 $response->addJSON('message', $editor);
248 $response->addJSON('title', $title);
249 } else {
250 echo "\n\n<h2>$title</h2>\n\n$editor";
251 unset($_POST);
253 exit;
254 } else {
255 $message = __('Error in processing request') . ' : ';
256 $message .= sprintf(
257 PMA_RTE_getWord('not_found'),
258 htmlspecialchars(PMA_Util::backquote($_REQUEST['item_name'])),
259 htmlspecialchars(PMA_Util::backquote($db))
261 $message = PMA_message::error($message);
262 if ($GLOBALS['is_ajax_request']) {
263 $response = PMA_Response::getInstance();
264 $response->isSuccess(false);
265 $response->addJSON('message', $message);
266 exit;
267 } else {
268 $message->display();
272 } // end PMA_EVN_handleEditor()
275 * This function will generate the values that are required to for the editor
277 * @return array Data necessary to create the editor.
279 function PMA_EVN_getDataFromRequest()
281 $retval = array();
282 $indices = array('item_name',
283 'item_original_name',
284 'item_status',
285 'item_execute_at',
286 'item_interval_value',
287 'item_interval_field',
288 'item_starts',
289 'item_ends',
290 'item_definition',
291 'item_preserve',
292 'item_comment',
293 'item_definer');
294 foreach ($indices as $index) {
295 $retval[$index] = isset($_REQUEST[$index]) ? $_REQUEST[$index] : '';
297 $retval['item_type'] = 'ONE TIME';
298 $retval['item_type_toggle'] = 'RECURRING';
299 if (isset($_REQUEST['item_type']) && $_REQUEST['item_type'] == 'RECURRING') {
300 $retval['item_type'] = 'RECURRING';
301 $retval['item_type_toggle'] = 'ONE TIME';
303 return $retval;
304 } // end PMA_EVN_getDataFromRequest()
307 * This function will generate the values that are required to complete
308 * the "Edit event" form given the name of a event.
310 * @param string $name The name of the event.
312 * @return array Data necessary to create the editor.
314 function PMA_EVN_getDataFromName($name)
316 global $db;
318 $retval = array();
319 $columns = "`EVENT_NAME`, `STATUS`, `EVENT_TYPE`, `EXECUTE_AT`, "
320 . "`INTERVAL_VALUE`, `INTERVAL_FIELD`, `STARTS`, `ENDS`, "
321 . "`EVENT_DEFINITION`, `ON_COMPLETION`, `DEFINER`, `EVENT_COMMENT`";
322 $where = "EVENT_SCHEMA='" . PMA_Util::sqlAddSlashes($db) . "' "
323 . "AND EVENT_NAME='" . PMA_Util::sqlAddSlashes($name) . "'";
324 $query = "SELECT $columns FROM `INFORMATION_SCHEMA`.`EVENTS` WHERE $where;";
325 $item = PMA_DBI_fetch_single_row($query);
326 if (! $item) {
327 return false;
329 $retval['item_name'] = $item['EVENT_NAME'];
330 $retval['item_status'] = $item['STATUS'];
331 $retval['item_type'] = $item['EVENT_TYPE'];
332 if ($retval['item_type'] == 'RECURRING') {
333 $retval['item_type_toggle'] = 'ONE TIME';
334 } else {
335 $retval['item_type_toggle'] = 'RECURRING';
337 $retval['item_execute_at'] = $item['EXECUTE_AT'];
338 $retval['item_interval_value'] = $item['INTERVAL_VALUE'];
339 $retval['item_interval_field'] = $item['INTERVAL_FIELD'];
340 $retval['item_starts'] = $item['STARTS'];
341 $retval['item_ends'] = $item['ENDS'];
342 $retval['item_preserve'] = '';
343 if ($item['ON_COMPLETION'] == 'PRESERVE') {
344 $retval['item_preserve'] = " checked='checked'";
346 $retval['item_definition'] = $item['EVENT_DEFINITION'];
347 $retval['item_definer'] = $item['DEFINER'];
348 $retval['item_comment'] = $item['EVENT_COMMENT'];
350 return $retval;
351 } // end PMA_EVN_getDataFromName()
354 * Displays a form used to add/edit an event
356 * @param string $mode If the editor will be used edit an event
357 * or add a new one: 'edit' or 'add'.
358 * @param string $operation If the editor was previously invoked with
359 * JS turned off, this will hold the name of
360 * the current operation
361 * @param array $item Data for the event returned by
362 * PMA_EVN_getDataFromRequest() or
363 * PMA_EVN_getDataFromName()
365 * @return string HTML code for the editor.
367 function PMA_EVN_getEditorForm($mode, $operation, $item)
369 global $db, $table, $event_status, $event_type, $event_interval;
371 // Escape special characters
372 $need_escape = array(
373 'item_original_name',
374 'item_name',
375 'item_type',
376 'item_execute_at',
377 'item_interval_value',
378 'item_starts',
379 'item_ends',
380 'item_definition',
381 'item_definer',
382 'item_comment'
384 foreach ($need_escape as $index) {
385 $item[$index] = htmlentities($item[$index], ENT_QUOTES);
387 $original_data = '';
388 if ($mode == 'edit') {
389 $original_data = "<input name='item_original_name' "
390 . "type='hidden' value='{$item['item_original_name']}'/>\n";
392 // Handle some logic first
393 if ($operation == 'change') {
394 if ($item['item_type'] == 'RECURRING') {
395 $item['item_type'] = 'ONE TIME';
396 $item['item_type_toggle'] = 'RECURRING';
397 } else {
398 $item['item_type'] = 'RECURRING';
399 $item['item_type_toggle'] = 'ONE TIME';
402 if ($item['item_type'] == 'ONE TIME') {
403 $isrecurring_class = ' hide';
404 $isonetime_class = '';
405 } else {
406 $isrecurring_class = '';
407 $isonetime_class = ' hide';
409 // Create the output
410 $retval = "";
411 $retval .= "<!-- START " . strtoupper($mode) . " EVENT FORM -->\n\n";
412 $retval .= "<form class='rte_form' action='db_events.php' method='post'>\n";
413 $retval .= "<input name='{$mode}_item' type='hidden' value='1' />\n";
414 $retval .= $original_data;
415 $retval .= PMA_generate_common_hidden_inputs($db, $table) . "\n";
416 $retval .= "<fieldset>\n";
417 $retval .= "<legend>" . __('Details') . "</legend>\n";
418 $retval .= "<table class='rte_table' style='width: 100%'>\n";
419 $retval .= "<tr>\n";
420 $retval .= " <td style='width: 20%;'>" . __('Event name') . "</td>\n";
421 $retval .= " <td><input type='text' name='item_name' \n";
422 $retval .= " value='{$item['item_name']}'\n";
423 $retval .= " maxlength='64' /></td>\n";
424 $retval .= "</tr>\n";
425 $retval .= "<tr>\n";
426 $retval .= " <td>" . __('Status') . "</td>\n";
427 $retval .= " <td>\n";
428 $retval .= " <select name='item_status'>\n";
429 foreach ($event_status['display'] as $key => $value) {
430 $selected = "";
431 if (! empty($item['item_status']) && $item['item_status'] == $value) {
432 $selected = " selected='selected'";
434 $retval .= "<option$selected>$value</option>";
436 $retval .= " </select>\n";
437 $retval .= " </td>\n";
438 $retval .= "</tr>\n";
440 $retval .= "<tr>\n";
441 $retval .= " <td>" . __('Event type') . "</td>\n";
442 $retval .= " <td>\n";
443 if ($GLOBALS['is_ajax_request']) {
444 $retval .= " <select name='item_type'>";
445 foreach ($event_type as $key => $value) {
446 $selected = "";
447 if (! empty($item['item_type']) && $item['item_type'] == $value) {
448 $selected = " selected='selected'";
450 $retval .= "<option$selected>$value</option>";
452 $retval .= " </select>\n";
453 } else {
454 $retval .= " <input name='item_type' type='hidden' \n";
455 $retval .= " value='{$item['item_type']}' />\n";
456 $retval .= " <div style='width: 49%; float: left; text-align: center;"
457 . " font-weight: bold;'>\n";
458 $retval .= " {$item['item_type']}\n";
459 $retval .= " </div>\n";
460 $retval .= " <input style='width: 49%;' type='submit'\n";
461 $retval .= " name='item_changetype'\n";
462 $retval .= " value='";
463 $retval .= sprintf(__('Change to %s'), $item['item_type_toggle']);
464 $retval .= "' />\n";
466 $retval .= " </td>\n";
467 $retval .= "</tr>\n";
468 $retval .= "<tr class='onetime_event_row $isonetime_class'>\n";
469 $retval .= " <td>" . __('Execute at') . "</td>\n";
470 $retval .= " <td class='nowrap'>\n";
471 $retval .= " <input type='text' name='item_execute_at'\n";
472 $retval .= " value='{$item['item_execute_at']}'\n";
473 $retval .= " class='datetimefield' />\n";
474 $retval .= " </td>\n";
475 $retval .= "</tr>\n";
476 $retval .= "<tr class='recurring_event_row $isrecurring_class'>\n";
477 $retval .= " <td>" . __('Execute every') . "</td>\n";
478 $retval .= " <td>\n";
479 $retval .= " <input style='width: 49%;' type='text'\n";
480 $retval .= " name='item_interval_value'\n";
481 $retval .= " value='{$item['item_interval_value']}' />\n";
482 $retval .= " <select style='width: 49%;' name='item_interval_field'>";
483 foreach ($event_interval as $key => $value) {
484 $selected = "";
485 if (! empty($item['item_interval_field'])
486 && $item['item_interval_field'] == $value
488 $selected = " selected='selected'";
490 $retval .= "<option$selected>$value</option>";
492 $retval .= " </select>\n";
493 $retval .= " </td>\n";
494 $retval .= "</tr>\n";
495 $retval .= "<tr class='recurring_event_row$isrecurring_class'>\n";
496 $retval .= " <td>" . _pgettext('Start of recurring event', 'Start');
497 $retval .= " </td>\n";
498 $retval .= " <td class='nowrap'>\n";
499 $retval .= " <input type='text'\n name='item_starts'\n";
500 $retval .= " value='{$item['item_starts']}'\n";
501 $retval .= " class='datetimefield' />\n";
502 $retval .= " </td>\n";
503 $retval .= "</tr>\n";
504 $retval .= "<tr class='recurring_event_row$isrecurring_class'>\n";
505 $retval .= " <td>" . _pgettext('End of recurring event', 'End') . "</td>\n";
506 $retval .= " <td class='nowrap'>\n";
507 $retval .= " <input type='text' name='item_ends'\n";
508 $retval .= " value='{$item['item_ends']}'\n";
509 $retval .= " class='datetimefield' />\n";
510 $retval .= " </td>\n";
511 $retval .= "</tr>\n";
512 $retval .= "<tr>\n";
513 $retval .= " <td>" . __('Definition') . "</td>\n";
514 $retval .= " <td><textarea name='item_definition' rows='15' cols='40'>";
515 $retval .= $item['item_definition'];
516 $retval .= "</textarea></td>\n";
517 $retval .= "</tr>\n";
518 $retval .= "<tr>\n";
519 $retval .= " <td>" . __('On completion preserve') . "</td>\n";
520 $retval .= " <td><input type='checkbox'\n";
521 $retval .= " name='item_preserve'{$item['item_preserve']} /></td>\n";
522 $retval .= "</tr>\n";
523 $retval .= "<tr>\n";
524 $retval .= " <td>" . __('Definer') . "</td>\n";
525 $retval .= " <td><input type='text' name='item_definer'\n";
526 $retval .= " value='{$item['item_definer']}' /></td>\n";
527 $retval .= "</tr>\n";
528 $retval .= "<tr>\n";
529 $retval .= " <td>" . __('Comment') . "</td>\n";
530 $retval .= " <td><input type='text' name='item_comment' maxlength='64'\n";
531 $retval .= " value='{$item['item_comment']}' /></td>\n";
532 $retval .= "</tr>\n";
533 $retval .= "</table>\n";
534 $retval .= "</fieldset>\n";
535 if ($GLOBALS['is_ajax_request']) {
536 $retval .= "<input type='hidden' name='editor_process_{$mode}'\n";
537 $retval .= " value='true' />\n";
538 $retval .= "<input type='hidden' name='ajax_request' value='true' />\n";
539 } else {
540 $retval .= "<fieldset class='tblFooters'>\n";
541 $retval .= " <input type='submit' name='editor_process_{$mode}'\n";
542 $retval .= " value='" . __('Go') . "' />\n";
543 $retval .= "</fieldset>\n";
545 $retval .= "</form>\n\n";
546 $retval .= "<!-- END " . strtoupper($mode) . " EVENT FORM -->\n\n";
548 return $retval;
549 } // end PMA_EVN_getEditorForm()
552 * Composes the query necessary to create an event from an HTTP request.
554 * @return string The CREATE EVENT query.
556 function PMA_EVN_getQueryFromRequest()
558 global $_REQUEST, $errors, $event_status, $event_type, $event_interval;
560 $query = 'CREATE ';
561 if (! empty($_REQUEST['item_definer'])) {
562 if (strpos($_REQUEST['item_definer'], '@') !== false) {
563 $arr = explode('@', $_REQUEST['item_definer']);
564 $query .= 'DEFINER=' . PMA_Util::backquote($arr[0]);
565 $query .= '@' . PMA_Util::backquote($arr[1]) . ' ';
566 } else {
567 $errors[] = __('The definer must be in the "username@hostname" format');
570 $query .= 'EVENT ';
571 if (! empty($_REQUEST['item_name'])) {
572 $query .= PMA_Util::backquote($_REQUEST['item_name']) . ' ';
573 } else {
574 $errors[] = __('You must provide an event name');
576 $query .= 'ON SCHEDULE ';
577 if (! empty($_REQUEST['item_type'])
578 && in_array($_REQUEST['item_type'], $event_type)
580 if ($_REQUEST['item_type'] == 'RECURRING') {
581 if (! empty($_REQUEST['item_interval_value'])
582 && !empty($_REQUEST['item_interval_field'])
583 && in_array($_REQUEST['item_interval_field'], $event_interval)
585 $query .= 'EVERY ' . intval($_REQUEST['item_interval_value']) . ' ';
586 $query .= $_REQUEST['item_interval_field'] . ' ';
587 } else {
588 $errors[] = __('You must provide a valid interval value for the event.');
590 if (! empty($_REQUEST['item_starts'])) {
591 $query .= "STARTS '"
592 . PMA_Util::sqlAddSlashes($_REQUEST['item_starts']) . "' ";
594 if (! empty($_REQUEST['item_ends'])) {
595 $query .= "ENDS '"
596 . PMA_Util::sqlAddSlashes($_REQUEST['item_ends']) . "' ";
598 } else {
599 if (! empty($_REQUEST['item_execute_at'])) {
600 $query .= "AT '"
601 . PMA_Util::sqlAddSlashes($_REQUEST['item_execute_at']) . "' ";
602 } else {
603 $errors[] = __('You must provide a valid execution time for the event.');
606 } else {
607 $errors[] = __('You must provide a valid type for the event.');
609 $query .= 'ON COMPLETION ';
610 if (empty($_REQUEST['item_preserve'])) {
611 $query .= 'NOT ';
613 $query .= 'PRESERVE ';
614 if (! empty($_REQUEST['item_status'])) {
615 foreach ($event_status['display'] as $key => $value) {
616 if ($value == $_REQUEST['item_status']) {
617 $query .= $event_status['query'][$key] . ' ';
618 break;
622 if (! empty($_REQUEST['item_comment'])) {
623 $query .= "COMMENT '" . PMA_Util::sqlAddslashes(
624 $_REQUEST['item_comment']
625 ) . "' ";
627 $query .= 'DO ';
628 if (! empty($_REQUEST['item_definition'])) {
629 $query .= $_REQUEST['item_definition'];
630 } else {
631 $errors[] = __('You must provide an event definition.');
634 return $query;
635 } // end PMA_EVN_getQueryFromRequest()