Merge pull request #1758 from gzzhanghao/controller

WIP: Introduce Controllers
This commit is contained in:
Atul Pratap Singh 2015-07-05 22:33:45 +05:30
commit aba718f105
21 changed files with 1606 additions and 800 deletions

View File

@ -0,0 +1,55 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds the PMA\TableController
*
* @package PMA
*/
namespace PMA\Controllers;
use PMA\DI\Container;
use PMA_DatabaseInterface;
use PMA_Response;
if (!defined('PHPMYADMIN')) {
exit;
}
require_once 'libraries/Response.class.php';
require_once 'libraries/di/Container.class.php';
require_once 'libraries/database_interface.inc.php';
/**
* Base class for all of controller
*
* @package PhpMyAdmin
*/
abstract class Controller
{
/**
* @var PMA_Response
*/
protected $response;
/**
* @var PMA_DatabaseInterface
*/
protected $dbi;
/**
* @var Container
*/
protected $container;
function __construct(Container $container = null)
{
if (!isset($container)) {
$container = Container::getDefaultContainer();
}
$this->container = $container;
$this->dbi = $container->get('dbi');
$this->response = PMA_Response::getInstance();
}
}

View File

@ -0,0 +1,235 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds the PMA\TableChartController
*
* @package PMA
*/
namespace PMA\Controllers\Table;
use PMA\DI\Container;
use PMA_Util;
use PMA_Message;
use PMA\Template;
use PMA\Controllers\TableController;
require_once 'libraries/common.inc.php';
require_once 'libraries/Util.class.php';
require_once 'libraries/Message.class.php';
require_once 'libraries/Template.class.php';
require_once 'libraries/controllers/TableController.class.php';
/**
* Handles table related logic
*
* @package PhpMyAdmin
*/
class TableChartController extends TableController
{
/**
* @var string $sql_query
*/
protected $sql_query;
/**
* @var $url_query
*/
protected $url_query;
/**
* @var string $db
*/
protected $db;
/**
* @var string $table
*/
protected $table;
/**
* @var array $cfg
*/
protected $cfg;
function __construct(Container $container = null)
{
parent::__construct($container);
$this->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));
}
}

View File

@ -0,0 +1,31 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds the PMA\TableController
*
* @package PMA
*/
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';
/**
* Handles table related logic
*
* @package PhpMyAdmin
*/
abstract class TableController extends Controller
{
function __construct(Container $container = null)
{
parent::__construct($container);
}
}

View File

@ -0,0 +1,182 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds the PMA\TableIndexesController
*
* @package PMA
*/
namespace PMA\Controllers\Table;
use PMA\Controllers\TableController;
use PMA\Template;
use PMA_GIS_Visualization;
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';
require_once 'libraries/Util.class.php';
require_once 'libraries/Message.class.php';
class TableGisVisualizationController extends TableController {
/**
* @var array $url_params
*/
protected $url_params;
/**
* @var string $sql_query
*/
protected $sql_query;
/**
* @var array $visualizationSettings
*/
protected $visualizationSettings;
/**
* @var PMA_GIS_Visualization $visualization
*/
protected $visualization;
public function __construct() {
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();
}
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($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;
}
// Execute the query and return the result
$result = $this->dbi->tryQuery($this->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];
}
// 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;
}
$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);
}
}

View File

@ -0,0 +1,193 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds the PMA\TableIndexesController
*
* @package PMA
*/
namespace PMA\Controllers\Table;
use PMA\Controllers\TableController;
use PMA_Index;
use PMA_Message;
use PMA_Response;
use PMA\Template;
use PMA_Util;
require_once 'libraries/common.inc.php';
require_once 'libraries/Index.class.php';
require_once 'libraries/Message.class.php';
require_once 'libraries/Util.class.php';
require_once 'libraries/Index.class.php';
require_once 'libraries/controllers/TableController.class.php';
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()
{
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;
}
}
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);
}
}
}

View File

@ -0,0 +1,356 @@
<?php
/* vim: set expandtab sw=4 ts=4 sts=4: */
/**
* Holds the PMA\TableRelationController
*
* @package PMA
*/
namespace PMA\Controllers\Table;
require_once 'libraries/common.inc.php';
require_once 'libraries/DatabaseInterface.class.php';
require_once 'libraries/controllers/TableController.class.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/Index.class.php';
require_once 'libraries/Util.class.php';
use PMA_DatabaseInterface;
use PMA_Table;
use PMA_Index;
use PMA_Util;
use PMA\Controllers\TableController;
use PMA\Template;
/**
* Handles table relation logic
*
* @package PhpMyAdmin
*/
class TableRelationController extends TableController
{
/**
* @var array $options_array
*/
protected $options_array;
/**
* @var array $cfgRelation
*/
protected $cfgRelation;
/**
* @var array $existrel
*/
protected $existrel;
/**
* @var string $db
*/
protected $db;
/**
* @var string $table
*/
protected $table;
/**
* @var string $disp
*/
protected $disp;
/**
* @var string $tbl_storage_engine
*/
protected $tbl_storage_engine;
/**
* @var array $existrel_foreign
*/
protected $existrel_foreign;
/**
* @var PMA_Table $udp_query
*/
protected $upd_query;
public function __construct()
{
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);
}
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('<div id="structure_content">');
/**
* 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('</div>');
}
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);
}
}

View File

@ -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');

View File

@ -0,0 +1,37 @@
<?php
namespace PMA\DI;
require_once 'libraries/di/Item.int.php';
class AliasItem implements Item
{
/** @var Container */
protected $container;
/** @var string */
protected $target;
/**
* Constructor
*
* @param Container $container
* @param string $target
*/
function __construct(Container $container, $target)
{
$this->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);
}
}

