2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Holds the PMA\TableRelationController
9 namespace PMA\libraries\controllers\table
;
11 require_once 'libraries/index.lib.php';
13 use PMA\libraries\controllers\TableController
;
14 use PMA\libraries\DatabaseInterface
;
15 use PMA\libraries\Index
;
16 use PMA\libraries\Table
;
17 use PMA\libraries\Template
;
18 use PMA\libraries\Util
;
21 * Handles table relation logic
25 class TableRelationController
extends TableController
28 * @var array $options_array
30 protected $options_array;
33 * @var array $cfgRelation
35 protected $cfgRelation;
38 * @var array $existrel
48 * @var string $tbl_storage_engine
50 protected $tbl_storage_engine;
53 * @var array $existrel_foreign
55 protected $existrel_foreign;
58 * @var Table $udp_query
65 * @param array $options_array Options
66 * @param array $cfgRelation Config relation
67 * @param string $tbl_storage_engine Table storage engine
68 * @param array $existrel Relations
69 * @param array $existrel_foreign External relations
70 * @param string $disp Display
71 * @param string $upd_query Update query
73 public function __construct($options_array, $cfgRelation, $tbl_storage_engine,
74 $existrel, $existrel_foreign, $disp, $upd_query
76 parent
::__construct();
78 $this->options_array
= $options_array;
79 $this->cfgRelation
= $cfgRelation;
80 $this->tbl_storage_engine
= $tbl_storage_engine;
81 $this->existrel
= $existrel;
82 $this->existrel_foreign
= $existrel_foreign;
84 $this->upd_query
= $upd_query;
92 public function indexAction()
94 // Send table of column names to populate corresponding dropdowns depending
95 // on the current selection
96 if (isset($_REQUEST['getDropdownValues'])
97 && $_REQUEST['getDropdownValues'] === 'true'
99 // if both db and table are selected
100 if (isset($_REQUEST['foreignTable'])) {
101 $this->getDropdownValueForTableAction();
102 } else { // if only the db is selected
103 $this->getDropdownValueForDbAction();
108 $this->response
->getHeader()->getScripts()->addFiles(
115 // Gets tables information
116 include_once 'libraries/tbl_info.inc.php';
118 // updates for Internal relations
119 if (isset($_POST['destination_db']) && $this->cfgRelation
['relwork']) {
120 $this->updateForInternalRelationAction();
123 // updates for foreign keys
124 if (isset($_POST['destination_foreign_db'])) {
125 $this->updateForForeignKeysAction();
128 // Updates for display field
129 if ($this->cfgRelation
['displaywork'] && isset($_POST['display_field'])) {
130 $this->updateForDisplayField();
133 // If we did an update, refresh our data
134 if (isset($_POST['destination_db']) && $this->cfgRelation
['relwork']) {
135 $this->existrel
= PMA_getForeigners(
136 $this->db
, $this->table
, '', 'internal'
139 if (isset($_POST['destination_foreign_db'])
140 && Util
::isForeignKeySupported($this->tbl_storage_engine
)
142 $this->existrel_foreign
= PMA_getForeigners(
143 $this->db
, $this->table
, '', 'foreign'
147 if ($this->cfgRelation
['displaywork']) {
148 $this->disp
= PMA_getDisplayField($this->db
, $this->table
);
151 // display secondary level tabs if necessary
152 $engine = $this->dbi
->getTable($this->db
, $this->table
)
153 ->getStatusInfo('ENGINE');
155 $this->response
->addHTML(
156 Template
::get('table/secondary_tabs')->render(
158 'url_params' => array(
159 'db' => $GLOBALS['db'],
160 'table' => $GLOBALS['table']
166 $this->response
->addHTML('<div id="structure_content">');
171 // Now find out the columns of our $table
172 // need to use DatabaseInterface::QUERY_STORE with $this->dbi->numRows()
174 $columns = $this->dbi
->getColumns($this->db
, $this->table
);
177 $this->response
->addHTML(
178 Template
::get('table/relation/common_form')->render(
181 'table' => $this->table
,
182 'columns' => $columns,
183 'cfgRelation' => $this->cfgRelation
,
184 'tbl_storage_engine' => $this->tbl_storage_engine
,
185 'existrel' => isset($this->existrel
) ?
$this->existrel
: array(),
186 'existrel_foreign' => isset($this->existrel_foreign
)
187 ?
$this->existrel_foreign
['foreign_keys_data'] : array(),
188 'options_array' => $this->options_array
193 if (Util
::isForeignKeySupported($this->tbl_storage_engine
)) {
194 $this->response
->addHTML(PMA_getHtmlForDisplayIndexes());
196 $this->response
->addHTML('</div>');
200 * Update for display field
204 public function updateForDisplayField()
206 if ($this->upd_query
->updateDisplayField(
207 $this->disp
, $_POST['display_field'], $this->cfgRelation
210 $this->response
->addHTML(
212 __('Display column was successfully updated.'),
224 public function updateForForeignKeysAction()
226 $multi_edit_columns_name = isset($_REQUEST['foreign_key_fields_name'])
227 ?
$_REQUEST['foreign_key_fields_name']
230 // (for now, one index name only; we keep the definitions if the
231 // foreign db is not the same)
232 list($html, $preview_sql_data, $display_query, $seen_error)
233 = $this->upd_query
->updateForeignKeys(
234 $_POST['destination_foreign_db'],
235 $multi_edit_columns_name, $_POST['destination_foreign_table'],
236 $_POST['destination_foreign_column'], $this->options_array
,
238 isset($this->existrel_foreign
)
239 ?
$this->existrel_foreign
['foreign_keys_data']
242 $this->response
->addHTML($html);
244 // If there is a request for SQL previewing.
245 if (isset($_REQUEST['preview_sql'])) {
246 PMA_previewSQL($preview_sql_data);
249 if (!empty($display_query) && !$seen_error) {
250 $GLOBALS['display_query'] = $display_query;
251 $this->response
->addHTML(
253 __('Your SQL query has been executed successfully.'),
261 * Update for internal relation
265 public function updateForInternalRelationAction()
267 $multi_edit_columns_name = isset($_REQUEST['fields_name'])
268 ?
$_REQUEST['fields_name']
271 if ($this->upd_query
->updateInternalRelations(
272 $multi_edit_columns_name,
273 $_POST['destination_db'],
274 $_POST['destination_table'],
275 $_POST['destination_column'],
277 isset($this->existrel
) ?
$this->existrel
: null
280 $this->response
->addHTML(
282 __('Internal relationships were successfully updated.'),
290 * Send table columns for foreign table dropdown
295 public function getDropdownValueForTableAction()
297 $foreignTable = $_REQUEST['foreignTable'];
298 $table_obj = $this->dbi
->getTable($_REQUEST['foreignDb'], $foreignTable);
299 // Since views do not have keys defined on them provide the full list of
301 if ($table_obj->isView()) {
302 $columnList = $table_obj->getColumns(false, false);
304 $columnList = $table_obj->getIndexedColumns(false, false);
307 foreach ($columnList as $column) {
308 $columns[] = htmlspecialchars($column);
310 if ($GLOBALS['cfg']['NaturalOrder']) {
311 usort($columns, 'strnatcasecmp');
313 $this->response
->addJSON('columns', $columns);
315 // @todo should be: $server->db($db)->table($table)->primary()
316 $primary = Index
::getPrimary($foreignTable, $_REQUEST['foreignDb']);
317 if (false === $primary) {
321 $this->response
->addJSON('primary', array_keys($primary->getColumns()));
325 * Send database selection values for dropdown
330 public function getDropdownValueForDbAction()
333 $foreign = isset($_REQUEST['foreign']) && $_REQUEST['foreign'] === 'true';
336 $query = 'SHOW TABLE STATUS FROM '
337 . Util
::backquote($_REQUEST['foreignDb']);
338 $tables_rs = $this->dbi
->query(
341 DatabaseInterface
::QUERY_STORE
344 while ($row = $this->dbi
->fetchArray($tables_rs)) {
345 if (isset($row['Engine'])
346 && mb_strtoupper($row['Engine']) == $this->tbl_storage_engine
348 $tables[] = htmlspecialchars($row['Name']);
352 $query = 'SHOW TABLES FROM '
353 . Util
::backquote($_REQUEST['foreignDb']);
354 $tables_rs = $this->dbi
->query(
357 DatabaseInterface
::QUERY_STORE
359 while ($row = $this->dbi
->fetchArray($tables_rs)) {
360 $tables[] = htmlspecialchars($row[0]);
363 if ($GLOBALS['cfg']['NaturalOrder']) {
364 usort($tables, 'strnatcasecmp');
366 $this->response
->addJSON('tables', $tables);