addScriptFiles(['database/routines.js']); $type = $_REQUEST['type'] ?? null; $this->checkUserPrivileges->getPrivileges(); $config = Config::getInstance(); if (! $request->isAjax()) { /** * Displays the header and tabs */ if (! empty($GLOBALS['table']) && in_array($GLOBALS['table'], $this->dbi->getTables($GLOBALS['db']))) { $this->checkParameters(['db', 'table']); $GLOBALS['urlParams'] = ['db' => $GLOBALS['db'], 'table' => $GLOBALS['table']]; $GLOBALS['errorUrl'] = Util::getScriptNameForOption($config->settings['DefaultTabTable'], 'table'); $GLOBALS['errorUrl'] .= Url::getCommon($GLOBALS['urlParams'], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { $this->redirect('/', ['reload' => true, 'message' => __('No databases selected.')]); return; } $tableName = TableName::tryFrom($request->getParam('table')); if ($tableName === null || ! $this->dbTableExists->hasTable($databaseName, $tableName)) { $this->redirect('/', ['reload' => true, 'message' => __('No table selected.')]); return; } } else { $GLOBALS['table'] = ''; $this->checkParameters(['db']); $GLOBALS['errorUrl'] = Util::getScriptNameForOption( $config->settings['DefaultTabDatabase'], 'database', ); $GLOBALS['errorUrl'] .= Url::getCommon(['db' => $GLOBALS['db']], '&'); $databaseName = DatabaseName::tryFrom($request->getParam('db')); if ($databaseName === null || ! $this->dbTableExists->hasDatabase($databaseName)) { $this->redirect('/', ['reload' => true, 'message' => __('No databases selected.')]); return; } } } elseif (strlen($GLOBALS['db']) > 0) { $this->dbi->selectDb($GLOBALS['db']); } /** * Keep a list of errors that occurred while * processing an 'Add' or 'Edit' operation. */ $GLOBALS['errors'] = []; $GLOBALS['message'] ??= null; if (! empty($_POST['editor_process_add']) || ! empty($_POST['editor_process_edit'])) { $output = $this->routines->handleRequestCreateOrEdit($GLOBALS['db']); if ($request->isAjax()) { if (! $GLOBALS['message']->isSuccess()) { $this->response->setRequestStatus(false); $this->response->addJSON('message', $output); return; } $routines = Routines::getDetails($this->dbi, $GLOBALS['db'], $_POST['item_type'], $_POST['item_name']); $routine = $routines[0]; $this->response->addJSON( 'name', htmlspecialchars( mb_strtoupper($_POST['item_name']), ), ); $this->response->addJSON( 'new_row', $this->template->render('database/routines/row', $this->routines->getRow($routine)), ); $this->response->addJSON('insert', ! empty($routine)); $this->response->addJSON('message', $output); $this->response->addJSON('tableType', 'routines'); return; } } /** * Display a form used to add/edit a routine, if necessary */ // FIXME: this must be simpler than that if ( $GLOBALS['errors'] !== [] || empty($_POST['editor_process_add']) && empty($_POST['editor_process_edit']) && ( ! empty($_REQUEST['add_item']) || ! empty($_REQUEST['edit_item']) || ! empty($_POST['routine_addparameter']) || ! empty($_POST['routine_removeparameter']) || ! empty($_POST['routine_changetype']) ) ) { // Handle requests to add/remove parameters and changing routine type // This is necessary when JS is disabled $operation = ''; if (! empty($_POST['routine_addparameter'])) { $operation = 'add'; } elseif (! empty($_POST['routine_removeparameter'])) { $operation = 'remove'; } elseif (! empty($_POST['routine_changetype'])) { $operation = 'change'; } // Get the data for the form (if any) $routine = null; $mode = null; $title = null; if (! empty($_REQUEST['add_item'])) { $title = __('Add routine'); $routine = $this->routines->getDataFromRequest(); $mode = 'add'; } elseif (! empty($_REQUEST['edit_item'])) { $title = __('Edit routine'); if ($operation === '' && ! empty($_GET['item_name']) && empty($_POST['editor_process_edit'])) { $routine = $this->routines->getDataFromName($_GET['item_name'], $_GET['item_type']); if ($routine !== null) { $routine['item_original_name'] = $routine['item_name']; $routine['item_original_type'] = $routine['item_type']; } } else { $routine = $this->routines->getDataFromRequest(); } $mode = 'edit'; } if ($routine !== null) { // Show form 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'; } } elseif ( $operation === 'add' || ($routine['item_num_params'] == 0 && $mode === 'add' && ! $GLOBALS['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']++; } elseif ($operation === 'remove') { unset( $routine['item_param_dir'][$routine['item_num_params'] - 1], $routine['item_param_name'][$routine['item_num_params'] - 1], $routine['item_param_type'][$routine['item_num_params'] - 1], $routine['item_param_length'][$routine['item_num_params'] - 1], $routine['item_param_opts_num'][$routine['item_num_params'] - 1], $routine['item_param_opts_text'][$routine['item_num_params'] - 1], ); $routine['item_num_params']--; } $parameterRows = ''; for ($i = 0; $i < $routine['item_num_params']; $i++) { $parameterRows .= $this->template->render( 'database/routines/parameter_row', $this->routines->getParameterRow( $routine, $i, $routine['item_type'] === 'FUNCTION' ? ' hide' : '', ), ); } $charsets = Charsets::getCharsets($this->dbi, $config->selectedServer['DisableIS']); $editor = $this->template->render('database/routines/editor_form', [ 'db' => $GLOBALS['db'], 'routine' => $routine, 'is_edit_mode' => $mode === 'edit', 'is_ajax' => $request->isAjax(), 'parameter_rows' => $parameterRows, 'charsets' => $charsets, 'numeric_options' => $this->routines->numericOptions, 'has_privileges' => $GLOBALS['proc_priv'] && $GLOBALS['is_reload_priv'], 'sql_data_access' => $this->routines->sqlDataAccess, ]); if ($request->isAjax()) { $this->response->addJSON('message', $editor); $this->response->addJSON('title', $title); $this->response->addJSON( 'paramTemplate', $this->template->render('database/routines/parameter_row', $this->routines->getParameterRow()), ); $this->response->addJSON('type', $routine['item_type']); return; } $this->response->addHTML("\n\n