View File

@ -0,0 +1,147 @@
<?php
namespace PMA\DI;
require_once 'libraries/di/Item.int.php';
require_once 'libraries/di/AliasItem.class.php';
require_once 'libraries/di/ValueItem.class.php';
require_once 'libraries/di/ServiceItem.class.php';
require_once 'libraries/di/FactoryItem.class.php';
class Container
{
/**
* @var Item[] $content
*/
protected $content = array();
/**
* @var Container
*/
protected static $defaultContainer;
/**
* Create a dependency injection container
*
* @param Container $base
*/
function __construct(Container $base = null)
{
if (isset($base)) {
$this->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);
}
if (isset($GLOBALS[$name])) {
return $GLOBALS[$name];
}
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;
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace PMA\DI;
require_once 'libraries/di/ReflectorItem.class.php';
class FactoryItem extends ReflectorItem
{
/**
* Constructor
*
* @param Container $container
* @param mixed $definition
*/
function __construct(Container $container, $definition)
{
parent::__construct($container, $definition);
}
/**
* Construct an instance
*
* @param array $params
* @return mixed
*/
public function get($params = array())
{
return $this->invoke($params);
}
}

14
libraries/di/Item.int.php Normal file
View File

@ -0,0 +1,14 @@
<?php
namespace PMA\DI;
interface Item
{
/**
* Get a value from the item
*
* @param array $params
* @return mixed
*/
public function get($params = array());
}

View File

@ -0,0 +1,113 @@
<?php
namespace PMA\DI;
require_once 'libraries/di/Item.int.php';
abstract class ReflectorItem implements Item
{
/** @var Container */
private $container;
/** @var \Reflector */
private $reflector;
/**
* Constructor
*
* @param Container $container
* @param mixed $definition
*/
public function __construct(Container $container, $definition)
{
$this->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]);
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace PMA\DI;
require_once 'libraries/di/ReflectorItem.class.php';
class ServiceItem extends ReflectorItem
{
/** @var mixed */
protected $instance;
/**
* Constructor
*
* @param Container $container
* @param mixed $definition
*/
function __construct(Container $container, $definition)
{
parent::__construct($container, $definition);
}
/**
* Get the instance of the service
*
* @param array $params
* @return mixed
*/
public function get($params = array())
{
if (!isset($this->instance)) {
$this->instance = $this->invoke();
}
return $this->instance;
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace PMA\DI;
require_once 'libraries/di/Item.int.php';
class ValueItem implements Item
{
/** @var mixed */
protected $value;
/**
* Constructor
*
* @param $value
*/
function __construct($value)
{
$this->value = $value;
}
/**
* Get the value
*
* @param array $params
* @return mixed
*/
public function get($params = array())
{
return $this->value;
}
}

View File

@ -617,5 +617,13 @@ class PMA_GIS_Visualization
}
return $results;
}
/**
* @param array $userSpecifiedSettings
*/
public function setUserSpecifiedSettings($userSpecifiedSettings)
{
$this->_userSpecifiedSettings = $userSpecifiedSettings;
}
}
?>

View File

@ -6,15 +6,19 @@
*
* @package PhpMyAdmin
*/
if (! defined('PHPMYADMIN')) {
if (!defined('PHPMYADMIN')) {
exit;
}
/**
* 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';
require_once 'libraries/util.lib.php';
use PMA\Util;
PMA_Util::checkParameters(array('server', 'db', 'table', 'action', 'num_fields'));
@ -22,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();
}
@ -49,21 +53,22 @@ $length_values_input_size = 8;
$content_cells = array();
/** @var string $db */
$form_params = array(
'db' => $db
);
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;
}
@ -71,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) {
@ -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();
@ -134,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':
@ -194,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;
}
@ -325,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 . ']'] = '';
@ -340,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(
@ -418,9 +340,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);
?>

26
libraries/util.lib.php Normal file
View File

@ -0,0 +1,26 @@
<?php
namespace PMA\Util;
/**
* Access to a multidimensional array by dot notation
*
* @param array $array
* @param string|array $path
* @param mixed $default
* @return mixed
*/
function get($array, $path, $default = null) {
if (is_string($path)) {
$path = explode('.', $path);
}
$p = array_shift($path);
while (isset($p)) {
if (!isset($array[$p])) {
return $default;
}
$array = $array[$p];
$p = array_shift($path);
}
return $array;
}

View File

@ -6,151 +6,16 @@
* @package PhpMyAdmin
*/
require_once 'libraries/common.inc.php';
require_once 'libraries/Template.class.php';
use PMA\Template;
namespace PMA;
/*
* Execute the query and return the result
*/
if (isset($_REQUEST['ajax_request'])
&& isset($_REQUEST['pos'])
&& isset($_REQUEST['session_max_rows'])
) {
$response = PMA_Response::getInstance();
require_once 'libraries/di/Container.class.php';
require_once 'libraries/controllers/TableChartController.class.php';
$tableLength = /*overload*/mb_strlen($GLOBALS['table']);
$dbLength = /*overload*/mb_strlen($GLOBALS['db']);
if ($tableLength && $dbLength) {
include './libraries/tbl_common.inc.php';
}
$container = DI\Container::getDefaultContainer();
$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;
}
$container->factory('PMA\Controllers\Table\TableChartController');
$container->alias('TableChartController', 'PMA\Controllers\Table\TableChartController');
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
)
)
);
/** @var Controllers\Table\TableChartController $controller */
$controller = $container->get('TableChartController');
$controller->indexAction();

View File

@ -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/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();

View File

@ -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/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();

View File

@ -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/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('<div id="structure_content">');
/**
* 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('</div>');
$tblRelationCtrl = new TableRelationController();
$tblRelationCtrl->indexAction();