From 104c68d681c69667a053b3207091bfa8ba047505 Mon Sep 17 00:00:00 2001 From: Jason Date: Wed, 24 Jun 2015 01:55:45 +0800 Subject: [PATCH 01/16] Introduce Controllers for tbl related scripts Signed-off-by: Jason --- libraries/controllers/Controller.class.php | 45 +++ .../controllers/TableController.class.php | 28 ++ .../table/TableChartController.class.php | 234 ++++++++++++ .../TableGisVisualizationController.class.php | 180 +++++++++ .../table/TableIndexesController.class.php | 193 ++++++++++ .../table/TableRelationController.class.php | 356 ++++++++++++++++++ libraries/gis/GIS_Visualization.class.php | 8 + tbl_chart.php | 150 +------- tbl_gis_visualization.php | 125 +----- tbl_indexes.php | 130 +------ tbl_relation.php | 250 +----------- 11 files changed, 1061 insertions(+), 638 deletions(-) create mode 100644 libraries/controllers/Controller.class.php create mode 100644 libraries/controllers/TableController.class.php create mode 100644 libraries/controllers/table/TableChartController.class.php create mode 100644 libraries/controllers/table/TableGisVisualizationController.class.php create mode 100644 libraries/controllers/table/TableIndexesController.class.php create mode 100644 libraries/controllers/table/TableRelationController.class.php diff --git a/libraries/controllers/Controller.class.php b/libraries/controllers/Controller.class.php new file mode 100644 index 0000000000..ac9ca469b1 --- /dev/null +++ b/libraries/controllers/Controller.class.php @@ -0,0 +1,45 @@ +dbi = $GLOBALS['dbi']; + $this->response = PMA_Response::getInstance(); + } +} diff --git a/libraries/controllers/TableController.class.php b/libraries/controllers/TableController.class.php new file mode 100644 index 0000000000..3c4f05ff6e --- /dev/null +++ b/libraries/controllers/TableController.class.php @@ -0,0 +1,28 @@ +sql_query = &$GLOBALS['sql_query']; + $this->url_query = &$GLOBALS['url_query']; + $this->table = &$GLOBALS['table']; + $this->db = &$GLOBALS['db']; + $this->cfg = &$GLOBALS['cfg']; + } + + /* + * Execute the query and return the result + */ + public function indexAction() + { + if (isset($_REQUEST['ajax_request']) + && isset($_REQUEST['pos']) + && isset($_REQUEST['session_max_rows']) + ) { + $this->ajaxAction(); + return; + } + + // Throw error if no sql query is set + if (!isset($this->sql_query) || $this->sql_query == '') { + $this->response->isSuccess(false); + $this->response->addHTML( + PMA_Message::error(__('No SQL query was set to fetch data.')) + ); + return; + } + + $this->response->getHeader()->getScripts()->addFiles(array( + 'chart.js', + 'tbl_chart.js', + 'jqplot/jquery.jqplot.js', + 'jqplot/plugins/jqplot.barRenderer.js', + 'jqplot/plugins/jqplot.canvasAxisLabelRenderer.js', + 'jqplot/plugins/jqplot.canvasTextRenderer.js', + 'jqplot/plugins/jqplot.categoryAxisRenderer.js', + 'jqplot/plugins/jqplot.dateAxisRenderer.js', + 'jqplot/plugins/jqplot.pointLabels.js', + 'jqplot/plugins/jqplot.pieRenderer.js', + 'jqplot/plugins/jqplot.highlighter.js' + )); + + /** + * Extract values for common work + * @todo Extract common files + */ + $db = &$this->db; + $table = &$this->table; + + /** + * Runs common work + */ + if (/*overload*/ + mb_strlen($this->table) + ) { + $url_params['goto'] = PMA_Util::getScriptNameForOption( + $this->cfg['DefaultTabTable'], 'table' + ); + $url_params['back'] = 'tbl_sql.php'; + include 'libraries/tbl_common.inc.php'; + include 'libraries/tbl_info.inc.php'; + } elseif (/*overload*/ + mb_strlen($this->db) + ) { + $url_params['goto'] = PMA_Util::getScriptNameForOption( + $this->cfg['DefaultTabDatabase'], 'database' + ); + $url_params['back'] = 'sql.php'; + include 'libraries/db_common.inc.php'; + include 'libraries/db_info.inc.php'; + } else { + $url_params['goto'] = PMA_Util::getScriptNameForOption( + $this->cfg['DefaultTabServer'], 'server' + ); + $url_params['back'] = 'sql.php'; + include 'libraries/server_common.inc.php'; + } + + $data = array(); + + $result = $this->dbi->tryQuery($this->sql_query); + $fields_meta = $this->dbi->getFieldsMeta($result); + while ($row = $this->dbi->fetchAssoc($result)) { + $data[] = $row; + } + + $keys = array_keys($data[0]); + + $numeric_types = array('int', 'real'); + $numeric_column_count = 0; + foreach ($keys as $idx => $key) { + if (in_array($fields_meta[$idx]->type, $numeric_types)) { + $numeric_column_count++; + } + } + + if ($numeric_column_count == 0) { + $this->response->isSuccess(false); + $this->response->addJSON( + 'message', + __('No numeric columns present in the table to plot.') + ); + return; + } + + $url_params['db'] = $this->db; + $url_params['reload'] = 1; + + /** + * Displays the page + */ + $this->response->addHTML(Template::get('tbl_chart') + ->render(array( + 'url_query' => $this->url_query, + 'url_params' => $url_params, + 'keys' => $keys, + 'fields_meta' => $fields_meta, + 'numeric_types' => $numeric_types, + 'numeric_column_count' => $numeric_column_count, + 'sql_query' => $this->sql_query + ))); + } + + /** + * Handle ajax request + */ + public function ajaxAction() + { + /** + * Extract values for common work + * @todo Extract common files + */ + $db = &$this->db; + $table = &$this->table; + + $tableLength = /*overload*/ + mb_strlen($this->table); + $dbLength = /*overload*/ + mb_strlen($this->db); + if ($tableLength && $dbLength) { + include './libraries/tbl_common.inc.php'; + } + + $sql_with_limit = sprintf( + 'SELECT * FROM(%s) AS `temp_res` LIMIT %s, %s', + $this->sql_query, + $_REQUEST['pos'], + $_REQUEST['session_max_rows'] + ); + $data = array(); + $result = $this->dbi->tryQuery($sql_with_limit); + while ($row = $this->dbi->fetchAssoc($result)) { + $data[] = $row; + } + + if (empty($data)) { + $this->response->isSuccess(false); + $this->response->addJSON('message', __('No data to display')); + return; + } + $sanitized_data = array(); + + foreach ($data as $data_row_number => $data_row) { + $tmp_row = array(); + foreach ($data_row as $data_column => $data_value) { + $tmp_row[htmlspecialchars($data_column)] = htmlspecialchars($data_value); + } + $sanitized_data[] = $tmp_row; + } + $this->response->isSuccess(true); + $this->response->addJSON('message', null); + $this->response->addJSON('chartData', json_encode($sanitized_data)); + } +} \ No newline at end of file diff --git a/libraries/controllers/table/TableGisVisualizationController.class.php b/libraries/controllers/table/TableGisVisualizationController.class.php new file mode 100644 index 0000000000..3912275019 --- /dev/null +++ b/libraries/controllers/table/TableGisVisualizationController.class.php @@ -0,0 +1,180 @@ +visualizationSettings + */ + protected $visualizationSettings; + + /** + * @var PMA_GIS_Visualization $visualization + */ + protected $visualization; + + public function __construct() { + $this->sql_query = &$GLOBALS['sql_query']; + + $this->url_params = &$GLOBALS['url_params']; + // Runs common work + require_once 'libraries/db_common.inc.php'; + $this->url_params['goto'] = PMA_Util::getScriptNameForOption( + $GLOBALS['cfg']['DefaultTabDatabase'], 'database' + ); + $this->url_params['back'] = 'sql.php'; + + $this->visualizationSettings = array(); + + // Convert geometric columns from bytes to text. + $pos = isset($_REQUEST['pos']) ? $_REQUEST['pos'] : $_SESSION['tmpval']['pos']; + if (isset($_REQUEST['session_max_rows'])) { + $rows = $_REQUEST['session_max_rows']; + } else { + if ($_SESSION['tmpval']['max_rows'] != 'all') { + $rows = $_SESSION['tmpval']['max_rows']; + } else { + $rows = $GLOBALS['cfg']['MaxRows']; + } + } + $this->visualization = PMA_GIS_Visualization::get( + $this->sql_query, + $this->visualizationSettings, + $rows, + $pos + ); + } + + public function saveToFileAction() { + $this->response->disable(); + $file_name = $this->visualizationSettings['spatialColumn']; + $save_format = $_REQUEST['fileFormat']; + $this->visualization->toFile($file_name, $save_format); + } + + public function indexAction() { + // Throw error if no sql query is set + if (! isset($sql_query) || $sql_query == '') { + $this->response->isSuccess(false); + $this->response->addHTML( + PMA_Message::error(__('No SQL query was set to fetch data.')) + ); + return; + } + + // Execute the query and return the result + $result = $this->dbi->tryQuery($sql_query); + // Get the meta data of results + $meta = $this->dbi->getFieldsMeta($result); + + // Find the candidate fields for label column and spatial column + $labelCandidates = array(); + $spatialCandidates = array(); + foreach ($meta as $column_meta) { + if ($column_meta->type == 'geometry') { + $spatialCandidates[] = $column_meta->name; + } else { + $labelCandidates[] = $column_meta->name; + } + } + + // Get settings if any posted + if (PMA_isValid($_REQUEST['visualizationSettings'], 'array')) { + $this->visualizationSettings = $_REQUEST['visualizationSettings']; + } + + if (! isset($this->visualizationSettings['labelColumn']) && isset($labelCandidates[0])) { + $this->visualizationSettings['labelColumn'] = ''; + } + + // If spatial column is not set, use first geometric column as spatial column + if (! isset($this->visualizationSettings['spatialColumn'])) { + $this->visualizationSettings['spatialColumn'] = $spatialCandidates[0]; + } + + if (isset($_REQUEST['saveToFile'])) { + $this->saveToFileAction(); + return; + } + + $this->response->getHeader()->getScripts()->addFiles( + array( + 'openlayers/OpenLayers.js', + 'jquery/jquery.svg.js', + 'tbl_gis_visualization.js', + 'OpenStreetMap.js' + ) + ); + + // If all the rows contain SRID, use OpenStreetMaps on the initial loading. + if (! isset($_REQUEST['displayVisualization'])) { + if ($this->visualization->hasSrid()) + unset($this->visualizationSettings['choice']); + $this->visualizationSettings['choice'] = 'useBaseLayer'; + } + + $this->visualization->setUserSpecifiedSettings($this->visualizationSettings); + if ($this->visualizationSettings != null) { + foreach ($this->visualization->getSettings() as $setting => $val) { + if (! isset($this->visualizationSettings[$setting])) { + $this->visualizationSettings[$setting] = $val; + } + } + } + + /** + * Displays the page + */ + $this->url_params['sql_query'] = $this->sql_query; + $downloadUrl = 'tbl_gis_visualization.php' . PMA_URL_getCommon($this->url_params) + . '&saveToFile=true'; + $svgSupport = (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER <= 8) + ? false : true; + $html = Template::get('gis_visualization/gis_visualization')->render( + array( + 'url_params' => $this->url_params, + 'downloadUrl' => $downloadUrl, + 'labelCandidates' => $labelCandidates, + 'spatialCandidates' => $spatialCandidates, + 'visualizationSettings' => $this->visualizationSettings, + 'sql_query' => $this->sql_query, + 'visualization' => $this->visualization->toImage($svgSupport ? 'svg' : 'png'), + 'svgSupport' => $svgSupport, + 'drawOl' => $this->visualization->asOl() + ) + ); + + $this->response->addHTML($html); + } +} \ No newline at end of file diff --git a/libraries/controllers/table/TableIndexesController.class.php b/libraries/controllers/table/TableIndexesController.class.php new file mode 100644 index 0000000000..01cbb24476 --- /dev/null +++ b/libraries/controllers/table/TableIndexesController.class.php @@ -0,0 +1,193 @@ +db = $GLOBALS['db']; + $this->table = $GLOBALS['table']; + + /** + * Extract values for common work + * @todo Extract common files + */ + $db = $this->db; + $table = $this->table; + + if (!isset($_REQUEST['create_edit_table'])) { + include_once 'libraries/tbl_common.inc.php'; + } + + if (isset($_REQUEST['index'])) { + if (is_array($_REQUEST['index'])) { + // coming already from form + $this->index = new PMA_Index($_REQUEST['index']); + } else { + $this->index = $this->dbi->getTable($this->db, $this->table) + ->getIndex($_REQUEST['index']); + } + } else { + $this->index = new PMA_Index; + } + } + + public function indexAction() + { + if (isset($_REQUEST['do_save_data'])) { + $this->doSaveDataAction(); + return; + } // end builds the new index + + $this->displayFormAction(); + } + + /** + * Display the form to edit/create an index + */ + public function displayFormAction() + { + include_once 'libraries/tbl_info.inc.php'; + + $add_fields = 0; + if (isset($_REQUEST['index']) && is_array($_REQUEST['index'])) { + // coming already from form + if (isset($_REQUEST['index']['columns']['names'])) { + $add_fields = count($_REQUEST['index']['columns']['names']) + - $this->index->getColumnCount(); + } + if (isset($_REQUEST['add_fields'])) { + $add_fields += $_REQUEST['added_fields']; + } + } elseif (isset($_REQUEST['create_index'])) { + $add_fields = $_REQUEST['added_fields']; + } // end preparing form values + + // Get fields and stores their name/type + if (isset($_REQUEST['create_edit_table'])) { + $fields = json_decode($_REQUEST['columns'], true); + $index_params = array( + 'Non_unique' => ($_REQUEST['index']['Index_choice'] == 'UNIQUE') ? '0' : '1' + ); + $this->index->set($index_params); + $add_fields = count($fields); + } else { + $fields = $this->dbi->getTable($this->db, $this->table)->getNameAndTypeOfTheColumns(); + } + + $form_params = array( + 'db' => $this->db, + 'table' => $this->table, + ); + + if (isset($_REQUEST['create_index'])) { + $form_params['create_index'] = 1; + } elseif (isset($_REQUEST['old_index'])) { + $form_params['old_index'] = $_REQUEST['old_index']; + } elseif (isset($_REQUEST['index'])) { + $form_params['old_index'] = $_REQUEST['index']; + } + + $this->response->getHeader()->getScripts()->addFile('indexes.js'); + + $this->response->addHTML(Template::get('index_form') + ->render(array( + 'fields' => $fields, + 'index' => $this->index, + 'form_params' => $form_params, + 'add_fields' => $add_fields + )) + ); + } + + /** + * Process the data from the edit/create index form, + * run the query to build the new index + * and moves back to "tbl_sql.php" + */ + public function doSaveDataAction() + { + $error = false; + + $sql_query = $this->dbi->getTable($this->db, $this->table) + ->getSqlQueryForIndexCreateOrEdit($this->index, $error); + + // If there is a request for SQL previewing. + if (isset($_REQUEST['preview_sql'])) { + + PMA_Response::getInstance()->addJSON( + 'sql_data', + Template::get('preview_sql') + ->render( + array( + 'query_data' => $sql_query + ) + ) + ); + } elseif (!$error) { + + $this->dbi->query($sql_query); + if ($GLOBALS['is_ajax_request'] == true) { + $message = PMA_Message::success( + __('Table %1$s has been altered successfully.') + ); + $message->addParam($this->table); + $response = PMA_Response::getInstance(); + $response->addJSON( + 'message', PMA_Util::getMessage($message, $sql_query, 'success') + ); + $response->addJSON( + 'index_table', PMA_Index::getHtmlForIndexes( + $this->table, $this->db + ) + ); + } else { + include 'tbl_structure.php'; + } + } else { + $response = PMA_Response::getInstance(); + $response->isSuccess(false); + $response->addJSON('message', $error); + } + } +} diff --git a/libraries/controllers/table/TableRelationController.class.php b/libraries/controllers/table/TableRelationController.class.php new file mode 100644 index 0000000000..65e20d9a40 --- /dev/null +++ b/libraries/controllers/table/TableRelationController.class.php @@ -0,0 +1,356 @@ +options_array = array( + 'CASCADE' => 'CASCADE', + 'SET_NULL' => 'SET NULL', + 'NO_ACTION' => 'NO ACTION', + 'RESTRICT' => 'RESTRICT', + ); + // Gets the relation settings + $this->cfgRelation = PMA_getRelationsParam(); + $this->db = &$GLOBALS['db']; + $this->table = &$GLOBALS['table']; + $this->tbl_storage_engine = /*overload*/ + mb_strtoupper( + PMA_Table::sGetStatusInfo( + $_REQUEST['db'], + $_REQUEST['table'], + 'Engine' + ) + ); + /** + * Updates + */ + if ($this->cfgRelation['relwork']) { + $this->existrel = PMA_getForeigners($this->db, $this->table, '', 'internal'); + } + if (PMA_Util::isForeignKeySupported($this->tbl_storage_engine)) { + $this->existrel_foreign = PMA_getForeigners($this->db, $this->table, '', 'foreign'); + } + if ($this->cfgRelation['displaywork']) { + $this->disp = PMA_getDisplayField($this->db, $this->table); + } else { + $this->disp = ''; + } + + $this->upd_query = new PMA_Table($this->table, $this->db, $this->dbi); + } + + public function indexAction() + { + // Send table of column names to populate corresponding dropdowns depending + // on the current selection + if (isset($_REQUEST['getDropdownValues']) + && $_REQUEST['getDropdownValues'] === 'true' + ) { + // if both db and table are selected + if (isset($_REQUEST['foreignTable'])) { + $this->getDropdownValueForTableAction(); + } else { // if only the db is selected + $this->getDropdownValueForDbAction(); + } + return; + } + + $this->response->getHeader()->getScripts()->addFiles( + array( + 'tbl_relation.js', + 'indexes.js' + ) + ); + + // Gets tables information + require_once 'libraries/tbl_info.inc.php'; + + // updates for Internal relations + if (isset($_POST['destination_db']) && $this->cfgRelation['relwork']) { + $this->updateForInternalRelationAction(); + } + + // updates for foreign keys + if (isset($_POST['destination_foreign_db'])) { + $this->updateForForeignKeysAction(); + } + + // Updates for display field + if ($this->cfgRelation['displaywork'] && isset($_POST['display_field'])) { + $this->updateForDisplayField(); + } + + // If we did an update, refresh our data + if (isset($_POST['destination_db']) && $this->cfgRelation['relwork']) { + $this->existrel = PMA_getForeigners($this->db, $this->table, '', 'internal'); + } + if (isset($_POST['destination_foreign_db']) + && PMA_Util::isForeignKeySupported($this->tbl_storage_engine) + ) { + $this->existrel_foreign = PMA_getForeigners($this->db, $this->table, '', 'foreign'); + } + + if ($this->cfgRelation['displaywork']) { + $this->disp = PMA_getDisplayField($this->db, $this->table); + } + + // display secondary level tabs if necessary + $engine = PMA_Table::sGetStatusInfo($this->db, $this->table, 'ENGINE'); + $this->response->addHTML(PMA_getStructureSecondaryTabs($engine)); + $this->response->addHTML('
'); + + /** + * Dialog + */ + // Now find out the columns of our $table + // need to use PMA_DatabaseInterface::QUERY_STORE with $this->dbi->numRows() + // in mysqli + $columns = $this->dbi->getColumns($this->db, $this->table); + + // common form + $this->response->addHTML(Template::get('tbl_relation/common_form')->render( + array( + 'db' => $this->db, + 'table' => $this->table, + 'columns' => $columns, + 'cfgRelation' => $this->cfgRelation, + 'tbl_storage_engine' => $this->tbl_storage_engine, + 'existrel' => isset($this->existrel) ? $this->existrel : array(), + 'existrel_foreign' => isset($this->existrel_foreign) ? $this->existrel_foreign['foreign_keys_data'] : array(), + 'options_array' => $this->options_array + ) + )); + + if (PMA_Util::isForeignKeySupported($this->tbl_storage_engine)) { + $this->response->addHTML(PMA_getHtmlForDisplayIndexes()); + } + $this->response->addHTML('
'); + } + + public function updateForDisplayField() + { + if ($this->upd_query->updateDisplayField($this->disp, $_POST['display_field'], $this->cfgRelation)) { + $this->response->addHTML(PMA_Util::getMessage( + __('Display column was successfully updated.'), + '', 'success') + ); + } + } + + public function updateForForeignKeysAction() + { + $multi_edit_columns_name = isset($_REQUEST['foreign_key_fields_name']) + ? $_REQUEST['foreign_key_fields_name'] + : null; + + // (for now, one index name only; we keep the definitions if the + // foreign db is not the same) + list($html, $preview_sql_data, $display_query, $seen_error) = $this->upd_query->updateForeignKeys( + $_POST['destination_foreign_db'], + $multi_edit_columns_name, $_POST['destination_foreign_table'], + $_POST['destination_foreign_column'], $this->options_array, $this->table, + isset($existrel_foreign) ? $existrel_foreign['foreign_keys_data'] : null + ); + $this->response->addHTML($html); + + // If there is a request for SQL previewing. + if (isset($_REQUEST['preview_sql'])) { + PMA_previewSQL($preview_sql_data); + } + + if (!empty($display_query) && !$seen_error) { + $GLOBALS['display_query'] = $display_query; + $this->response->addHTML(PMA_Util::getMessage( + __('Your SQL query has been executed successfully.'), + null, 'success' + )); + } + } + + public function updateForInternalRelationAction() + { + $multi_edit_columns_name = isset($_REQUEST['fields_name']) + ? $_REQUEST['fields_name'] + : null; + + if ($this->upd_query->updateInternalRelations( + $multi_edit_columns_name, $_POST['destination_db'], $_POST['destination_table'], + $_POST['destination_column'], $this->cfgRelation, isset($existrel) ? $existrel : null + ) + ) { + $this->response->addHTML(PMA_Util::getMessage( + __('Internal relations were successfully updated.'), + '', 'success' + )); + } + } + + /** + * Send table columns for foreign table dropdown + * + * @return void + * + */ + public function getDropdownValueForTableAction() + { + $foreignTable = $_REQUEST['foreignTable']; + $table_obj = new PMA_Table($foreignTable, $_REQUEST['foreignDb']); + // Since views do not have keys defined on them provide the full list of columns + if (PMA_Table::isView($_REQUEST['foreignDb'], $foreignTable)) { + $columnList = $table_obj->getColumns(false, false); + } else { + $columnList = $table_obj->getIndexedColumns(false, false); + } + $columns = array(); + foreach ($columnList as $column) { + $columns[] = htmlspecialchars($column); + } + $this->response->addJSON('columns', $columns); + + // @todo should be: $server->db($db)->table($table)->primary() + $primary = PMA_Index::getPrimary($foreignTable, $_REQUEST['foreignDb']); + if (false === $primary) { + return; + } + + $this->response->addJSON('primary', array_keys($primary->getColumns())); + } + + /** + * Send database selection values for dropdown + * + * @return void + * + */ + public function getDropdownValueForDbAction() + { + $tables = array(); + $foreign = isset($_REQUEST['foreign']) && $_REQUEST['foreign'] === 'true'; + + // In Drizzle, 'SHOW TABLE STATUS' will show status only for the tables + // which are currently in the table cache. Hence we have to use 'SHOW TABLES' + // and manually retrieve table engine values. + if ($foreign && !PMA_DRIZZLE) { + $query = 'SHOW TABLE STATUS FROM ' + . PMA_Util::backquote($_REQUEST['foreignDb']); + $tables_rs = $this->dbi->query( + $query, + null, + PMA_DatabaseInterface::QUERY_STORE + ); + + while ($row = $this->dbi->fetchArray($tables_rs)) { + if (isset($row['Engine']) + && /*overload*/ + mb_strtoupper($row['Engine']) == $this->tbl_storage_engine + ) { + $tables[] = htmlspecialchars($row['Name']); + } + } + } else { + $query = 'SHOW TABLES FROM ' + . PMA_Util::backquote($_REQUEST['foreignDb']); + $tables_rs = $this->dbi->query( + $query, + null, + PMA_DatabaseInterface::QUERY_STORE + ); + while ($row = $this->dbi->fetchArray($tables_rs)) { + if ($foreign && PMA_DRIZZLE) { + $engine = /*overload*/ + mb_strtoupper( + PMA_Table::sGetStatusInfo( + $_REQUEST['foreignDb'], + $row[0], + 'Engine' + ) + ); + if (isset($engine) && $engine == $this->tbl_storage_engine) { + $tables[] = htmlspecialchars($row[0]); + } + } else { + $tables[] = htmlspecialchars($row[0]); + } + } + } + $this->response->addJSON('tables', $tables); + } +} \ No newline at end of file diff --git a/libraries/gis/GIS_Visualization.class.php b/libraries/gis/GIS_Visualization.class.php index 8400774a0c..f9f34dead8 100644 --- a/libraries/gis/GIS_Visualization.class.php +++ b/libraries/gis/GIS_Visualization.class.php @@ -617,5 +617,13 @@ class PMA_GIS_Visualization } return $results; } + + /** + * @param array $userSpecifiedSettings + */ + public function setUserSpecifiedSettings($userSpecifiedSettings) + { + $this->_userSpecifiedSettings = $userSpecifiedSettings; + } } ?> diff --git a/tbl_chart.php b/tbl_chart.php index f6cd4c0644..ee6354cfe6 100644 --- a/tbl_chart.php +++ b/tbl_chart.php @@ -6,151 +6,9 @@ * @package PhpMyAdmin */ -require_once 'libraries/common.inc.php'; -require_once 'libraries/Template.class.php'; -use PMA\Template; +require_once 'libraries/controllers/table/TableChartController.class.php'; -/* - * Execute the query and return the result - */ -if (isset($_REQUEST['ajax_request']) - && isset($_REQUEST['pos']) - && isset($_REQUEST['session_max_rows']) -) { - $response = PMA_Response::getInstance(); +use PMA\Controllers\Table\TableChartController; - $tableLength = /*overload*/mb_strlen($GLOBALS['table']); - $dbLength = /*overload*/mb_strlen($GLOBALS['db']); - if ($tableLength && $dbLength) { - include './libraries/tbl_common.inc.php'; - } - - $sql_with_limit = 'SELECT * FROM( ' . $sql_query . ' ) AS `temp_res` LIMIT ' - . $_REQUEST['pos'] . ', ' . $_REQUEST['session_max_rows']; - $data = array(); - $result = $GLOBALS['dbi']->tryQuery($sql_with_limit); - while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { - $data[] = $row; - } - - if (empty($data)) { - $response->isSuccess(false); - $response->addJSON('message', __('No data to display')); - exit; - } - $sanitized_data = array(); - - foreach ($data as $data_row_number => $data_row) { - $tmp_row = array(); - foreach ($data_row as $data_column => $data_value) { - $tmp_row[htmlspecialchars($data_column)] = htmlspecialchars($data_value); - } - $sanitized_data[] = $tmp_row; - } - $response->isSuccess(true); - $response->addJSON('message', null); - $response->addJSON('chartData', json_encode($sanitized_data)); - unset($sanitized_data); - exit; -} - -$response = PMA_Response::getInstance(); -// Throw error if no sql query is set -if (! isset($sql_query) || $sql_query == '') { - $response->isSuccess(false); - $response->addHTML( - PMA_Message::error(__('No SQL query was set to fetch data.')) - ); - exit; -} -$header = $response->getHeader(); -$scripts = $header->getScripts(); -$scripts->addFile('chart.js'); -$scripts->addFile('tbl_chart.js'); -$scripts->addFile('jqplot/jquery.jqplot.js'); -$scripts->addFile('jqplot/plugins/jqplot.barRenderer.js'); -$scripts->addFile('jqplot/plugins/jqplot.canvasAxisLabelRenderer.js'); -$scripts->addFile('jqplot/plugins/jqplot.canvasTextRenderer.js'); -$scripts->addFile('jqplot/plugins/jqplot.categoryAxisRenderer.js'); -$scripts->addFile('jqplot/plugins/jqplot.dateAxisRenderer.js'); -$scripts->addFile('jqplot/plugins/jqplot.pointLabels.js'); -$scripts->addFile('jqplot/plugins/jqplot.pieRenderer.js'); -$scripts->addFile('jqplot/plugins/jqplot.highlighter.js'); - -/** - * Runs common work - */ -if (/*overload*/mb_strlen($GLOBALS['table'])) { - $url_params['goto'] = PMA_Util::getScriptNameForOption( - $GLOBALS['cfg']['DefaultTabTable'], 'table' - ); - $url_params['back'] = 'tbl_sql.php'; - include 'libraries/tbl_common.inc.php'; - include 'libraries/tbl_info.inc.php'; -} elseif (/*overload*/mb_strlen($GLOBALS['db'])) { - $url_params['goto'] = PMA_Util::getScriptNameForOption( - $GLOBALS['cfg']['DefaultTabDatabase'], 'database' - ); - $url_params['back'] = 'sql.php'; - include 'libraries/db_common.inc.php'; - include 'libraries/db_info.inc.php'; -} else { - $url_params['goto'] = PMA_Util::getScriptNameForOption( - $GLOBALS['cfg']['DefaultTabServer'], 'server' - ); - $url_params['back'] = 'sql.php'; - include 'libraries/server_common.inc.php'; -} - -$data = array(); - -$result = $GLOBALS['dbi']->tryQuery($sql_query); -$fields_meta = $GLOBALS['dbi']->getFieldsMeta($result); -while ($row = $GLOBALS['dbi']->fetchAssoc($result)) { - $data[] = $row; -} - -$keys = array_keys($data[0]); - -$numeric_types = array('int', 'real'); -$numeric_column_count = 0; -foreach ($keys as $idx => $key) { - if (in_array($fields_meta[$idx]->type, $numeric_types)) { - $numeric_column_count++; - } -} -if ($numeric_column_count == 0) { - $response->isSuccess(false); - $response->addJSON( - 'message', - __('No numeric columns present in the table to plot.') - ); - exit; -} - -// get settings if any posted -$chartSettings = array(); -if (PMA_isValid($_REQUEST['chartSettings'], 'array')) { - $chartSettings = $_REQUEST['chartSettings']; -} - -$url_params['db'] = $GLOBALS['db']; -$url_params['reload'] = 1; - -/** - * Displays the page - */ -$response->addHTML( - Template::get('tbl_chart') - ->render( - array( - 'url_query' => $url_query, - 'url_params' => $url_params, - 'keys' => $keys, - 'fields_meta' => $fields_meta, - 'numeric_types' => $numeric_types, - 'numeric_column_count' => $numeric_column_count, - 'sql_query' => $sql_query - ) - ) -); +$controller = new TableChartController(); +$controller->indexAction(); diff --git a/tbl_gis_visualization.php b/tbl_gis_visualization.php index c6ddfb319f..8f2e633eca 100644 --- a/tbl_gis_visualization.php +++ b/tbl_gis_visualization.php @@ -6,126 +6,9 @@ * @package PhpMyAdmin */ -require_once 'libraries/common.inc.php'; -require_once './libraries/gis/GIS_Visualization.class.php'; -require_once './libraries/gis/GIS_Factory.class.php'; +use PMA\Controllers\Table\TableGisVisualizationController; -// Runs common work -require_once 'libraries/db_common.inc.php'; -$url_params['goto'] = PMA_Util::getScriptNameForOption( - $GLOBALS['cfg']['DefaultTabDatabase'], 'database' -); -$url_params['back'] = 'sql.php'; +require_once 'libraries/controllers/table/TableGisVisualizationController.class.php'; -$response = PMA_Response::getInstance(); -// Throw error if no sql query is set -if (! isset($sql_query) || $sql_query == '') { - $response->isSuccess(false); - $response->addHTML( - PMA_Message::error(__('No SQL query was set to fetch data.')) - ); - exit; -} - -// Execute the query and return the result -$result = $GLOBALS['dbi']->tryQuery($sql_query); -// Get the meta data of results -$meta = $GLOBALS['dbi']->getFieldsMeta($result); - -// Find the candidate fields for label column and spatial column -$labelCandidates = array(); $spatialCandidates = array(); -foreach ($meta as $column_meta) { - if ($column_meta->type == 'geometry') { - $spatialCandidates[] = $column_meta->name; - } else { - $labelCandidates[] = $column_meta->name; - } -} - -// Get settings if any posted -$visualizationSettings = array(); -if (PMA_isValid($_REQUEST['visualizationSettings'], 'array')) { - $visualizationSettings = $_REQUEST['visualizationSettings']; -} - -if (! isset($visualizationSettings['labelColumn']) && isset($labelCandidates[0])) { - $visualizationSettings['labelColumn'] = ''; -} - -// If spatial column is not set, use first geometric column as spatial column -if (! isset($visualizationSettings['spatialColumn'])) { - $visualizationSettings['spatialColumn'] = $spatialCandidates[0]; -} - -// Convert geometric columns from bytes to text. -$pos = isset($_REQUEST['pos']) ? $_REQUEST['pos'] : $_SESSION['tmpval']['pos']; -if (isset($_REQUEST['session_max_rows'])) { - $rows = $_REQUEST['session_max_rows']; -} else { - if ($_SESSION['tmpval']['max_rows'] != 'all') { - $rows = $_SESSION['tmpval']['max_rows']; - } else { - $rows = $GLOBALS['cfg']['MaxRows']; - } -} - -if (isset($_REQUEST['saveToFile'])) { - $response->disable(); - $file_name = $visualizationSettings['spatialColumn']; - $save_format = $_REQUEST['fileFormat']; - $visualization = PMA_GIS_Visualization::get($sql_query, $visualizationSettings, $rows, $pos); - $visualization->toFile($file_name, $save_format); - exit(); -} - -$header = $response->getHeader(); -$scripts = $header->getScripts(); -$scripts->addFile('openlayers/OpenLayers.js'); -$scripts->addFile('jquery/jquery.svg.js'); -$scripts->addFile('tbl_gis_visualization.js'); -$scripts->addFile('OpenStreetMap.js'); - -// If all the rows contain SRID, use OpenStreetMaps on the initial loading. -if (! isset($_REQUEST['displayVisualization'])) { - $visualization = PMA_GIS_Visualization::get($sql_query, $visualizationSettings, $rows, $pos); - if ($visualization->hasSrid()) - unset($visualizationSettings['choice']); - $visualizationSettings['choice'] = 'useBaseLayer'; -} - -$svgSupport = (PMA_USR_BROWSER_AGENT == 'IE' && PMA_USR_BROWSER_VER <= 8) - ? false : true; -$format = $svgSupport ? 'svg' : 'png'; - -$visualization = PMA_GIS_Visualization::get($sql_query, $visualizationSettings, $rows, $pos); -if ($visualizationSettings != null) { - foreach ($visualization->getSettings() as $setting => $val) { - if (! isset($visualizationSettings[$setting])) { - $visualizationSettings[$setting] = $val; - } - } -} - -$result = $visualization->toImage($format); - -/** - * Displays the page - */ -$url_params['sql_query'] = $sql_query; -$downloadUrl = 'tbl_gis_visualization.php' . PMA_URL_getCommon($url_params) - . '&saveToFile=true'; -$html = PMA\Template::get('gis_visualization/gis_visualization')->render( - array( - 'url_params' => $url_params, - 'downloadUrl' => $downloadUrl, - 'labelCandidates' => $labelCandidates, - 'spatialCandidates' => $spatialCandidates, - 'visualizationSettings' => $visualizationSettings, - 'sql_query' => $sql_query, - 'visualization' => $result, - 'svgSupport' => $svgSupport, - 'drawOl' => $visualization->asOl() - ) -); - -$response->addHTML($html); +$controller = new TableGisVisualizationController(); +$controller->indexAction(); diff --git a/tbl_indexes.php b/tbl_indexes.php index ebf70f3480..e20d02847b 100644 --- a/tbl_indexes.php +++ b/tbl_indexes.php @@ -6,131 +6,9 @@ * @package PhpMyAdmin */ -/** - * Gets some core libraries - */ -require_once 'libraries/common.inc.php'; -require_once 'libraries/Index.class.php'; -require_once 'libraries/Template.class.php'; +require_once 'libraries/controllers/table/TableIndexesController.class.php'; -if (! isset($_REQUEST['create_edit_table'])) { - include_once 'libraries/tbl_common.inc.php'; -} +use PMA\Controllers\Table\TableIndexesController; -if (isset($_REQUEST['index'])) { - if (is_array($_REQUEST['index'])) { - // coming already from form - $index = new PMA_Index($_REQUEST['index']); - } else { - $index = $GLOBALS['dbi']->getTable($db, $table) - ->getIndex($_REQUEST['index']); - } -} else { - $index = new PMA_Index; -} - -/** - * Process the data from the edit/create index form, - * run the query to build the new index - * and moves back to "tbl_sql.php" - */ -if (isset($_REQUEST['do_save_data'])) { - - $error = false; - - $sql_query = $GLOBALS['dbi']->getTable($db, $table) - ->getSqlQueryForIndexCreateOrEdit($index, $error); - - // If there is a request for SQL previewing. - if (isset($_REQUEST['preview_sql'])) { - - PMA_Response::getInstance()->addJSON( - 'sql_data', - PMA\Template::get('preview_sql') - ->render( - array( - 'query_data' => $sql_query - ) - ) - ); - } elseif (!$error) { - - $GLOBALS['dbi']->query($sql_query); - if ($GLOBALS['is_ajax_request'] == true) { - $message = PMA_Message::success( - __('Table %1$s has been altered successfully.') - ); - $message->addParam($table); - $response = PMA_Response::getInstance(); - $response->addJSON( - 'message', PMA_Util::getMessage($message, $sql_query, 'success') - ); - $response->addJSON('index_table', PMA_Index::getHtmlForIndexes($table, $db)); - } else { - include 'tbl_structure.php'; - } - } else { - $response = PMA_Response::getInstance(); - $response->isSuccess(false); - $response->addJSON('message', $error); - } - exit; -} // end builds the new index - - -/** - * Display the form to edit/create an index - */ -require_once 'libraries/tbl_info.inc.php'; - -$add_fields = 0; -if (isset($_REQUEST['index']) && is_array($_REQUEST['index'])) { - // coming already from form - if (isset($_REQUEST['index']['columns']['names'])) { - $add_fields = count($_REQUEST['index']['columns']['names']) - - $index->getColumnCount(); - } - if (isset($_REQUEST['add_fields'])) { - $add_fields += $_REQUEST['added_fields']; - } -} elseif (isset($_REQUEST['create_index'])) { - $add_fields = $_REQUEST['added_fields']; -} // end preparing form values - -// Get fields and stores their name/type -if (isset($_REQUEST['create_edit_table'])) { - $fields = json_decode($_REQUEST['columns'], true); - $index_params = array( - 'Non_unique' => ($_REQUEST['index']['Index_choice'] == 'UNIQUE') ? '0' : '1' - ); - $index->set($index_params); - $add_fields = count($fields); -} else { - $fields = $GLOBALS['dbi']->getTable($db, $table)->getNameAndTypeOfTheColumns(); -} - -$form_params = array( - 'db' => $db, - 'table' => $table, -); - -if (isset($_REQUEST['create_index'])) { - $form_params['create_index'] = 1; -} elseif (isset($_REQUEST['old_index'])) { - $form_params['old_index'] = $_REQUEST['old_index']; -} elseif (isset($_REQUEST['index'])) { - $form_params['old_index'] = $_REQUEST['index']; -} - -$response = PMA_Response::getInstance(); -$response->addHTML(PMA\Template::get('index_form') - ->render(array( - 'fields' => $fields, - 'index' => $index, - 'form_params' => $form_params, - 'add_fields' => $add_fields - )) -); -$header = $response->getHeader(); -$scripts = $header->getScripts(); -$scripts->addFile('indexes.js'); +$controller = new TableIndexesController(); +$controller->indexAction(); diff --git a/tbl_relation.php b/tbl_relation.php index 21a69ba70d..103ef61d0a 100644 --- a/tbl_relation.php +++ b/tbl_relation.php @@ -15,251 +15,11 @@ */ /** - * Gets some core libraries + * Get the TableRelationController */ -require_once 'libraries/common.inc.php'; -require_once 'libraries/index.lib.php'; -require_once 'libraries/Template.class.php'; -require_once 'libraries/Table.class.php'; -require_once 'libraries/structure.lib.php'; +require_once 'libraries/controllers/table/TableRelationController.class.php'; -$response = PMA_Response::getInstance(); +use PMA\Controllers\Table\TableRelationController; -// Send table of column names to populate corresponding dropdowns depending -// on the current selection -if (isset($_REQUEST['getDropdownValues']) - && $_REQUEST['getDropdownValues'] === 'true' -) { - if (isset($_REQUEST['foreignTable'])) { // if both db and table are selected - $foreignTable = $_REQUEST['foreignTable']; - $table_obj = new PMA_Table($foreignTable, $_REQUEST['foreignDb']); - // Since views do not have keys defined on them provide the full list of columns - if (PMA_Table::isView($_REQUEST['foreignDb'], $foreignTable)) { - $columnList = $table_obj->getColumns(false, false); - } else { - $columnList = $table_obj->getIndexedColumns(false, false); - } - $columns = array(); - foreach ($columnList as $column) { - $columns[] = htmlspecialchars($column); - } - $response->addJSON('columns', $columns); - - // @todo should be: $server->db($db)->table($table)->primary() - $primary = PMA_Index::getPrimary($foreignTable, $_REQUEST['foreignDb']); - if (false === $primary) { - return; - } - - $primarycols = array_keys($primary->getColumns()); - $response->addJSON('primary', $primarycols); - } else { // if only the db is selected - $tables = array(); - $foreign = isset($_REQUEST['foreign']) && $_REQUEST['foreign'] === 'true'; - if ($foreign) { - $tbl_storage_engine = /*overload*/mb_strtoupper( - PMA_Table::sGetStatusInfo( - $_REQUEST['db'], - $_REQUEST['table'], - 'Engine' - ) - ); - } - - // In Drizzle, 'SHOW TABLE STATUS' will show status only for the tables - // which are currently in the table cache. Hence we have to use 'SHOW TABLES' - // and manually retrieve table engine values. - if ($foreign && ! PMA_DRIZZLE) { - $query = 'SHOW TABLE STATUS FROM ' - . PMA_Util::backquote($_REQUEST['foreignDb']); - $tables_rs = $GLOBALS['dbi']->query( - $query, - null, - PMA_DatabaseInterface::QUERY_STORE - ); - - while ($row = $GLOBALS['dbi']->fetchArray($tables_rs)) { - if (isset($row['Engine']) - && /*overload*/mb_strtoupper($row['Engine']) == $tbl_storage_engine - ) { - $tables[] = htmlspecialchars($row['Name']); - } - } - } else { - $query = 'SHOW TABLES FROM ' - . PMA_Util::backquote($_REQUEST['foreignDb']); - $tables_rs = $GLOBALS['dbi']->query( - $query, - null, - PMA_DatabaseInterface::QUERY_STORE - ); - while ($row = $GLOBALS['dbi']->fetchArray($tables_rs)) { - if ($foreign && PMA_DRIZZLE) { - $engine = /*overload*/mb_strtoupper( - PMA_Table::sGetStatusInfo( - $_REQUEST['foreignDb'], - $row[0], - 'Engine' - ) - ); - if (isset($engine) && $engine == $tbl_storage_engine) { - $tables[] = htmlspecialchars($row[0]); - } - } else { - $tables[] = htmlspecialchars($row[0]); - } - } - } - $response->addJSON('tables', $tables); - } - exit; -} - -$header = $response->getHeader(); -$scripts = $header->getScripts(); -$scripts->addFile('tbl_relation.js'); -$scripts->addFile('indexes.js'); - -/** - * Gets tables information - */ -require_once 'libraries/tbl_info.inc.php'; - -$options_array = array( - 'CASCADE' => 'CASCADE', - 'SET_NULL' => 'SET NULL', - 'NO_ACTION' => 'NO ACTION', - 'RESTRICT' => 'RESTRICT', -); - -/** - * Gets the relation settings - */ -$cfgRelation = PMA_getRelationsParam(); - -/** - * Updates - */ -if ($cfgRelation['relwork']) { - $existrel = PMA_getForeigners($db, $table, '', 'internal'); -} -if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) { - $existrel_foreign = PMA_getForeigners($db, $table, '', 'foreign'); -} -if ($cfgRelation['displaywork']) { - $disp = PMA_getDisplayField($db, $table); -} else { - $disp = ''; -} - -// will be used in the logic for internal relations and foreign keys: -$multi_edit_columns_name = isset($_REQUEST['fields_name']) - ? $_REQUEST['fields_name'] - : null; - - -$html_output = ''; -$upd_query = new PMA_Table($table, $db, $GLOBALS['dbi']); - -// u p d a t e s f o r I n t e r n a l r e l a t i o n s -if (isset($_POST['destination_db']) && $cfgRelation['relwork']) { - if ($upd_query->updateInternalRelations( - $multi_edit_columns_name, $_POST['destination_db'], $_POST['destination_table'], - $_POST['destination_column'], $cfgRelation, isset($existrel) ? $existrel : null - )) { - $html_output .= PMA_Util::getMessage( - __('Internal relations were successfully updated.'), - '', 'success' - ); - } -} // end if (updates for internal relations) - -$multi_edit_columns_name = isset($_REQUEST['foreign_key_fields_name']) - ? $_REQUEST['foreign_key_fields_name'] - : null; - -// u p d a t e s f o r f o r e i g n k e y s -// (for now, one index name only; we keep the definitions if the -// foreign db is not the same) -if (isset($_POST['destination_foreign_db'])) { - list($html, $preview_sql_data, $display_query, $seen_error) = $upd_query->updateForeignKeys( - $_POST['destination_foreign_db'], - $multi_edit_columns_name, $_POST['destination_foreign_table'], - $_POST['destination_foreign_column'], $options_array, $table, - isset($existrel_foreign) ? $existrel_foreign['foreign_keys_data'] : null - ); - $html_output .= $html; - - // If there is a request for SQL previewing. - if (isset($_REQUEST['preview_sql'])) { - PMA_previewSQL($preview_sql_data); - } - - if (! empty($display_query) && ! $seen_error) { - $GLOBALS['display_query'] = $display_query; - $html_output .= PMA_Util::getMessage( - __('Your SQL query has been executed successfully.'), - null, 'success' - ); - } -} // end if isset($destination_foreign) - -// U p d a t e s f o r d i s p l a y f i e l d -if ($cfgRelation['displaywork'] && isset($_POST['display_field'])) { - if ($upd_query->updateDisplayField($disp, $_POST['display_field'], $cfgRelation)) { - $html_output .= PMA_Util::getMessage( - __('Display column was successfully updated.'), - '', 'success' - ); - } -} // end if - -// If we did an update, refresh our data -if (isset($_POST['destination_db']) && $cfgRelation['relwork']) { - $existrel = PMA_getForeigners($db, $table, '', 'internal'); -} -if (isset($_POST['destination_foreign_db']) - && PMA_Util::isForeignKeySupported($tbl_storage_engine) -) { - $existrel_foreign = PMA_getForeigners($db, $table, '', 'foreign'); -} - -if ($cfgRelation['displaywork']) { - $disp = PMA_getDisplayField($db, $table); -} - - -// display secondary level tabs if necessary -$engine = PMA_Table::sGetStatusInfo($db, $table, 'ENGINE'); -$response->addHTML(PMA_getStructureSecondaryTabs($engine)); -$response->addHTML('
'); - -/** - * Dialog - */ -// Now find out the columns of our $table -// need to use PMA_DatabaseInterface::QUERY_STORE with $GLOBALS['dbi']->numRows() -// in mysqli -$columns = $GLOBALS['dbi']->getColumns($db, $table); - -// common form -$html_output .= PMA\Template::get('tbl_relation/common_form')->render( - array( - 'db' => $db, - 'table' => $table, - 'columns' => $columns, - 'cfgRelation' => $cfgRelation, - 'tbl_storage_engine' => $tbl_storage_engine, - 'existrel' => isset($existrel) ? $existrel : array(), - 'existrel_foreign' => isset($existrel_foreign) ? $existrel_foreign['foreign_keys_data'] : array(), - 'options_array' => $options_array - ) -); - -if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) { - $html_output .= PMA_getHtmlForDisplayIndexes(); -} -// Render HTML output -$response->addHTML($html_output); - -$response->addHTML('
'); +$tblRelationCtrl = new TableRelationController(); +$tblRelationCtrl->indexAction(); From 452ccc58d350c003ca89ad4f0ff9598dd7d28249 Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 30 Jun 2015 10:08:03 +0800 Subject: [PATCH 02/16] Introduce dependency injection container Signed-off-by: Jason --- libraries/database_interface.inc.php | 8 +- libraries/di/AliasItem.class.php | 37 +++++ libraries/di/Container.class.php | 142 ++++++++++++++++++ libraries/di/FactoryItem.class.php | 30 ++++ libraries/di/Item.int.php | 14 ++ libraries/di/ReflectorItem.class.php | 113 ++++++++++++++ libraries/di/ServiceItem.class.php | 36 +++++ libraries/di/ValueItem.class.php | 32 ++++ libraries/tbl_columns_definition_form.inc.php | 12 +- tbl_chart.php | 11 +- 10 files changed, 426 insertions(+), 9 deletions(-) create mode 100644 libraries/di/AliasItem.class.php create mode 100644 libraries/di/Container.class.php create mode 100644 libraries/di/FactoryItem.class.php create mode 100644 libraries/di/Item.int.php create mode 100644 libraries/di/ReflectorItem.class.php create mode 100644 libraries/di/ServiceItem.class.php create mode 100644 libraries/di/ValueItem.class.php diff --git a/libraries/database_interface.inc.php b/libraries/database_interface.inc.php index bb85bcd6d8..52968bb093 100644 --- a/libraries/database_interface.inc.php +++ b/libraries/database_interface.inc.php @@ -10,7 +10,8 @@ if (! defined('PHPMYADMIN')) { exit; } -require_once './libraries/DatabaseInterface.class.php'; +require_once 'libraries/di/Container.class.php'; +require_once 'libraries/DatabaseInterface.class.php'; if (defined('TESTSUITE')) { /** @@ -81,4 +82,7 @@ if (defined('TESTSUITE')) { } } $GLOBALS['dbi'] = new PMA_DatabaseInterface($extension); -?> + +$container = \PMA\DI\Container::getDefaultContainer(); +$container->set('PMA_DatabaseInterface', $GLOBALS['dbi']); +$container->alias('dbi', 'PMA_DatabaseInterface'); diff --git a/libraries/di/AliasItem.class.php b/libraries/di/AliasItem.class.php new file mode 100644 index 0000000000..3c09922026 --- /dev/null +++ b/libraries/di/AliasItem.class.php @@ -0,0 +1,37 @@ +container = $container; + $this->target = $target; + } + + /** + * Get the target item + * + * @param array $params + * @return mixed + */ + public function get($params = array()) + { + return $this->container->get($this->target, $params); + } +} \ No newline at end of file diff --git a/libraries/di/Container.class.php b/libraries/di/Container.class.php new file mode 100644 index 0000000000..02cf0f2813 --- /dev/null +++ b/libraries/di/Container.class.php @@ -0,0 +1,142 @@ +content = $base->content; + } else { + $this->alias('container', 'Container'); + } + $this->set('Container', $this); + } + + /** + * Get an object with given name and parameters + * + * @param string $name + * @param array $params + * @return mixed + */ + public function get($name, $params = array()) + { + if (isset($this->content[$name])) { + return $this->content[$name]->get($params); + } + return null; + } + + /** + * Remove an object from container + * + * @param string $name + */ + public function remove($name) + { + unset($this->content[$name]); + } + + /** + * Rename an object in container + * + * @param string $name + * @param string $newName + */ + public function rename($name, $newName) + { + $this->content[$newName] = $this->content[$name]; + $this->remove($name); + } + + /** + * Set values in the container + * + * @param string|array $name + * @param mixed $value + */ + public function set($name, $value = null) + { + if (is_array($name)) { + foreach ($name as $key => $val) { + $this->set($key, $val); + } + return; + } + $this->content[$name] = new ValueItem($value); + } + + /** + * Register a service in the container + * + * @param string $name + * @param mixed $service + */ + public function service($name, $service = null) + { + if (!isset($service)) { + $service = $name; + } + $this->content[$name] = new ServiceItem($this, $service); + } + + /** + * Register a factory in the container + * + * @param string $name + * @param mixed $factory + */ + public function factory($name, $factory = null) + { + if (!isset($factory)) { + $factory = $name; + } + $this->content[$name] = new FactoryItem($this, $factory); + } + + /** + * Register an alias in the container + * + * @param string $name + * @param string $target + */ + public function alias($name, $target) + { + // The target may be not defined yet + $this->content[$name] = new AliasItem($this, $target); + } + + /** + * Get the global default container + */ + public static function getDefaultContainer() + { + if (!isset(static::$defaultContainer)) { + static::$defaultContainer = new Container(); + } + return static::$defaultContainer; + } +} \ No newline at end of file diff --git a/libraries/di/FactoryItem.class.php b/libraries/di/FactoryItem.class.php new file mode 100644 index 0000000000..fe95139410 --- /dev/null +++ b/libraries/di/FactoryItem.class.php @@ -0,0 +1,30 @@ +invoke($params); + } +} \ No newline at end of file diff --git a/libraries/di/Item.int.php b/libraries/di/Item.int.php new file mode 100644 index 0000000000..3283e9093d --- /dev/null +++ b/libraries/di/Item.int.php @@ -0,0 +1,14 @@ +container = $container; + $this->reflector = self::resolveReflector($definition); + } + + /** + * Invoke the reflector with given parameters + * + * @param array $params + * @return mixed + */ + protected function invoke($params = array()) + { + $args = array(); + $reflector = $this->reflector; + if ($reflector instanceof \ReflectionClass) { + $constructor = $reflector->getConstructor(); + if (isset($constructor)) { + $args = $this->resolveArgs( + $constructor->getParameters(), + $params + ); + } + return $reflector->newInstanceArgs($args); + } + /** @var \ReflectionFunctionAbstract $reflector */ + $args = $this->resolveArgs( + $reflector->getParameters(), + $params + ); + if ($reflector instanceof \ReflectionMethod) { + /** @var \ReflectionMethod $reflector */ + return $reflector->invokeArgs(null, $args); + } + /** @var \ReflectionFunction $reflector */ + return $reflector->invokeArgs($args); + } + + /** + * Getting required arguments with given parameters + * + * @param \ReflectionParameter[] $required + * @param array $params + * @return array + */ + private function resolveArgs($required, $params = array()) + { + $args = array(); + foreach ($required as $param) { + $name = $param->getName(); + $type = $param->getClass(); + if (isset($type)) { + $type = $type->getName(); + } + if (isset($params[$name])) { + $args[] = $params[$name]; + } elseif (is_string($type) && isset($params[$type])) { + $args[] = $params[$type]; + } else { + $content = $this->container->get($name); + if (isset($content)) { + $args[] = $content; + } elseif (is_string($type)) { + $args[] = $this->container->get($type); + } else { + $args[] = null; + } + } + } + return $args; + } + + /** + * Resolve the reflection + * + * @param mixed $definition + * @return \Reflector + */ + private static function resolveReflector($definition) + { + if (function_exists($definition)) { + return new \ReflectionFunction($definition); + } + if (is_string($definition)) { + $definition = explode('::', $definition); + } + if (!isset($definition[1])) { + return new \ReflectionClass($definition[0]); + } + return new \ReflectionMethod($definition[0], $definition[1]); + } +} \ No newline at end of file diff --git a/libraries/di/ServiceItem.class.php b/libraries/di/ServiceItem.class.php new file mode 100644 index 0000000000..38fc177b5f --- /dev/null +++ b/libraries/di/ServiceItem.class.php @@ -0,0 +1,36 @@ +instance)) { + $this->instance = $this->invoke(); + } + return $this->instance; + } +} \ No newline at end of file diff --git a/libraries/di/ValueItem.class.php b/libraries/di/ValueItem.class.php new file mode 100644 index 0000000000..7dd352efe2 --- /dev/null +++ b/libraries/di/ValueItem.class.php @@ -0,0 +1,32 @@ +value = $value; + } + + /** + * Get the value + * + * @param array $params + * @return mixed + */ + public function get($params = array()) + { + return $this->value; + } +} \ No newline at end of file diff --git a/libraries/tbl_columns_definition_form.inc.php b/libraries/tbl_columns_definition_form.inc.php index 933536901a..ba01ef4352 100644 --- a/libraries/tbl_columns_definition_form.inc.php +++ b/libraries/tbl_columns_definition_form.inc.php @@ -13,8 +13,9 @@ if (! defined('PHPMYADMIN')) { /** * Check parameters */ -require_once './libraries/Util.class.php'; -require_once './libraries/Template.class.php'; +require_once 'libraries/di/Container.class.php'; +require_once 'libraries/Util.class.php'; +require_once 'libraries/Template.class.php'; PMA_Util::checkParameters(array('server', 'db', 'table', 'action', 'num_fields')); @@ -49,6 +50,7 @@ $length_values_input_size = 8; $content_cells = array(); +/** @var string $db */ $form_params = array( 'db' => $db ); @@ -90,12 +92,13 @@ $is_backup = ($action != 'tbl_create.php' && $action != 'tbl_addfield.php'); require_once './libraries/transformations.lib.php'; $cfgRelation = PMA_getRelationsParam(); - $comments_map = PMA_getComments($db, $table); $move_columns = array(); if (isset($fields_meta)) { - $move_columns = $GLOBALS['dbi']->getTable($db, $table)->getColumnsMeta(); + /** @var PMA_DatabaseInterface $dbi */ + $dbi = \PMA\DI\Container::getDefaultContainer()->get('dbi'); + $move_columns = $dbi->getTable($db, $table)->getColumnsMeta(); } $available_mime = array(); @@ -422,4 +425,3 @@ $scripts = $header->getScripts(); $scripts->addFile('jquery/jquery.uitablefilter.js'); $scripts->addFile('indexes.js'); $response->addHTML($html); -?> diff --git a/tbl_chart.php b/tbl_chart.php index ee6354cfe6..3856c5bf7d 100644 --- a/tbl_chart.php +++ b/tbl_chart.php @@ -6,9 +6,16 @@ * @package PhpMyAdmin */ +namespace PMA; + +require_once 'libraries/di/Container.class.php'; require_once 'libraries/controllers/table/TableChartController.class.php'; -use PMA\Controllers\Table\TableChartController; +$container = DI\Container::getDefaultContainer(); -$controller = new TableChartController(); +$container->factory('PMA\Controllers\Table\TableChartController'); +$container->alias('TableChartController', 'PMA\Controllers\Table\TableChartController'); + +/** @var Controllers\Table\TableChartController $controller */ +$controller = $container->get('TableChartController'); $controller->indexAction(); From c692ddbb666863c6b646fb80469776d30b9d8b7e Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 30 Jun 2015 10:26:12 +0800 Subject: [PATCH 03/16] Use DI in controllers and simplify directory structure Signed-off-by: Jason --- libraries/controllers/Controller.class.php | 20 ++++++++++++++----- .../TableChartController.class.php | 5 +++-- .../controllers/TableController.class.php | 7 +++++-- .../TableGisVisualizationController.class.php | 0 .../TableIndexesController.class.php | 0 .../TableRelationController.class.php | 0 tbl_chart.php | 2 +- 7 files changed, 24 insertions(+), 10 deletions(-) rename libraries/controllers/{table => }/TableChartController.class.php (98%) rename libraries/controllers/{table => }/TableGisVisualizationController.class.php (100%) rename libraries/controllers/{table => }/TableIndexesController.class.php (100%) rename libraries/controllers/{table => }/TableRelationController.class.php (100%) diff --git a/libraries/controllers/Controller.class.php b/libraries/controllers/Controller.class.php index ac9ca469b1..0e382b61b9 100644 --- a/libraries/controllers/Controller.class.php +++ b/libraries/controllers/Controller.class.php @@ -8,6 +8,7 @@ namespace PMA\Controllers; +use PMA\DI\Container; use PMA_DatabaseInterface; use PMA_Response; @@ -16,8 +17,8 @@ if (!defined('PHPMYADMIN')) { } require_once 'libraries/Response.class.php'; +require_once 'libraries/di/Container.class.php'; require_once 'libraries/database_interface.inc.php'; -require_once 'libraries/controllers/Controller.class.php'; /** * Base class for all of controller @@ -28,18 +29,27 @@ abstract class Controller { /** - * @var PMA_Response $response + * @var PMA_Response */ protected $response; /** - * @var $dbi PMA_DatabaseInterface + * @var PMA_DatabaseInterface */ protected $dbi; - function __construct() + /** + * @var Container + */ + protected $container; + + function __construct(Container $container = null) { - $this->dbi = $GLOBALS['dbi']; + if (!isset($container)) { + $container = Container::getDefaultContainer(); + } + $this->container = $container; + $this->dbi = $container->get('dbi'); $this->response = PMA_Response::getInstance(); } } diff --git a/libraries/controllers/table/TableChartController.class.php b/libraries/controllers/TableChartController.class.php similarity index 98% rename from libraries/controllers/table/TableChartController.class.php rename to libraries/controllers/TableChartController.class.php index d84591425a..920648ff7c 100644 --- a/libraries/controllers/table/TableChartController.class.php +++ b/libraries/controllers/TableChartController.class.php @@ -9,6 +9,7 @@ namespace PMA\Controllers\Table; +use PMA\DI\Container; use PMA_Util; use PMA_Message; use PMA\Template; @@ -53,9 +54,9 @@ class TableChartController extends TableController */ protected $cfg; - function __construct() + function __construct(Container $container = null) { - parent::__construct(); + parent::__construct($container); $this->sql_query = &$GLOBALS['sql_query']; $this->url_query = &$GLOBALS['url_query']; diff --git a/libraries/controllers/TableController.class.php b/libraries/controllers/TableController.class.php index 3c4f05ff6e..acd7d3bae6 100644 --- a/libraries/controllers/TableController.class.php +++ b/libraries/controllers/TableController.class.php @@ -8,10 +8,13 @@ namespace PMA\Controllers; +use PMA\DI\Container; + if (!defined('PHPMYADMIN')) { exit; } +require_once 'libraries/di/Container.class.php'; require_once 'libraries/controllers/Controller.class.php'; /** @@ -21,8 +24,8 @@ require_once 'libraries/controllers/Controller.class.php'; */ abstract class TableController extends Controller { - function __construct() + function __construct(Container $container = null) { - parent::__construct(); + parent::__construct($container); } } \ No newline at end of file diff --git a/libraries/controllers/table/TableGisVisualizationController.class.php b/libraries/controllers/TableGisVisualizationController.class.php similarity index 100% rename from libraries/controllers/table/TableGisVisualizationController.class.php rename to libraries/controllers/TableGisVisualizationController.class.php diff --git a/libraries/controllers/table/TableIndexesController.class.php b/libraries/controllers/TableIndexesController.class.php similarity index 100% rename from libraries/controllers/table/TableIndexesController.class.php rename to libraries/controllers/TableIndexesController.class.php diff --git a/libraries/controllers/table/TableRelationController.class.php b/libraries/controllers/TableRelationController.class.php similarity index 100% rename from libraries/controllers/table/TableRelationController.class.php rename to libraries/controllers/TableRelationController.class.php diff --git a/tbl_chart.php b/tbl_chart.php index 3856c5bf7d..576a4ba7b4 100644 --- a/tbl_chart.php +++ b/tbl_chart.php @@ -9,7 +9,7 @@ namespace PMA; require_once 'libraries/di/Container.class.php'; -require_once 'libraries/controllers/table/TableChartController.class.php'; +require_once 'libraries/controllers/TableChartController.class.php'; $container = DI\Container::getDefaultContainer(); From d014dbcc293118e2dd43ba2d36465b745537d5f8 Mon Sep 17 00:00:00 2001 From: Deven Bansod Date: Tue, 30 Jun 2015 23:23:27 +0530 Subject: [PATCH 04/16] Trial Approach to solve Privileges bug for RFE#657 Signed-off-by: Deven Bansod --- db_operations.php | 1 + db_routines.php | 1 + doc/faq.rst | 7 + libraries/check_user_privileges.lib.php | 209 ++++++++++++++++++ libraries/dbi/DBIDummy.class.php | 20 ++ libraries/operations.lib.php | 104 +++++++-- libraries/rte/rte_routines.lib.php | 17 +- libraries/structure.lib.php | 1 + libraries/tbl_columns_definition_form.inc.php | 3 +- tbl_operations.php | 1 + tbl_structure.php | 1 + .../column_adjust_privileges.phtml | 24 +- .../column_attributes.phtml | 5 +- 13 files changed, 367 insertions(+), 27 deletions(-) diff --git a/db_operations.php b/db_operations.php index 7099be344e..12b2e1d5d3 100644 --- a/db_operations.php +++ b/db_operations.php @@ -21,6 +21,7 @@ require_once 'libraries/mysql_charsets.inc.php'; /** * functions implementation for this script */ +require_once 'libraries/check_user_privileges.lib.php'; require_once 'libraries/operations.lib.php'; // add a javascript file for jQuery functions to handle Ajax actions diff --git a/db_routines.php b/db_routines.php index c273b7b291..be7791c649 100644 --- a/db_routines.php +++ b/db_routines.php @@ -16,6 +16,7 @@ require_once 'libraries/mysql_charsets.inc.php'; /** * Include all other files */ +require_once 'libraries/check_user_privileges.lib.php'; require_once 'libraries/rte/rte_routines.lib.php'; /** diff --git a/doc/faq.rst b/doc/faq.rst index 48649158d9..5909f6807f 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -2065,6 +2065,13 @@ Notes: *column-related privileges* for the columns inside the table are also adjusted to the table's new name. +* While adjusting privileges, the user performing the operation **must** have the following + privileges: + + * SELECT, INSERT, UPDATE, DELETE privileges on following tables: + `mysql`.`db`, `mysql`.`columns_priv`, `mysql`.`tables_priv`, `mysql`.`procs_priv` + * FLUSH privilege (GLOBAL) + Thus, if you want to replicate the database/table/column/procedure as it is while renaming/copying/moving these objects, make sure you have checked this option. diff --git a/libraries/check_user_privileges.lib.php b/libraries/check_user_privileges.lib.php index aa118617e2..d03bb34c31 100644 --- a/libraries/check_user_privileges.lib.php +++ b/libraries/check_user_privileges.lib.php @@ -14,6 +14,208 @@ if (! defined('PHPMYADMIN')) { */ $GLOBALS['is_superuser'] = $GLOBALS['dbi']->isSuperuser(); +/** + * Check if user has required privileges for + * performing 'FLUSH PRIVILEGES' operation + * + * @return void + */ +function PMA_checkRequiredPrivilegesForFlushing() +{ + + $res = $GLOBALS['dbi']->tryQuery( + 'FLUSH PRIVILEGES' + ); + + // Save the value + $GLOBALS['flush_priv'] = $res; +} + +/** + * Check if user has required privileges for + * performing 'Adjust Privileges' operations + * + * @return void + */ +function PMA_checkRequiredPrivilgesForAdjust() +{ + $privs_available = true; + // FOR DB PRIVS + $select_privs_available = $GLOBALS['dbi']->tryQuery( + 'SELECT * FROM `mysql`.`db` LIMIT 1' + ); + + $privs_available = $select_privs_available && $privs_available; + + if ($privs_available) { + $delete_privs_available = $GLOBALS['dbi']->tryQuery( + 'DELETE FROM `mysql`.`db` WHERE `host` = "" AND ' + . '`Db` = "" AND `User` = "" LIMIT 1;' + ); + $privs_available = $delete_privs_available && $privs_available; + } + + if ($privs_available) { + $insert_privs_available = $GLOBALS['dbi']->tryQuery( + 'INSERT INTO `mysql`.`db`(`host`, `Db`, `User`) VALUES("pma_test_host", ' + . '"mysql", "pma_test_user");' + ); + // If successful test insert, delete the test row + if ($insert_privs_available) { + $GLOBALS['dbi']->tryQuery( + 'DELETE FROM `mysql`.`db` WHERE host = "pma_test_host" AND ' + . 'Db = "mysql" AND User = "pma_test_user" LIMIT 1;' + ); + } + $privs_available = $insert_privs_available && $privs_available; + } + + if ($privs_available) { + $update_privs_available = $GLOBALS['dbi']->tryQuery( + 'UPDATE `mysql`.`db` SET `host` = "" WHERE `host` = "" AND ' + . '`Db` = "" AND `User` = "" LIMIT 1;' + ); + $privs_available = $update_privs_available && $privs_available; + } + // save the value + $GLOBALS['db_priv'] = $privs_available; + // reset the value + $privs_available = true; + + // FOR COLUMNS_PRIV + $select_privs_available = $GLOBALS['dbi']->tryQuery( + 'SELECT * FROM `mysql`.`columns_priv` LIMIT 1' + ); + + $privs_available = $select_privs_available && $privs_available; + + if ($privs_available) { + $delete_privs_available = $GLOBALS['dbi']->tryQuery( + 'DELETE FROM `mysql`.`columns_priv` WHERE `host` = "" AND ' + . '`Db` = "" AND `User` = "" LIMIT 1;' + ); + $privs_available = $delete_privs_available && $privs_available; + } + + if ($privs_available) { + $insert_privs_available = $GLOBALS['dbi']->tryQuery( + 'INSERT INTO `mysql`.`columns_priv`(`host`, `Db`, `User`, `Table_name`,' + . ' `Column_name`) VALUES("pma_test_host", ' + . '"mysql", "pma_test_user", "", "")' + ); + // If successful test insert, delete the test row + if ($insert_privs_available) { + $GLOBALS['dbi']->tryQuery( + 'DELETE FROM `mysql`.`columns_priv` WHERE host = "pma_test_host" AND ' + . 'Db = "mysql" AND User = "pma_test_user" AND Table_name = ""' + . ' AND Column_name = "" LIMIT 1;' + ); + } + $privs_available = $insert_privs_available && $privs_available; + } + + if ($privs_available) { + $update_privs_available = $GLOBALS['dbi']->tryQuery( + 'UPDATE `mysql`.`columns_priv` SET `host` = "" WHERE `host` = "" AND ' + . '`Db` = "" AND `User` = "" AND Column_name = "" AND Table_name = "" LIMIT 1;' + ); + $privs_available = $update_privs_available && $privs_available; + + } + // Save the value + $GLOBALS['col_priv'] = $privs_available; + // Reset the value + $privs_available = true; + + // FOR TABLES_PRIV + $select_privs_available = $GLOBALS['dbi']->tryQuery( + 'SELECT * FROM `mysql`.`tables_priv` LIMIT 1' + ); + + $privs_available = $select_privs_available && $privs_available; + + if ($privs_available) { + $delete_privs_available = $GLOBALS['dbi']->tryQuery( + 'DELETE FROM `mysql`.`tables_priv` WHERE `host` = "" AND ' + . '`Db` = "" AND `User` = "" AND Table_name = "" LIMIT 1;' + ); + $privs_available = $delete_privs_available && $privs_available; + } + + if ($privs_available) { + $insert_privs_available = $GLOBALS['dbi']->tryQuery( + 'INSERT INTO `mysql`.`tables_priv`(`host`, `Db`, `User`, `Table_name`' + . ') VALUES("pma_test_host", ' + . '"mysql", "pma_test_user", "")' + ); + // If successful test insert, delete the test row + if ($insert_privs_available) { + $GLOBALS['dbi']->tryQuery( + 'DELETE FROM `mysql`.`tables_priv` WHERE host = "pma_test_host" AND ' + . 'Db = "mysql" AND User = "pma_test_user" AND Table_name = "" LIMIT 1;' + ); + } + $privs_available = $insert_privs_available && $privs_available; + } + + if ($privs_available) { + $update_privs_available = $GLOBALS['dbi']->tryQuery( + 'UPDATE `mysql`.`tables_priv` SET `host` = "" WHERE `host` = "" AND ' + . '`Db` = "" AND `User` = "" AND Table_name = "" LIMIT 1;' + ); + $privs_available = $update_privs_available && $privs_available; + + } + // Save the value + $GLOBALS['table_priv'] = $privs_available; + // Reset the value + $privs_available = true; + + // FOR PROCS_PRIV + $select_privs_available = $GLOBALS['dbi']->tryQuery( + 'SELECT * FROM `mysql`.`procs_priv` LIMIT 1' + ); + + $privs_available = $select_privs_available && $privs_available; + + if ($privs_available) { + $delete_privs_available = $GLOBALS['dbi']->tryQuery( + 'DELETE FROM `mysql`.`procs_priv` WHERE `host` = "" AND ' + . '`Db` = "" AND `User` = "" AND `Routine_name` = ""' + . ' AND `Routine_type` = "" LIMIT 1;' + ); + $privs_available = $delete_privs_available && $privs_available; + } + + if ($privs_available) { + $insert_privs_available = $GLOBALS['dbi']->tryQuery( + 'INSERT INTO `mysql`.`procs_priv`(`host`, `Db`, `User`, `Routine_name`,' + . ' `Routine_type`) VALUES("pma_test_host", ' + . '"mysql", "pma_test_user", "", "PROCEDURE")' + ); + // If successful test insert, delete the test row + if ($insert_privs_available) { + $GLOBALS['dbi']->tryQuery( + 'DELETE FROM `mysql`.`procs_priv` WHERE `host` = "pma_test_host" AND ' + . '`Db` = "mysql" AND `User` = "pma_test_user" AND `Routine_name` = ""' + . ' AND `Routine_type` = "PROCEDURE" LIMIT 1;' + ); + } + $privs_available = $insert_privs_available && $privs_available; + } + + if ($privs_available) { + $update_privs_available = $GLOBALS['dbi']->tryQuery( + 'UPDATE `mysql`.`procs_priv` SET `host` = "" WHERE `host` = "" AND ' + . '`Db` = "" AND `User` = "" AND `Routine_name` = "" LIMIT 1;' + ); + $privs_available = $update_privs_available && $privs_available; + } + // Save the value + $GLOBALS['proc_priv'] = $privs_available; + +} + /** * sets privilege information extracted from SHOW GRANTS result * @@ -185,6 +387,13 @@ if (!PMA_DRIZZLE) { } else { PMA_analyseShowGrant(); } + + // Check if privileges to 'mysql'.col_privs, 'mysql'.db, + // 'mysql'.table_privs, 'mysql'.proc_privs and privileges for + // flushing the privileges are available + PMA_checkRequiredPrivilegesForFlushing(); + PMA_checkRequiredPrivilgesForAdjust(); + } else { // todo: for simple_user_policy only database with user's login can be created // (unless logged in as root) diff --git a/libraries/dbi/DBIDummy.class.php b/libraries/dbi/DBIDummy.class.php index 10323afe6d..7ac4c44155 100644 --- a/libraries/dbi/DBIDummy.class.php +++ b/libraries/dbi/DBIDummy.class.php @@ -559,6 +559,26 @@ $GLOBALS['dummy_queries'] = array( array( 'query' => "SHOW EVENTS FROM `default`", 'result' => array() + ), + array( + 'query' => "FLUSH PRIVILEGES", + 'result' => array() + ), + array( + 'query' => "SELECT * FROM `mysql`.`db` LIMIT 1", + 'result' => array() + ), + array( + 'query' => "SELECT * FROM `mysql`.`columns_priv` LIMIT 1", + 'result' => array() + ), + array( + 'query' => "SELECT * FROM `mysql`.`tables_priv` LIMIT 1", + 'result' => array() + ), + array( + 'query' => "SELECT * FROM `mysql`.`procs_priv` LIMIT 1", + 'result' => array() ) ); /** diff --git a/libraries/operations.lib.php b/libraries/operations.lib.php index 9b938e3c48..306e770755 100644 --- a/libraries/operations.lib.php +++ b/libraries/operations.lib.php @@ -77,11 +77,26 @@ function PMA_getHtmlForRenameDatabase($db) $html_output .= ''; - $html_output .= ''; + + if (isset($GLOBALS['db_priv']) && $GLOBALS['db_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + $html_output .= ''; + } else { + $html_output .= ''; + } + $html_output .= '
'; + . __('Adjust Privileges') . PMA_Util::showDocu('faq', 'faq6-39') + . '
'; + $html_output .= '' . '' . '
' @@ -205,11 +220,25 @@ function PMA_getHtmlForCopyDatabase($db) $html_output .= '
'; $html_output .= '
'; - $html_output .= ''; + + if (isset($GLOBALS['db_priv']) && $GLOBALS['db_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + $html_output .= ''; + } else { + $html_output .= ''; + } $html_output .= '
'; + $html_output .= '' . '
' - . '' - . '
'; + + if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + $html_output .= ''; + } else { + $html_output .= ''; + } + + $html_output .= '
' . '
'; @@ -868,10 +911,23 @@ function PMA_getHtmlForRenameTable() . 'value="' . htmlspecialchars($GLOBALS['table']) . '" required="required" />' . '' - . '' - . '' - . '
'; - if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] - && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] - ) { - $html_output .= ''; - } else { - $html_output .= ''; + if (! PMA_DRIZZLE) { + if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] + && isset($GLOBALS['col_priv']) && $GLOBALS['col_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + $html_output .= ''; + } else { + $html_output .= ''; + } + $html_output .= '
'; } - $html_output .= '
' - . ''; - - $html_output .= '
' + $html_output .= '
' . '' . '
' . '' @@ -913,25 +939,28 @@ function PMA_getHtmlForRenameTable() . '' . ''; - if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] - && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] - ) { - $html_output .= ''; - } else { - $html_output .= ''; + if (! PMA_DRIZZLE) { + if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] + && isset($GLOBALS['col_priv']) && $GLOBALS['col_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + $html_output .= ''; + } else { + $html_output .= ''; + } + $html_output .= ''; } - $html_output .= '' - . '' - . ''; + + $html_output .= ''; return $html_output; } @@ -1264,25 +1293,27 @@ function PMA_getHtmlForCopytable() $html_output .= '
'; - if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] - && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] - ) { - $html_output .= ''; - } else { - $html_output .= ''; + if (! PMA_DRIZZLE) { + if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] + && isset($GLOBALS['col_priv']) && $GLOBALS['col_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + $html_output .= ''; + } else { + $html_output .= ''; + } + $html_output .= '
'; } - $html_output .= '
'; - if (isset($_COOKIE['pma_switch_to_new']) && $_COOKIE['pma_switch_to_new'] == 'true' ) { @@ -1914,24 +1945,30 @@ function PMA_getQueryAndResultForPartition() */ function PMA_AdjustPrivileges_renameOrMoveTable($oldDb, $oldTable, $newDb, $newTable) { - $GLOBALS['dbi']->selectDb('mysql'); + if (! PMA_DRIZZLE) { + if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] + && isset($GLOBALS['col_priv']) && $GLOBALS['col_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + $GLOBALS['dbi']->selectDb('mysql'); - // For table specific privileges - $query_table_specific = 'UPDATE ' . PMA_Util::backquote('tables_priv') - . 'SET Db = "' . $newDb . '", Table_name = "' . $newTable - . '" where Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; - $GLOBALS['dbi']->query($query_table_specific); + // For table specific privileges + $query_table_specific = 'UPDATE ' . PMA_Util::backquote('tables_priv') + . 'SET Db = "' . $newDb . '", Table_name = "' . $newTable + . '" where Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; + $GLOBALS['dbi']->query($query_table_specific); - // For column specific privileges - $query_col_specific = 'UPDATE ' . PMA_Util::backquote('columns_priv') - . 'SET Db = "' . $newDb . '", Table_name = "' . $newTable - . '" where Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; - $GLOBALS['dbi']->query($query_col_specific); - - // Finally FLUSH the new privileges - $flush_query = "FLUSH PRIVILEGES;"; - $GLOBALS['dbi']->query($flush_query); + // For column specific privileges + $query_col_specific = 'UPDATE ' . PMA_Util::backquote('columns_priv') + . 'SET Db = "' . $newDb . '", Table_name = "' . $newTable + . '" where Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; + $GLOBALS['dbi']->query($query_col_specific); + // Finally FLUSH the new privileges + $flush_query = "FLUSH PRIVILEGES;"; + $GLOBALS['dbi']->query($flush_query); + } + } } /** @@ -1946,46 +1983,52 @@ function PMA_AdjustPrivileges_renameOrMoveTable($oldDb, $oldTable, $newDb, $newT */ function PMA_AdjustPrivileges_copyTable($oldDb, $oldTable, $newDb, $newTable) { - $GLOBALS['dbi']->selectDb('mysql'); + if (! PMA_DRIZZLE) { + if (isset($GLOBALS['table_priv']) && $GLOBALS['table_priv'] + && isset($GLOBALS['col_priv']) && $GLOBALS['col_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + $GLOBALS['dbi']->selectDb('mysql'); - // For Table Specific privileges - $query_table_specific_old = 'SELECT * FROM ' - . PMA_Util::backquote('tables_priv') . ' where ' - . 'Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; + // For Table Specific privileges + $query_table_specific_old = 'SELECT * FROM ' + . PMA_Util::backquote('tables_priv') . ' where ' + . 'Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; - $old_privs_table = $GLOBALS['dbi']->fetchResult($query_table_specific_old, 0); + $old_privs_table = $GLOBALS['dbi']->fetchResult($query_table_specific_old, 0); - foreach ($old_privs_table as $old_priv) { - $newDb_table_privs_query = 'INSERT INTO ' - . PMA_Util::backquote('tables_priv') . ' VALUES("' - . $old_priv[0] . '", "' . $newDb . '", "' . $old_priv[2] . '", "' - . $newTable . '", "' . $old_priv[4] . '", "' . $old_priv[5] . '", "' - . $old_priv[6] . '", "' . $old_priv[7] . '");'; + foreach ($old_privs_table as $old_priv) { + $newDb_table_privs_query = 'INSERT INTO ' + . PMA_Util::backquote('tables_priv') . ' VALUES("' + . $old_priv[0] . '", "' . $newDb . '", "' . $old_priv[2] . '", "' + . $newTable . '", "' . $old_priv[4] . '", "' . $old_priv[5] . '", "' + . $old_priv[6] . '", "' . $old_priv[7] . '");'; - $GLOBALS['dbi']->query($newDb_table_privs_query); + $GLOBALS['dbi']->query($newDb_table_privs_query); + } + + // For Column Specific privileges + $query_col_specific_old = 'SELECT * FROM ' + . PMA_Util::backquote('columns_priv') . ' WHERE ' + . 'Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; + + $old_privs_col = $GLOBALS['dbi']->fetchResult($query_col_specific_old, 0); + + foreach ($old_privs_col as $old_priv) { + $newDb_col_privs_query = 'INSERT INTO ' + . PMA_Util::backquote('columns_priv') . ' VALUES("' + . $old_priv[0] . '", "' . $newDb . '", "' . $old_priv[2] . '", "' + . $newTable . '", "' . $old_priv[4] . '", "' . $old_priv[5] . '", "' + . $old_priv[6] . '");'; + + $GLOBALS['dbi']->query($newDb_col_privs_query); + } + + // Finally FLUSH the new privileges + $flush_query = "FLUSH PRIVILEGES;"; + $GLOBALS['dbi']->query($flush_query); + } } - - // For Column Specific privileges - $query_col_specific_old = 'SELECT * FROM ' - . PMA_Util::backquote('columns_priv') . ' WHERE ' - . 'Db = "' . $oldDb . '" AND Table_name = "' . $oldTable . '";'; - - $old_privs_col = $GLOBALS['dbi']->fetchResult($query_col_specific_old, 0); - - foreach ($old_privs_col as $old_priv) { - $newDb_col_privs_query = 'INSERT INTO ' - . PMA_Util::backquote('columns_priv') . ' VALUES("' - . $old_priv[0] . '", "' . $newDb . '", "' . $old_priv[2] . '", "' - . $newTable . '", "' . $old_priv[4] . '", "' . $old_priv[5] . '", "' - . $old_priv[6] . '");'; - - $GLOBALS['dbi']->query($newDb_col_privs_query); - } - - // Finally FLUSH the new privileges - $flush_query = "FLUSH PRIVILEGES;"; - $GLOBALS['dbi']->query($flush_query); - } /** diff --git a/libraries/rte/rte_routines.lib.php b/libraries/rte/rte_routines.lib.php index 75714cf519..8f2db513ac 100644 --- a/libraries/rte/rte_routines.lib.php +++ b/libraries/rte/rte_routines.lib.php @@ -301,21 +301,28 @@ function PMA_RTN_handleEditor() $db, $_REQUEST['item_original_type'], $_REQUEST['item_original_name'] ); - // Backup the Old Privileges before dropping - // if $_REQUEST['item_adjust_privileges'] set - $privilegesBackup = array(); - if (isset($_REQUEST['item_adjust_privileges']) - && ! empty($_REQUEST['item_adjust_privileges']) - ) { - $privilegesBackupQuery = 'SELECT * FROM ' . PMA_Util::backquote('mysql') - . '.' . PMA_Util::backquote('procs_priv') - . ' where Routine_name = "' . $_REQUEST['item_original_name'] - . '" AND Routine_type = "' . $_REQUEST['item_original_type'] - . '";'; - $privilegesBackup = $GLOBALS['dbi']->fetchResult( - $privilegesBackupQuery, 0 - ); + if (! defined('PMA_DRIZZLE') || ! PMA_DRIZZLE) { + if (isset($GLOBALS['proc_priv']) && $GLOBALS['proc_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + // Backup the Old Privileges before dropping + // if $_REQUEST['item_adjust_privileges'] set + $privilegesBackup = array(); + if (isset($_REQUEST['item_adjust_privileges']) + && ! empty($_REQUEST['item_adjust_privileges']) + ) { + $privilegesBackupQuery = 'SELECT * FROM ' . PMA_Util::backquote('mysql') + . '.' . PMA_Util::backquote('procs_priv') + . ' where Routine_name = "' . $_REQUEST['item_original_name'] + . '" AND Routine_type = "' . $_REQUEST['item_original_type'] + . '";'; + + $privilegesBackup = $GLOBALS['dbi']->fetchResult( + $privilegesBackupQuery, 0 + ); + } + } } $drop_routine = "DROP {$_REQUEST['item_original_type']} " @@ -355,23 +362,30 @@ function PMA_RTN_handleEditor() // Default value $resultAdjust = false; - // Insert all the previous privileges - // but with the new name and the new type - foreach ($privilegesBackup as $priv) { - $adjustProcPrivilege = 'INSERT INTO ' - . PMA_Util::backquote('mysql') . '.' - . PMA_Util::backquote('procs_priv') - . ' VALUES("' . $priv[0] . '", "' - . $priv[1] . '", "' . $priv[2] . '", "' - . $_REQUEST['item_name'] . '", "' - . $_REQUEST['item_type'] . '", "' - . $priv[5] . '", "' - . $priv[6] . '", "' - . $priv[7] . '");'; - $resultAdjust = $GLOBALS['dbi']->query( - $adjustProcPrivilege - ); + if (! defined('PMA_DRIZZLE') || ! PMA_DRIZZLE) { + if (isset($GLOBALS['proc_priv']) && $GLOBALS['proc_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + // Insert all the previous privileges + // but with the new name and the new type + foreach ($privilegesBackup as $priv) { + $adjustProcPrivilege = 'INSERT INTO ' + . PMA_Util::backquote('mysql') . '.' + . PMA_Util::backquote('procs_priv') + . ' VALUES("' . $priv[0] . '", "' + . $priv[1] . '", "' . $priv[2] . '", "' + . $_REQUEST['item_name'] . '", "' + . $_REQUEST['item_type'] . '", "' + . $priv[5] . '", "' + . $priv[6] . '", "' + . $priv[7] . '");'; + $resultAdjust = $GLOBALS['dbi']->query( + $adjustProcPrivilege + ); + } + } } + if ($resultAdjust) { // Flush the Privileges $flushPrivQuery = 'FLUSH PRIVILEGES;'; @@ -1101,19 +1115,21 @@ function PMA_RTN_getEditorForm($mode, $operation, $routine) $retval .= " " . __('Adjust Privileges'); $retval .= PMA_Util::showDocu('faq', 'faq6-39'); $retval .= ""; - if (isset($GLOBALS['proc_priv']) && $GLOBALS['proc_priv'] - && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] - ) { - $retval .= " "; - } else { - $retval .= " "; + if (! defined('PMA_DRIZZLE') || ! PMA_DRIZZLE) { + if (isset($GLOBALS['proc_priv']) && $GLOBALS['proc_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { + $retval .= " "; + } else { + $retval .= " "; + } } $retval .= ""; } diff --git a/libraries/structure.lib.php b/libraries/structure.lib.php index 88bc5c62ba..1fa6a61eb5 100644 --- a/libraries/structure.lib.php +++ b/libraries/structure.lib.php @@ -2785,26 +2785,33 @@ function PMA_adjustColumnPrivileges($db, $table, $adjust_privileges) { $changed = false; - $GLOBALS['dbi']->selectDb('mysql'); + if (! defined('PMA_DRIZZLE') || ! PMA_DRIZZLE) { + if (isset($GLOBALS['col_priv']) && $GLOBALS['col_priv'] + && isset($GLOBALS['flush_priv']) && $GLOBALS['flush_priv'] + ) { - // For Column specific privileges - foreach ($adjust_privileges as $oldCol => $newCol) { - $query_adjust_col_privileges = 'UPDATE ' - . PMA_Util::backquote('columns_priv') . ' ' - . 'SET Column_name = "' . $newCol . '" ' - . 'WHERE Db = "' . $db . '" AND Table_name = "' . $table - . '" AND Column_name = "' . $oldCol . '";'; + $GLOBALS['dbi']->selectDb('mysql'); - $GLOBALS['dbi']->query($query_adjust_col_privileges); + // For Column specific privileges + foreach ($adjust_privileges as $oldCol => $newCol) { + $query_adjust_col_privileges = 'UPDATE ' + . PMA_Util::backquote('columns_priv') . ' ' + . 'SET Column_name = "' . $newCol . '" ' + . 'WHERE Db = "' . $db . '" AND Table_name = "' . $table + . '" AND Column_name = "' . $oldCol . '";'; - // i.e. if atleast one column privileges adjusted - $changed = true; - } + $GLOBALS['dbi']->query($query_adjust_col_privileges); - if ($changed) { - // Finally FLUSH the new privileges - $flushPrivQuery = "FLUSH PRIVILEGES;"; - $GLOBALS['dbi']->query($flushPrivQuery); + // i.e. if atleast one column privileges adjusted + $changed = true; + } + + if ($changed) { + // Finally FLUSH the new privileges + $flushPrivQuery = "FLUSH PRIVILEGES;"; + $GLOBALS['dbi']->query($flushPrivQuery); + } + } } return $changed; diff --git a/templates/columns_definitions/column_attributes.phtml b/templates/columns_definitions/column_attributes.phtml index a3df524384..eb4049c463 100644 --- a/templates/columns_definitions/column_attributes.phtml +++ b/templates/columns_definitions/column_attributes.phtml @@ -84,7 +84,7 @@ $ci_offset = -1; 'columnMeta' => isset($columnMeta) ? $columnMeta : null )); ?> - + Date: Wed, 1 Jul 2015 21:47:44 +0800 Subject: [PATCH 06/16] Refine tbl_columns_definition_form.inc.php Signed-off-by: Jason --- libraries/tbl_columns_definition_form.inc.php | 233 ++++++------------ libraries/util.lib.php | 26 ++ 2 files changed, 102 insertions(+), 157 deletions(-) create mode 100644 libraries/util.lib.php diff --git a/libraries/tbl_columns_definition_form.inc.php b/libraries/tbl_columns_definition_form.inc.php index ba01ef4352..83ddd88573 100644 --- a/libraries/tbl_columns_definition_form.inc.php +++ b/libraries/tbl_columns_definition_form.inc.php @@ -6,7 +6,7 @@ * * @package PhpMyAdmin */ -if (! defined('PHPMYADMIN')) { +if (!defined('PHPMYADMIN')) { exit; } @@ -16,6 +16,9 @@ if (! defined('PHPMYADMIN')) { require_once 'libraries/di/Container.class.php'; require_once 'libraries/Util.class.php'; require_once 'libraries/Template.class.php'; +require_once 'libraries/util.lib.php'; + +use PMA\Util; PMA_Util::checkParameters(array('server', 'db', 'table', 'action', 'num_fields')); @@ -23,13 +26,13 @@ PMA_Util::checkParameters(array('server', 'db', 'table', 'action', 'num_fields') * Initialize to avoid code execution path warnings */ -if (! isset($num_fields)) { +if (!isset($num_fields)) { $num_fields = 0; } -if (! isset($mime_map)) { +if (!isset($mime_map)) { $mime_map = null; } -if (! isset($columnMeta)) { +if (!isset($columnMeta)) { $columnMeta = array(); } @@ -57,15 +60,15 @@ $form_params = array( if ($action == 'tbl_create.php') { $form_params['reload'] = 1; -} elseif ($action == 'tbl_addfield.php') { - if (isset($_REQUEST['field_where'])) { - $form_params['field_where'] = $_REQUEST['field_where']; - } - if (isset($_REQUEST['field_where'])) { - $form_params['after_field'] = $_REQUEST['after_field']; - } - $form_params['table'] = $table; } else { + if ($action == 'tbl_addfield.php') { + $form_params = array_merge($form_params, array( + 'field_where' => Util\get($_REQUEST, 'field_where') + )); + if (isset($_REQUEST['field_where'])) { + $form_params['after_field'] = $_REQUEST['after_field']; + } + } $form_params['table'] = $table; } @@ -73,13 +76,10 @@ if (isset($num_fields)) { $form_params['orig_num_fields'] = $num_fields; } -if (isset($_REQUEST['field_where'])) { - $form_params['orig_field_where'] = $_REQUEST['field_where']; -} - -if (isset($_REQUEST['after_field'])) { - $form_params['orig_after_field'] = $_REQUEST['after_field']; -} +$form_params = array_merge($form_params, array( + 'orig_field_where' => Util\get($_REQUEST, 'field_where'), + 'orig_after_field' => Util\get($_REQUEST, 'after_field'), +)); if (isset($selected) && is_array($selected)) { foreach ($selected as $o_fld_nr => $o_fld_val) { @@ -137,52 +137,33 @@ for ($columnNumber = 0; $columnNumber < $num_fields; $columnNumber++) { $extracted_columnspec = array(); if (!empty($regenerate)) { - $columnMeta['Field'] = isset($_REQUEST['field_name'][$columnNumber]) - ? $_REQUEST['field_name'][$columnNumber] - : false; - $columnMeta['Type'] = isset($_REQUEST['field_type'][$columnNumber]) - ? $_REQUEST['field_type'][$columnNumber] - : false; - $columnMeta['Collation'] = isset($_REQUEST['field_collation'][$columnNumber]) - ? $_REQUEST['field_collation'][$columnNumber] - : ''; - $columnMeta['Null'] = isset($_REQUEST['field_null'][$columnNumber]) - ? $_REQUEST['field_null'][$columnNumber] - : ''; + + $columnMeta = array_merge($columnMeta, array( + 'Field' => Util\get($_REQUEST, "field_name.${columnNumber}", false), + 'Type' => Util\get($_REQUEST, "field_type.${columnNumber}", false), + 'Collation' => Util\get($_REQUEST, "field_collation.${columnNumber}", ''), + 'Null' => Util\get($_REQUEST, "field_null.${columnNumber}", ''), + 'DefaultType' => Util\get($_REQUEST, "field_default_type.${columnNumber}", 'NONE'), + 'DefaultValue' => Util\get($_REQUEST, "field_default_value.${columnNumber}", ''), + 'Extra' => Util\get($_REQUEST, "field_extra.${columnNumber}", false), + )); $columnMeta['Key'] = ''; - if (isset($_REQUEST['field_key'][$columnNumber])) { - $parts = explode('_', $_REQUEST['field_key'][$columnNumber], 2); - if (count($parts) == 2 && $parts[1] == $columnNumber) { - switch ($parts[0]) { - case 'primary': - $columnMeta['Key'] = 'PRI'; - break; - case 'index': - $columnMeta['Key'] = 'MUL'; - break; - case 'unique': - $columnMeta['Key'] = 'UNI'; - break; - case 'fulltext': - $columnMeta['Key'] = 'FULLTEXT'; - break; - case 'spatial': - $columnMeta['Key'] = 'SPATIAL'; - break; - } - } + $parts = explode('_', Util\get($_REQUEST, "field_key.${columnNumber}", ''), 2); + if (count($parts) == 2 && $parts[1] == $columnNumber) { + $columnMeta['Key'] = Util\get(array( + 'primary' => 'PRI', + 'index' => 'MUL', + 'unique' => 'UNI', + 'fulltext' => 'FULLTEXT', + 'spatial' => 'SPATIAL' + ), $parts[0], ''); } - // put None in the drop-down for Default, when someone adds a field - $columnMeta['DefaultType'] - = isset($_REQUEST['field_default_type'][$columnNumber]) - ? $_REQUEST['field_default_type'][$columnNumber] - : 'NONE'; - $columnMeta['DefaultValue'] - = isset($_REQUEST['field_default_value'][$columnNumber]) - ? $_REQUEST['field_default_value'][$columnNumber] - : ''; + $columnMeta['Comment'] = + isset($submit_fulltext[$columnNumber]) + && ($submit_fulltext[$columnNumber] == $columnNumber) + ? 'FULLTEXT' : false; switch ($columnMeta['DefaultType']) { case 'NONE': @@ -197,71 +178,42 @@ for ($columnNumber = 0; $columnNumber < $num_fields; $columnNumber++) { break; } - $columnMeta['Extra'] - = (isset($_REQUEST['field_extra'][$columnNumber]) - ? $_REQUEST['field_extra'][$columnNumber] - : false); - $columnMeta['Comment'] - = (isset($submit_fulltext[$columnNumber]) - && ($submit_fulltext[$columnNumber] == $columnNumber) - ? 'FULLTEXT' - : false); + $length = Util\get($_REQUEST, "field_length.${columnNumber}", $length); + $submit_attribute = Util\get($_REQUEST, "field_attribute.${columnNumber}", false); + $comments_map[$columnMeta['Field']] = Util\get($_REQUEST, "field_comments.${columnNumber}"); - $length - = (isset($_REQUEST['field_length'][$columnNumber]) - ? $_REQUEST['field_length'][$columnNumber] - : $length); + $mime_map[$columnMeta['Field']] = array_merge( + $mime_map[$columnMeta['Field']], + array( + 'mimetype' => Util\get($_REQUEST, "field_mimetype.${$columnNumber}"), + 'transformation' => Util\get($_REQUEST, "field_transformation.${$columnNumber}"), + 'transformation_options' => Util\get($_REQUEST, "field_transformation_options.${$columnNumber}") + ) + ); - $submit_attribute - = (isset($_REQUEST['field_attribute'][$columnNumber]) - ? $_REQUEST['field_attribute'][$columnNumber] - : false); - - if (isset($_REQUEST['field_comments'][$columnNumber])) { - $comments_map[$columnMeta['Field']] - = $_REQUEST['field_comments'][$columnNumber]; - } - - if (isset($_REQUEST['field_mimetype'][$columnNumber])) { - $mime_map[$columnMeta['Field']]['mimetype'] - = $_REQUEST['field_mimetype'][$columnNumber]; - } - - if (isset($_REQUEST['field_transformation'][$columnNumber])) { - $mime_map[$columnMeta['Field']]['transformation'] - = $_REQUEST['field_transformation'][$columnNumber]; - } - - if (isset($_REQUEST['field_transformation_options'][$columnNumber])) { - $mime_map[$columnMeta['Field']]['transformation_options'] - = $_REQUEST['field_transformation_options'][$columnNumber]; - } - - } - elseif (isset($fields_meta[$columnNumber])) - { + } elseif (isset($fields_meta[$columnNumber])) { $columnMeta = $fields_meta[$columnNumber]; switch ($columnMeta['Default']) { case null: if (is_null($columnMeta['Default'])) { // null if ($columnMeta['Null'] == 'YES') { - $columnMeta['DefaultType'] = 'NULL'; + $columnMeta['DefaultType'] = 'NULL'; $columnMeta['DefaultValue'] = ''; } else { - $columnMeta['DefaultType'] = 'NONE'; + $columnMeta['DefaultType'] = 'NONE'; $columnMeta['DefaultValue'] = ''; } } else { // empty - $columnMeta['DefaultType'] = 'USER_DEFINED'; + $columnMeta['DefaultType'] = 'USER_DEFINED'; $columnMeta['DefaultValue'] = $columnMeta['Default']; } break; case 'CURRENT_TIMESTAMP': - $columnMeta['DefaultType'] = 'CURRENT_TIMESTAMP'; + $columnMeta['DefaultType'] = 'CURRENT_TIMESTAMP'; $columnMeta['DefaultValue'] = ''; break; default: - $columnMeta['DefaultType'] = 'USER_DEFINED'; + $columnMeta['DefaultType'] = 'USER_DEFINED'; $columnMeta['DefaultValue'] = $columnMeta['Default']; break; } @@ -328,12 +280,14 @@ for ($columnNumber = 0; $columnNumber < $num_fields; $columnNumber++) { if (isset($columnMeta['Type'])) { // keep in uppercase because the new type will be in uppercase $form_params['field_type_orig[' . $columnNumber . ']'] - = /*overload*/mb_strtoupper($type); + = /*overload*/ + mb_strtoupper($type); if (isset($columnMeta['column_status']) && !$columnMeta['column_status']['isEditable'] ) { $form_params['field_type[' . $columnNumber . ']'] - = /*overload*/mb_strtoupper($type); + = /*overload*/ + mb_strtoupper($type); } } else { $form_params['field_type_orig[' . $columnNumber . ']'] = ''; @@ -343,50 +297,15 @@ for ($columnNumber = 0; $columnNumber < $num_fields; $columnNumber++) { $form_params['field_length_orig[' . $columnNumber . ']'] = $length; // old column default - $form_params['field_default_value_orig[' . $columnNumber . ']'] - = (isset($columnMeta['Default']) ? $columnMeta['Default'] : ''); - $form_params['field_default_type_orig[' . $columnNumber . ']'] - = (isset($columnMeta['DefaultType']) ? $columnMeta['DefaultType'] : ''); - - // old column collation - if (isset($columnMeta['Collation'])) { - $form_params['field_collation_orig[' . $columnNumber . ']'] - = $columnMeta['Collation']; - } else { - $form_params['field_collation_orig[' . $columnNumber . ']'] = ''; - } - - // old column attribute - if (isset($extracted_columnspec['attribute'])) { - $form_params['field_attribute_orig[' . $columnNumber . ']'] - = trim($extracted_columnspec['attribute']); - } else { - $form_params['field_attribute_orig[' . $columnNumber . ']'] = ''; - } - - // old column null - if (isset($columnMeta['Null'])) { - $form_params['field_null_orig[' . $columnNumber . ']'] - = $columnMeta['Null']; - } else { - $form_params['field_null_orig[' . $columnNumber . ']'] = ''; - } - - // old column extra (for auto_increment) - if (isset($columnMeta['Extra'])) { - $form_params['field_extra_orig[' . $columnNumber . ']'] - = $columnMeta['Extra']; - } else { - $form_params['field_extra_orig[' . $columnNumber . ']'] = ''; - } - - // old column comment - if (isset($columnMeta['Comment'])) { - $form_params['field_comments_orig[' . $columnNumber . ']'] - = $columnMeta['Comment']; - } else { - $form_params['field_comment_orig[' . $columnNumber . ']'] = ''; - } + $form_params = array_merge($form_params, array( + "field_default_value_orig[${columnNumber}]" => Util\get($columnMeta, 'Default', ''), + "field_default_type_orig[${columnNumber}]" => Util\get($columnMeta, 'DefaultType', ''), + "field_collation_orig[${columnNumber}]" => Util\get($columnMeta, 'Collation', ''), + "field_attribute_orig[${columnNumber}]" => trim(Util\get($extracted_columnspec, 'attribute', '')), + "field_null_orig[${columnNumber}]" => Util\get($columnMeta, 'Null', ''), + "field_extra_orig[${columnNumber}]" => Util\get($columnMeta, 'Extra', ''), + "field_comments_orig[${columnNumber}]" => Util\get($columnMeta, 'Comment', ''), + )); } $content_cells[$columnNumber] = array( @@ -420,8 +339,8 @@ $html = PMA\Template::get('columns_definitions/column_definitions_form') unset($form_params); $response = PMA_Response::getInstance(); -$header = $response->getHeader(); -$scripts = $header->getScripts(); -$scripts->addFile('jquery/jquery.uitablefilter.js'); -$scripts->addFile('indexes.js'); +$response->getHeader()->getScripts()->addFiles(array( + 'jquery/jquery.uitablefilter.js', + 'indexes.js' +)); $response->addHTML($html); diff --git a/libraries/util.lib.php b/libraries/util.lib.php new file mode 100644 index 0000000000..238f68213b --- /dev/null +++ b/libraries/util.lib.php @@ -0,0 +1,26 @@ + Date: Fri, 3 Jul 2015 06:30:45 -0400 Subject: [PATCH 07/16] Fix parameter type Signed-off-by: Marc Delisle --- libraries/server_privileges.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/server_privileges.lib.php b/libraries/server_privileges.lib.php index 822a09ea9c..e5004d10ff 100644 --- a/libraries/server_privileges.lib.php +++ b/libraries/server_privileges.lib.php @@ -1129,7 +1129,7 @@ function PMA_getHtmlForNotAttachedPrivilegesToTableSpecificColumn($row) * * @param string $db the database * @param string $table the table - * @param string $row first row from result or boolean false + * @param array $row first row from result or boolean false * * @return string $html_output */ From d1e2c58ee460437783604b72b535a778e18f341b Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 3 Jul 2015 23:04:19 +0800 Subject: [PATCH 08/16] Test & fix TableGisVisualizationController Also fix typos in controllers. Signed-off-by: Jason --- .../TableGisVisualizationController.class.php | 48 ++++++++++--------- libraries/di/Container.class.php | 5 ++ tbl_gis_visualization.php | 2 +- tbl_indexes.php | 2 +- tbl_relation.php | 2 +- 5 files changed, 33 insertions(+), 26 deletions(-) diff --git a/libraries/controllers/TableGisVisualizationController.class.php b/libraries/controllers/TableGisVisualizationController.class.php index 3912275019..7ee11dea98 100644 --- a/libraries/controllers/TableGisVisualizationController.class.php +++ b/libraries/controllers/TableGisVisualizationController.class.php @@ -16,6 +16,7 @@ use PMA_Message; use PMA_Util; require_once 'libraries/common.inc.php'; +require_once 'libraries/db_common.inc.php'; require_once 'libraries/controllers/TableController.class.php'; require_once 'libraries/gis/GIS_Visualization.class.php'; require_once 'libraries/gis/GIS_Factory.class.php'; @@ -35,7 +36,7 @@ class TableGisVisualizationController extends TableController { protected $sql_query; /** - * @var array $this->visualizationSettings + * @var array $visualizationSettings */ protected $visualizationSettings; @@ -45,35 +46,18 @@ class TableGisVisualizationController extends TableController { protected $visualization; public function __construct() { + parent::__construct(); + $this->sql_query = &$GLOBALS['sql_query']; $this->url_params = &$GLOBALS['url_params']; - // Runs common work - require_once 'libraries/db_common.inc.php'; + $this->url_params['goto'] = PMA_Util::getScriptNameForOption( $GLOBALS['cfg']['DefaultTabDatabase'], 'database' ); $this->url_params['back'] = 'sql.php'; $this->visualizationSettings = array(); - - // Convert geometric columns from bytes to text. - $pos = isset($_REQUEST['pos']) ? $_REQUEST['pos'] : $_SESSION['tmpval']['pos']; - if (isset($_REQUEST['session_max_rows'])) { - $rows = $_REQUEST['session_max_rows']; - } else { - if ($_SESSION['tmpval']['max_rows'] != 'all') { - $rows = $_SESSION['tmpval']['max_rows']; - } else { - $rows = $GLOBALS['cfg']['MaxRows']; - } - } - $this->visualization = PMA_GIS_Visualization::get( - $this->sql_query, - $this->visualizationSettings, - $rows, - $pos - ); } public function saveToFileAction() { @@ -85,7 +69,7 @@ class TableGisVisualizationController extends TableController { public function indexAction() { // Throw error if no sql query is set - if (! isset($sql_query) || $sql_query == '') { + if (! isset($this->sql_query) || $this->sql_query == '') { $this->response->isSuccess(false); $this->response->addHTML( PMA_Message::error(__('No SQL query was set to fetch data.')) @@ -94,7 +78,7 @@ class TableGisVisualizationController extends TableController { } // Execute the query and return the result - $result = $this->dbi->tryQuery($sql_query); + $result = $this->dbi->tryQuery($this->sql_query); // Get the meta data of results $meta = $this->dbi->getFieldsMeta($result); @@ -123,6 +107,24 @@ class TableGisVisualizationController extends TableController { $this->visualizationSettings['spatialColumn'] = $spatialCandidates[0]; } + // Convert geometric columns from bytes to text. + $pos = isset($_REQUEST['pos']) ? $_REQUEST['pos'] : $_SESSION['tmpval']['pos']; + if (isset($_REQUEST['session_max_rows'])) { + $rows = $_REQUEST['session_max_rows']; + } else { + if ($_SESSION['tmpval']['max_rows'] != 'all') { + $rows = $_SESSION['tmpval']['max_rows']; + } else { + $rows = $GLOBALS['cfg']['MaxRows']; + } + } + $this->visualization = PMA_GIS_Visualization::get( + $this->sql_query, + $this->visualizationSettings, + $rows, + $pos + ); + if (isset($_REQUEST['saveToFile'])) { $this->saveToFileAction(); return; diff --git a/libraries/di/Container.class.php b/libraries/di/Container.class.php index 02cf0f2813..a98811e787 100644 --- a/libraries/di/Container.class.php +++ b/libraries/di/Container.class.php @@ -47,6 +47,11 @@ class Container if (isset($this->content[$name])) { return $this->content[$name]->get($params); } + + if (isset($GLOBALS[$name])) { + return $GLOBALS[$name]; + } + return null; } diff --git a/tbl_gis_visualization.php b/tbl_gis_visualization.php index 8f2e633eca..545f96b712 100644 --- a/tbl_gis_visualization.php +++ b/tbl_gis_visualization.php @@ -8,7 +8,7 @@ use PMA\Controllers\Table\TableGisVisualizationController; -require_once 'libraries/controllers/table/TableGisVisualizationController.class.php'; +require_once 'libraries/controllers/TableGisVisualizationController.class.php'; $controller = new TableGisVisualizationController(); $controller->indexAction(); diff --git a/tbl_indexes.php b/tbl_indexes.php index e20d02847b..1111408024 100644 --- a/tbl_indexes.php +++ b/tbl_indexes.php @@ -6,7 +6,7 @@ * @package PhpMyAdmin */ -require_once 'libraries/controllers/table/TableIndexesController.class.php'; +require_once 'libraries/controllers/TableIndexesController.class.php'; use PMA\Controllers\Table\TableIndexesController; diff --git a/tbl_relation.php b/tbl_relation.php index 103ef61d0a..9fefb5391d 100644 --- a/tbl_relation.php +++ b/tbl_relation.php @@ -17,7 +17,7 @@ /** * Get the TableRelationController */ -require_once 'libraries/controllers/table/TableRelationController.class.php'; +require_once 'libraries/controllers/TableRelationController.class.php'; use PMA\Controllers\Table\TableRelationController; From fb71cfa18dae08b462ca2289bc0e004396c24951 Mon Sep 17 00:00:00 2001 From: dingo thirteen Date: Sat, 4 Jul 2015 11:08:08 +0200 Subject: [PATCH 09/16] Translated using Weblate (Dutch) Currently translated at 100.0% (3142 of 3142 strings) [CI skip] --- po/nl.po | 57 ++++++++++++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/po/nl.po b/po/nl.po index d1dd9dbba0..a9c43de90c 100644 --- a/po/nl.po +++ b/po/nl.po @@ -4,10 +4,10 @@ msgstr "" "Project-Id-Version: phpMyAdmin 4.5.0-dev\n" "Report-Msgid-Bugs-To: phpmyadmin-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2015-06-28 06:20-0400\n" -"PO-Revision-Date: 2015-06-23 16:27+0200\n" +"PO-Revision-Date: 2015-07-04 11:08+0200\n" "Last-Translator: dingo thirteen \n" -"Language-Team: Dutch \n" +"Language-Team: Dutch " +"\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -275,7 +275,6 @@ msgid "Data" msgstr "Data" #: db_export.php:54 -#, fuzzy #| msgid "Select All" msgid "Select all" msgstr "Alles selecteren" @@ -6145,16 +6144,14 @@ msgid "Customize appearance of the navigation panel." msgstr "Weergaveopties voor het navigatiepaneel." #: libraries/config/messages.inc.php:248 -#, fuzzy #| msgid "Navigation panel" msgid "Navigation tree" -msgstr "Navigatiepaneel" +msgstr "Navigatie boomstructuur" #: libraries/config/messages.inc.php:249 -#, fuzzy #| msgid "Customize navigation panel" msgid "Customize the navigation tree." -msgstr "Aanpassen navigatiepaneel" +msgstr "Aanpassen navigatie boomstructuur." #: libraries/config/messages.inc.php:250 libraries/select_server.lib.php:46 #: setup/frames/index.inc.php:144 @@ -6757,64 +6754,56 @@ msgid "Enable navigation tree expansion" msgstr "Uitklappen van de navigatiestructuur inschakelen" #: libraries/config/messages.inc.php:487 -#, fuzzy #| msgid "Show/Hide tables list" msgid "Show tables in tree" -msgstr "Toon/verberg lijst met tabellen" +msgstr "Toon tabellen in boomstructuur" #: libraries/config/messages.inc.php:489 -#, fuzzy #| msgid "" #| "Whether to offer the possibility of tree expansion in the navigation " #| "panel." msgid "Whether to show tables under database in the navigation tree" -msgstr "" -"Of uitklappen van de boomstructuur aangeboden mag worden in het " -"navigatiepaneel." +msgstr "Of tabellen getoond worden in de navigatie boomstructuur" #: libraries/config/messages.inc.php:490 -#, fuzzy #| msgid "Show versions" msgid "Show views in tree" -msgstr "Versies weergeven" +msgstr "Versies weergeven in boomstructuur" #: libraries/config/messages.inc.php:492 -#, fuzzy #| msgid "Show databases navigation as tree" msgid "Whether to show views under database in the navigation tree" -msgstr "Geef databases navigatiescherm weer als boomstructuur" +msgstr "Of views getoond worden onder database in de navigatie boomstructuur" #: libraries/config/messages.inc.php:493 -#, fuzzy #| msgid "Show function fields" msgid "Show functions in tree" -msgstr "Toon functievelden" +msgstr "Toon functies in boomstructuur" #: libraries/config/messages.inc.php:495 msgid "Whether to show functions under database in the navigation tree" -msgstr "" +msgstr "Of functies getoond worden onder database in de navigatie boomstructuur" #: libraries/config/messages.inc.php:496 -#, fuzzy #| msgid "Show processes" msgid "Show procedures in tree" -msgstr "Laat processen zien" +msgstr "Laat procedures zien een boomstructuur" #: libraries/config/messages.inc.php:498 msgid "Whether to show procedures under database in the navigation tree" msgstr "" +"Of procedures getoond worden onder database in de navigatie boomstructuur" #: libraries/config/messages.inc.php:499 -#, fuzzy #| msgid "Show versions" msgid "Show events in tree" -msgstr "Versies weergeven" +msgstr "Toon gebeurtenissen in een boomstructuur" #: libraries/config/messages.inc.php:501 -#, fuzzy #| msgid "Show databases navigation as tree" msgid "Whether to show events under database in the navigation tree" -msgstr "Geef databases navigatiescherm weer als boomstructuur" +msgstr "" +"Of gebeurtenissen getoond worden onder database in de navigatie boomstructuur" #: libraries/config/messages.inc.php:503 msgid "Maximum number of recently used tables; set 0 to disable." @@ -6843,6 +6832,8 @@ msgstr "Waar de tabelregellinks getoond worden" #: libraries/config/messages.inc.php:510 msgid "Whether to show row links even in the absence of a unique key." msgstr "" +"Of links naar rijen getoond worden zelfs bij afwezigheid van een uniek " +"sleutelveld." #: libraries/config/messages.inc.php:511 msgid "Show row links anyway" @@ -8259,16 +8250,14 @@ msgid "View output as text" msgstr "Bekijk output als tekst" #: libraries/display_export.lib.php:660 -#, fuzzy #| msgid "Export views as tables" msgid "Export databases as separate files" -msgstr "Views exporteren als tabellen" +msgstr "Exporteer databases as afzonderlijke bestanden" #: libraries/display_export.lib.php:662 -#, fuzzy #| msgid "Export table headers" msgid "Export tables as separate files" -msgstr "Exporteer tabel kopregels" +msgstr "Exporteer tabellen als afzonderlijke bestanden" #: libraries/display_export.lib.php:692 libraries/display_export.lib.php:814 msgid "Rename exported databases/tables/columns" @@ -9283,10 +9272,9 @@ msgid "An error has occurred while loading the navigation display" msgstr "Er is een fout opgetreden bij het laden van de navigatieweergave" #: libraries/navigation/Navigation.class.php:192 -#, fuzzy #| msgid "Group name:" msgid "Groups:" -msgstr "Groepsnaam:" +msgstr "Groepen:" #: libraries/navigation/Navigation.class.php:193 msgid "Events:" @@ -11165,10 +11153,9 @@ msgid "Managing Central list of columns" msgstr "Beheer van centrale lijst van kolommen" #: libraries/relation.lib.php:324 -#, fuzzy #| msgid "Remember table's sorting" msgid "Remembering Designer Settings" -msgstr "De tabelsortering onthouden" +msgstr "Onthoud Ontwerper Instellingen" #: libraries/relation.lib.php:332 msgid "Quick steps to setup advanced features:" From 4a05b4265edea43cf2bfc1b493f55307cd906267 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Sat, 4 Jul 2015 06:40:49 -0400 Subject: [PATCH 10/16] Fix code execution path Signed-off-by: Marc Delisle --- libraries/config/FormDisplay.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/config/FormDisplay.class.php b/libraries/config/FormDisplay.class.php index 1da1c46647..e337f54a4a 100644 --- a/libraries/config/FormDisplay.class.php +++ b/libraries/config/FormDisplay.class.php @@ -395,6 +395,7 @@ class FormDisplay $opts['errors'] = $this->_errors[$work_path]; } + $type = ''; switch ($form->getOptionType($field)) { case 'string': $type = 'text'; From ee650720cba47483ba502222dd442a683fca5d02 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Sat, 4 Jul 2015 07:24:39 -0400 Subject: [PATCH 11/16] bug #4974 Creating a database from console doesn't update navigation panel Signed-off-by: Marc Delisle --- ChangeLog | 1 + js/console.js | 1 + 2 files changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 000de97898..f4bbe63659 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,7 @@ phpMyAdmin - ChangeLog - bug #4972 Incorrect length computed for binary data - bug Remove character set from create_tables_drizzle.sql - bug #4973 Users overview needs clarification +- bug #4974 Creating a database from console doesn't update navigation panel 4.4.10.0 (2015-06-17) - bug #4950 Issues in database selection for replication diff --git a/js/console.js b/js/console.js index 3493f13d1d..f824b9ae52 100644 --- a/js/console.js +++ b/js/console.js @@ -235,6 +235,7 @@ var PMA_console = { .val(PMA_consoleMessages.appendQuery({sql_query: queryString}).message_id); PMA_console.$requestForm.trigger('submit'); PMA_consoleInput.clear(); + PMA_reloadNavigation(); }, ajaxCallback: function(data) { if(data && data.console_message_id) { From 6d4aac0853075e9c823bba39d142f928cbc3fa51 Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Sun, 5 Jul 2015 06:41:48 -0400 Subject: [PATCH 12/16] bug #4844 FAQ 1.17 needs an update Signed-off-by: Marc Delisle --- ChangeLog | 1 + doc/faq.rst | 24 ++++++++---------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index f4bbe63659..84ac987ec6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,7 @@ phpMyAdmin - ChangeLog - bug Remove character set from create_tables_drizzle.sql - bug #4973 Users overview needs clarification - bug #4974 Creating a database from console doesn't update navigation panel +- bug #4844 FAQ 1.17 needs an update 4.4.10.0 (2015-06-17) - bug #4950 Issues in database selection for replication diff --git a/doc/faq.rst b/doc/faq.rst index fe5cb6c004..8edbc3757a 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -186,24 +186,16 @@ hosting provider is unwilling to change the settings: .. _faq1_17: -1.17 Which MySQL versions does phpMyAdmin support? --------------------------------------------------- +1.17 Which Database versions does phpMyAdmin support? +----------------------------------------------------- -Since phpMyAdmin 3.0.x, only MySQL 5.0.1 and newer are supported. For -older MySQL versions, you need to use the latest 2.x branch. -phpMyAdmin can connect to your MySQL server using PHP's classic `MySQL -extension `_ as well as the `improved MySQL -extension (MySQLi) `_ that is available in PHP -5.0. The latter one should be used unless you have a good reason not -to do so. When compiling PHP, we strongly recommend that you manually -link the MySQL extension of your choice to a MySQL client library of -at least the same minor version since the one that is bundled with -some PHP distributions is rather old and might cause problems see -:ref:`faq1_17a`. `MariaDB `_ is also supported -(versions 5.1 and 5.2 were tested). +For `MySQL `_, versions 5.5 and newer are supported. +For older MySQL versions, our `Downloads `_ page offers older phpMyAdmin versions +(which may have become unsupported). -.. versionchanged:: 3.5 - Since phpMyAdmin 3.5 `Drizzle `_ is supported. +For `MariaDB `_, versions 5.5 and newer are supported. + +For `Drizzle `_, versions 7.1 and newer are supported. .. _faq1_17a: From ece5e60ab1052b765418f238e29c7344a09261eb Mon Sep 17 00:00:00 2001 From: Deven Bansod Date: Sun, 5 Jul 2015 19:59:31 +0530 Subject: [PATCH 13/16] Fixed some spelling mistakes Signed-off-by: Deven Bansod --- doc/faq.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/faq.rst b/doc/faq.rst index fe5cb6c004..fc36faca18 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -1886,7 +1886,7 @@ to display the plot. After the plot is generated, you can use the mousewheel to zoom in and out of the plot. In addition, panning feature is enabled to navigate through the plot. You can zoom-in to a -certail level of detail and use panning to locate your area of +certain level of detail and use panning to locate your area of interest. Clicking on a point opens a dialogue box, displaying field values of the data row represented by the point. You can edit the values if required and click on submit to issue an update query. Basic @@ -1988,7 +1988,7 @@ On startup of the wizard, user gets to select upto what normal form they want to normalize the table structure. Here is an example table which you can use to test all of the three First, Second and -Third Normal From. +Third Normal Form. .. code-block:: mysql From 2c6f5e7efbb9a64bee72b0f801a4e44efff4ba0b Mon Sep 17 00:00:00 2001 From: Marc Delisle Date: Sun, 5 Jul 2015 17:41:34 -0400 Subject: [PATCH 14/16] This variable is needed for multiple db dropping Signed-off-by: Marc Delisle --- libraries/server_databases.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/server_databases.lib.php b/libraries/server_databases.lib.php index 703bd9505a..1aec17c35f 100644 --- a/libraries/server_databases.lib.php +++ b/libraries/server_databases.lib.php @@ -466,7 +466,7 @@ function PMA_dropMultiDatabases() 'table' => $GLOBALS['table']); } //the following variables will be used on mult_submits.inc.php - global $selected, $mult_btn; + global $query_type, $selected, $mult_btn; include 'libraries/mult_submits.inc.php'; unset($action, $submit_mult, $err_url, $selected_db, $GLOBALS['db']); From ca61c3ace83942195b40a49b25c8dfa0f71adaf6 Mon Sep 17 00:00:00 2001 From: Atul Pratap Singh Date: Mon, 6 Jul 2015 12:41:16 +0530 Subject: [PATCH 15/16] Achieve constructor injection usign the introduced DIC Signed-off-by: Atul Pratap Singh --- libraries/controllers/Controller.class.php | 8 +-- .../TableChartController.class.php | 24 ++------ .../controllers/TableController.class.php | 19 +++++-- .../TableGisVisualizationController.class.php | 26 ++++----- .../TableIndexesController.class.php | 38 +------------ .../TableRelationController.class.php | 52 +++++------------ tbl_chart.php | 10 +++- tbl_gis_visualization.php | 22 +++++++- tbl_indexes.php | 36 +++++++++++- tbl_relation.php | 56 ++++++++++++++++++- 10 files changed, 164 insertions(+), 127 deletions(-) diff --git a/libraries/controllers/Controller.class.php b/libraries/controllers/Controller.class.php index 0e382b61b9..5d79cb663e 100644 --- a/libraries/controllers/Controller.class.php +++ b/libraries/controllers/Controller.class.php @@ -43,13 +43,11 @@ abstract class Controller */ protected $container; - function __construct(Container $container = null) + function __construct() { - if (!isset($container)) { - $container = Container::getDefaultContainer(); - } + $container = Container::getDefaultContainer(); $this->container = $container; - $this->dbi = $container->get('dbi'); + $this->dbi = $this->container->get('dbi'); $this->response = PMA_Response::getInstance(); } } diff --git a/libraries/controllers/TableChartController.class.php b/libraries/controllers/TableChartController.class.php index 920648ff7c..5ee3ab65ca 100644 --- a/libraries/controllers/TableChartController.class.php +++ b/libraries/controllers/TableChartController.class.php @@ -39,30 +39,18 @@ class TableChartController extends TableController */ protected $url_query; - /** - * @var string $db - */ - protected $db; - - /** - * @var string $table - */ - protected $table; - /** * @var array $cfg */ protected $cfg; - function __construct(Container $container = null) + function __construct($sql_query, $url_query, $cfg) { - parent::__construct($container); + parent::__construct(); - $this->sql_query = &$GLOBALS['sql_query']; - $this->url_query = &$GLOBALS['url_query']; - $this->table = &$GLOBALS['table']; - $this->db = &$GLOBALS['db']; - $this->cfg = &$GLOBALS['cfg']; + $this->sql_query = $sql_query; + $this->url_query = $url_query; + $this->cfg = $cfg; } /* @@ -232,4 +220,4 @@ class TableChartController extends TableController $this->response->addJSON('message', null); $this->response->addJSON('chartData', json_encode($sanitized_data)); } -} \ No newline at end of file +} diff --git a/libraries/controllers/TableController.class.php b/libraries/controllers/TableController.class.php index acd7d3bae6..ed3a032bcd 100644 --- a/libraries/controllers/TableController.class.php +++ b/libraries/controllers/TableController.class.php @@ -14,7 +14,6 @@ if (!defined('PHPMYADMIN')) { exit; } -require_once 'libraries/di/Container.class.php'; require_once 'libraries/controllers/Controller.class.php'; /** @@ -24,8 +23,20 @@ require_once 'libraries/controllers/Controller.class.php'; */ abstract class TableController extends Controller { - function __construct(Container $container = null) + /** + * @var string $db + */ + protected $db; + + /** + * @var string $table + */ + protected $table; + + function __construct() { - parent::__construct($container); + parent::__construct(); + $this->db = $this->container->get('db'); + $this->table = $this->container->get('table'); } -} \ No newline at end of file +} diff --git a/libraries/controllers/TableGisVisualizationController.class.php b/libraries/controllers/TableGisVisualizationController.class.php index 7ee11dea98..b3685ed34a 100644 --- a/libraries/controllers/TableGisVisualizationController.class.php +++ b/libraries/controllers/TableGisVisualizationController.class.php @@ -9,21 +9,20 @@ namespace PMA\Controllers\Table; -use PMA\Controllers\TableController; use PMA\Template; use PMA_GIS_Visualization; use PMA_Message; -use PMA_Util; +use PMA\Controllers\TableController; require_once 'libraries/common.inc.php'; require_once 'libraries/db_common.inc.php'; require_once 'libraries/controllers/TableController.class.php'; require_once 'libraries/gis/GIS_Visualization.class.php'; require_once 'libraries/gis/GIS_Factory.class.php'; -require_once 'libraries/Util.class.php'; require_once 'libraries/Message.class.php'; -class TableGisVisualizationController extends TableController { +class TableGisVisualizationController extends TableController +{ /** * @var array $url_params @@ -45,19 +44,14 @@ class TableGisVisualizationController extends TableController { */ protected $visualization; - public function __construct() { + public function __construct($sql_query, $url_params, $goto, $back, $visualizationSettings) { parent::__construct(); - $this->sql_query = &$GLOBALS['sql_query']; - - $this->url_params = &$GLOBALS['url_params']; - - $this->url_params['goto'] = PMA_Util::getScriptNameForOption( - $GLOBALS['cfg']['DefaultTabDatabase'], 'database' - ); - $this->url_params['back'] = 'sql.php'; - - $this->visualizationSettings = array(); + $this->sql_query = $sql_query; + $this->url_params = $url_params; + $this->url_params['goto'] = $goto; + $this->url_params['back'] = $back; + $this->visualizationSettings = $visualizationSettings; } public function saveToFileAction() { @@ -179,4 +173,4 @@ class TableGisVisualizationController extends TableController { $this->response->addHTML($html); } -} \ No newline at end of file +} diff --git a/libraries/controllers/TableIndexesController.class.php b/libraries/controllers/TableIndexesController.class.php index 01cbb24476..cdd4d2c3ac 100644 --- a/libraries/controllers/TableIndexesController.class.php +++ b/libraries/controllers/TableIndexesController.class.php @@ -26,50 +26,16 @@ require_once 'libraries/Template.class.php'; class TableIndexesController extends TableController { - /** - * @var string $db - */ - protected $db; - - /** - * @var string $table - */ - protected $table; - /** * @var PMA_Index $index */ protected $index; - function __construct() + function __construct($index) { parent::__construct(); - $this->db = $GLOBALS['db']; - $this->table = $GLOBALS['table']; - - /** - * Extract values for common work - * @todo Extract common files - */ - $db = $this->db; - $table = $this->table; - - if (!isset($_REQUEST['create_edit_table'])) { - include_once 'libraries/tbl_common.inc.php'; - } - - if (isset($_REQUEST['index'])) { - if (is_array($_REQUEST['index'])) { - // coming already from form - $this->index = new PMA_Index($_REQUEST['index']); - } else { - $this->index = $this->dbi->getTable($this->db, $this->table) - ->getIndex($_REQUEST['index']); - } - } else { - $this->index = new PMA_Index; - } + $this->index = $index; } public function indexAction() diff --git a/libraries/controllers/TableRelationController.class.php b/libraries/controllers/TableRelationController.class.php index 65e20d9a40..dd4766a5ec 100644 --- a/libraries/controllers/TableRelationController.class.php +++ b/libraries/controllers/TableRelationController.class.php @@ -77,44 +77,18 @@ class TableRelationController extends TableController */ protected $upd_query; - public function __construct() - { + public function __construct($options_array, $cfgRelation, $tbl_storage_engine, + $existrel, $existrel_foreign, $disp, $upd_query + ) { parent::__construct(); - $this->options_array = array( - 'CASCADE' => 'CASCADE', - 'SET_NULL' => 'SET NULL', - 'NO_ACTION' => 'NO ACTION', - 'RESTRICT' => 'RESTRICT', - ); - // Gets the relation settings - $this->cfgRelation = PMA_getRelationsParam(); - $this->db = &$GLOBALS['db']; - $this->table = &$GLOBALS['table']; - $this->tbl_storage_engine = /*overload*/ - mb_strtoupper( - PMA_Table::sGetStatusInfo( - $_REQUEST['db'], - $_REQUEST['table'], - 'Engine' - ) - ); - /** - * Updates - */ - if ($this->cfgRelation['relwork']) { - $this->existrel = PMA_getForeigners($this->db, $this->table, '', 'internal'); - } - if (PMA_Util::isForeignKeySupported($this->tbl_storage_engine)) { - $this->existrel_foreign = PMA_getForeigners($this->db, $this->table, '', 'foreign'); - } - if ($this->cfgRelation['displaywork']) { - $this->disp = PMA_getDisplayField($this->db, $this->table); - } else { - $this->disp = ''; - } - - $this->upd_query = new PMA_Table($this->table, $this->db, $this->dbi); + $this->options_array = $options_array; + $this->cfgRelation = $cfgRelation; + $this->tbl_storage_engine = $tbl_storage_engine; + $this->existrel = $existrel; + $this->existrel_foreign = $existrel_foreign; + $this->disp = $disp; + $this->upd_query = $upd_query; } public function indexAction() @@ -227,7 +201,7 @@ class TableRelationController extends TableController $_POST['destination_foreign_db'], $multi_edit_columns_name, $_POST['destination_foreign_table'], $_POST['destination_foreign_column'], $this->options_array, $this->table, - isset($existrel_foreign) ? $existrel_foreign['foreign_keys_data'] : null + isset($this->existrel_foreign) ? $this->existrel_foreign['foreign_keys_data'] : null ); $this->response->addHTML($html); @@ -253,7 +227,7 @@ class TableRelationController extends TableController if ($this->upd_query->updateInternalRelations( $multi_edit_columns_name, $_POST['destination_db'], $_POST['destination_table'], - $_POST['destination_column'], $this->cfgRelation, isset($existrel) ? $existrel : null + $_POST['destination_column'], $this->cfgRelation, isset($this->existrel) ? $this->existrel : null ) ) { $this->response->addHTML(PMA_Util::getMessage( @@ -353,4 +327,4 @@ class TableRelationController extends TableController } $this->response->addJSON('tables', $tables); } -} \ No newline at end of file +} diff --git a/tbl_chart.php b/tbl_chart.php index 576a4ba7b4..4e9c2ab839 100644 --- a/tbl_chart.php +++ b/tbl_chart.php @@ -12,10 +12,16 @@ require_once 'libraries/di/Container.class.php'; require_once 'libraries/controllers/TableChartController.class.php'; $container = DI\Container::getDefaultContainer(); - $container->factory('PMA\Controllers\Table\TableChartController'); $container->alias('TableChartController', 'PMA\Controllers\Table\TableChartController'); +/* Define dependencies for the concerned controller */ +$dependency_definitions = array( + "sql_query" => &$GLOBALS['sql_query'], + "url_query" => &$GLOBALS['url_query'], + "cfg" => &$GLOBALS['cfg'] +); + /** @var Controllers\Table\TableChartController $controller */ -$controller = $container->get('TableChartController'); +$controller = $container->get('TableChartController', $dependency_definitions); $controller->indexAction(); diff --git a/tbl_gis_visualization.php b/tbl_gis_visualization.php index 545f96b712..4bafe39ad4 100644 --- a/tbl_gis_visualization.php +++ b/tbl_gis_visualization.php @@ -6,9 +6,27 @@ * @package PhpMyAdmin */ -use PMA\Controllers\Table\TableGisVisualizationController; +namespace PMA; +use PMA_Util; + +require_once 'libraries/di/Container.class.php'; require_once 'libraries/controllers/TableGisVisualizationController.class.php'; +require_once 'libraries/Util.class.php'; -$controller = new TableGisVisualizationController(); +$container = DI\Container::getDefaultContainer(); +$container->factory('PMA\Controllers\Table\TableGisVisualizationController'); +$container->alias('TableGisVisualizationController', 'PMA\Controllers\Table\TableGisVisualizationController'); + +/* Define dependencies for the concerned controller */ +$dependency_definitions = array( + "sql_query" => &$GLOBALS['sql_query'], + "url_params" => &$GLOBALS['url_params'], + "goto" => PMA_Util::getScriptNameForOption($GLOBALS['cfg']['DefaultTabDatabase'], 'database'), + "back" => 'sql.php', + "visualizationSettings" => array() +); + +/** @var Controllers\Table\TableGisVisualizationController $controller */ +$controller = $container->get('TableGisVisualizationController', $dependency_definitions); $controller->indexAction(); diff --git a/tbl_indexes.php b/tbl_indexes.php index 1111408024..f2bef4fcb5 100644 --- a/tbl_indexes.php +++ b/tbl_indexes.php @@ -6,9 +6,41 @@ * @package PhpMyAdmin */ +namespace PMA; + +use PMA_Index; + +require_once 'libraries/di/Container.class.php'; require_once 'libraries/controllers/TableIndexesController.class.php'; +require_once 'libraries/Index.class.php'; -use PMA\Controllers\Table\TableIndexesController; +$container = DI\Container::getDefaultContainer(); +$container->factory('PMA\Controllers\Table\TableIndexesController'); +$container->alias('TableIndexesController', 'PMA\Controllers\Table\TableIndexesController'); -$controller = new TableIndexesController(); +/* Define dependencies for the concerned controller */ +$db = $container->get('db'); +$table = $container->get('table'); +$dbi = $container->get('dbi'); + +if (!isset($_REQUEST['create_edit_table'])) { + include_once 'libraries/tbl_common.inc.php'; +} +if (isset($_REQUEST['index'])) { + if (is_array($_REQUEST['index'])) { + // coming already from form + $index = new PMA_Index($_REQUEST['index']); + } else { + $index = $dbi->getTable($db, $table)->getIndex($_REQUEST['index']); + } +} else { + $index = new PMA_Index; +} + +$dependency_definitions = array( + "index" => $index +); + +/** @var Controllers\Table\TableIndexesController $controller */ +$controller = $container->get('TableIndexesController', $dependency_definitions); $controller->indexAction(); diff --git a/tbl_relation.php b/tbl_relation.php index 9fefb5391d..349e59768c 100644 --- a/tbl_relation.php +++ b/tbl_relation.php @@ -17,9 +17,59 @@ /** * Get the TableRelationController */ +namespace PMA; + +use PMA_Table; +use PMA_Util; + +require_once 'libraries/di/Container.class.php'; require_once 'libraries/controllers/TableRelationController.class.php'; +require_once 'libraries/Table.class.php'; +require_once 'libraries/Util.class.php'; -use PMA\Controllers\Table\TableRelationController; +$container = DI\Container::getDefaultContainer(); +$container->factory('PMA\Controllers\Table\TableRelationController'); +$container->alias('TableRelationController', 'PMA\Controllers\Table\TableRelationController'); -$tblRelationCtrl = new TableRelationController(); -$tblRelationCtrl->indexAction(); +/* Define dependencies for the concerned controller */ +$db = $container->get('db'); +$table = $container->get('table'); +$dbi = $container->get('dbi'); +$options_array = array( + 'CASCADE' => 'CASCADE', + 'SET_NULL' => 'SET NULL', + 'NO_ACTION' => 'NO ACTION', + 'RESTRICT' => 'RESTRICT', +); +$cfgRelation = PMA_getRelationsParam(); +$tbl_storage_engine = /*overload*/ + mb_strtoupper( + PMA_Table::sGetStatusInfo( + $db, + $table, + 'Engine' + ) + ); +$upd_query = new PMA_Table($table, $db, $dbi); + +$dependency_definitions = array( + "options_array" => $options_array, + "cfgRelation" => $cfgRelation, + "tbl_storage_engine" => $tbl_storage_engine, + "upd_query" => $upd_query +); +if ($cfgRelation['relwork']) { + $dependency_definitions['existrel'] = PMA_getForeigners($db, $table, '', 'internal'); +} +if (PMA_Util::isForeignKeySupported($tbl_storage_engine)) { + $dependency_definitions['existrel_foreign'] = PMA_getForeigners($db, $table, '', 'foreign'); +} +if ($cfgRelation['displaywork']) { + $dependency_definitions['disp'] = PMA_getDisplayField($db, $table); +} else { + $dependency_definitions['disp'] = 'asas'; +} + +/** @var Controllers\Table\TableRelationController $controller */ +$controller = $container->get('TableRelationController', $dependency_definitions); +$controller->indexAction(); From 5bb0b3dcf3b19b44ae47cb4cc22e1b1f31779c48 Mon Sep 17 00:00:00 2001 From: Atul Pratap Singh Date: Mon, 6 Jul 2015 12:54:59 +0530 Subject: [PATCH 16/16] Add missing class docs Signed-off-by: Atul Pratap Singh --- libraries/di/AliasItem.class.php | 9 ++++++++- libraries/di/Container.class.php | 9 ++++++++- libraries/di/FactoryItem.class.php | 9 ++++++++- libraries/di/Item.int.php | 9 ++++++++- libraries/di/ReflectorItem.class.php | 9 ++++++++- libraries/di/ServiceItem.class.php | 9 ++++++++- libraries/di/ValueItem.class.php | 9 ++++++++- 7 files changed, 56 insertions(+), 7 deletions(-) diff --git a/libraries/di/AliasItem.class.php b/libraries/di/AliasItem.class.php index 3c09922026..5664cd533c 100644 --- a/libraries/di/AliasItem.class.php +++ b/libraries/di/AliasItem.class.php @@ -1,4 +1,11 @@ container->get($this->target, $params); } -} \ No newline at end of file +} diff --git a/libraries/di/Container.class.php b/libraries/di/Container.class.php index a98811e787..75ed3878a2 100644 --- a/libraries/di/Container.class.php +++ b/libraries/di/Container.class.php @@ -1,4 +1,11 @@ invoke($params); } -} \ No newline at end of file +} diff --git a/libraries/di/Item.int.php b/libraries/di/Item.int.php index 3283e9093d..60a0b1dcdc 100644 --- a/libraries/di/Item.int.php +++ b/libraries/di/Item.int.php @@ -1,4 +1,11 @@ instance; } -} \ No newline at end of file +} diff --git a/libraries/di/ValueItem.class.php b/libraries/di/ValueItem.class.php index 7dd352efe2..34d1fb4ea5 100644 --- a/libraries/di/ValueItem.class.php +++ b/libraries/di/ValueItem.class.php @@ -1,4 +1,11 @@ value; } -} \ No newline at end of file +}