Translated using Weblate (Slovenian)
[phpmyadmin.git] / libraries / central_columns.lib.php
blob19b3d049f63e35241cc8b959d22ad6c80c875ef7
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Functions for displaying user preferences pages
6 * @package PhpMyAdmin
7 */
8 use PMA\libraries\Charsets;
9 use PMA\libraries\Message;
10 use PMA\libraries\Util;
11 use PMA\libraries\URL;
13 /**
14 * Defines the central_columns parameters for the current user
16 * @return array the central_columns parameters for the current user
17 * @access public
19 function PMA_centralColumnsGetParams()
21 static $cfgCentralColumns = null;
23 if (null !== $cfgCentralColumns) {
24 return $cfgCentralColumns;
27 $cfgRelation = PMA_getRelationsParam();
29 if ($cfgRelation['centralcolumnswork']) {
30 $cfgCentralColumns = array(
31 'user' => $GLOBALS['cfg']['Server']['user'],
32 'db' => $cfgRelation['db'],
33 'table' => $cfgRelation['central_columns'],
35 } else {
36 $cfgCentralColumns = false;
39 return $cfgCentralColumns;
42 /**
43 * get $num columns of given database from central columns list
44 * starting at offset $from
46 * @param string $db selected database
47 * @param int $from starting offset of first result
48 * @param int $num maximum number of results to return
50 * @return array list of $num columns present in central columns list
51 * starting at offset $from for the given database
53 function PMA_getColumnsList($db, $from=0, $num=25)
55 $cfgCentralColumns = PMA_centralColumnsGetParams();
56 if (empty($cfgCentralColumns)) {
57 return array();
59 $pmadb = $cfgCentralColumns['db'];
60 $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
61 $central_list_table = $cfgCentralColumns['table'];
62 //get current values of $db from central column list
63 if ($num == 0) {
64 $query = 'SELECT * FROM ' . Util::backquote($central_list_table) . ' '
65 . 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\';';
66 } else {
67 $query = 'SELECT * FROM ' . Util::backquote($central_list_table) . ' '
68 . 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' '
69 . 'LIMIT ' . $from . ', ' . $num . ';';
71 $has_list = (array) $GLOBALS['dbi']->fetchResult(
72 $query, null, null, $GLOBALS['controllink']
74 PMA_handleColumnExtra($has_list);
75 return $has_list;
78 /**
79 * get the number of columns present in central list for given db
81 * @param string $db current database
83 * @return int number of columns in central list of columns for $db
85 function PMA_getCentralColumnsCount($db)
87 $cfgCentralColumns = PMA_centralColumnsGetParams();
88 if (empty($cfgCentralColumns)) {
89 return 0;
91 $pmadb = $cfgCentralColumns['db'];
92 $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
93 $central_list_table = $cfgCentralColumns['table'];
94 $query = 'SELECT count(db_name) FROM ' .
95 Util::backquote($central_list_table) . ' '
96 . 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\';';
97 $res = $GLOBALS['dbi']->fetchResult(
98 $query, null, null, $GLOBALS['controllink']
100 if (isset($res[0])) {
101 return $res[0];
102 } else {
103 return 0;
107 * return the existing columns in central list among the given list of columns
109 * @param string $db the selected database
110 * @param string $cols comma separated list of given columns
111 * @param boolean $allFields set if need all the fields of existing columns,
112 * otherwise only column_name is returned
114 * @return array list of columns in central columns among given set of columns
116 function PMA_findExistingColNames($db, $cols, $allFields=false)
118 $cfgCentralColumns = PMA_centralColumnsGetParams();
119 if (empty($cfgCentralColumns)) {
120 return array();
122 $pmadb = $cfgCentralColumns['db'];
123 $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
124 $central_list_table = $cfgCentralColumns['table'];
125 if ($allFields) {
126 $query = 'SELECT * FROM ' . Util::backquote($central_list_table) . ' '
127 . 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
128 $has_list = (array) $GLOBALS['dbi']->fetchResult(
129 $query, null, null, $GLOBALS['controllink']
131 PMA_handleColumnExtra($has_list);
132 } else {
133 $query = 'SELECT col_name FROM '
134 . Util::backquote($central_list_table) . ' '
135 . 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
136 $has_list = (array) $GLOBALS['dbi']->fetchResult(
137 $query, null, null, $GLOBALS['controllink']
141 return $has_list;
145 * return error message to be displayed if central columns
146 * configuration storage is not completely configured
148 * @return Message
150 function PMA_configErrorMessage()
152 return Message::error(
154 'The configuration storage is not ready for the central list'
155 . ' of columns feature.'
161 * build the insert query for central columns list given PMA storage
162 * db, central_columns table, column name and corresponding definition to be added
164 * @param string $column column to add into central list
165 * @param array $def list of attributes of the column being added
166 * @param string $db PMA configuration storage database name
167 * @param string $central_list_table central columns configuration storage table name
169 * @return string query string to insert the given column
170 * with definition into central list
172 function PMA_getInsertQuery($column, $def, $db, $central_list_table)
174 $type = "";
175 $length = 0;
176 $attribute = "";
177 if (isset($def['Type'])) {
178 $extracted_columnspec = Util::extractColumnSpec($def['Type']);
179 $attribute = trim($extracted_columnspec[ 'attribute']);
180 $type = $extracted_columnspec['type'];
181 $length = $extracted_columnspec['spec_in_brackets'];
183 if (isset($def['Attribute'])) {
184 $attribute = $def['Attribute'];
186 $collation = isset($def['Collation'])?$def['Collation']:"";
187 $isNull = ($def['Null'] == "NO")?0:1;
188 $extra = isset($def['Extra'])?$def['Extra']:"";
189 $default = isset($def['Default'])?$def['Default']:"";
190 $insQuery = 'INSERT INTO '
191 . Util::backquote($central_list_table) . ' '
192 . 'VALUES ( \'' . $GLOBALS['dbi']->escapeString($db) . '\' ,'
193 . '\'' . $GLOBALS['dbi']->escapeString($column) . '\',\''
194 . $GLOBALS['dbi']->escapeString($type) . '\','
195 . '\'' . $GLOBALS['dbi']->escapeString($length) . '\',\''
196 . $GLOBALS['dbi']->escapeString($collation) . '\','
197 . '\'' . $GLOBALS['dbi']->escapeString($isNull) . '\','
198 . '\'' . implode(',', array($extra, $attribute))
199 . '\',\'' . $GLOBALS['dbi']->escapeString($default) . '\');';
200 return $insQuery;
204 * If $isTable is true then unique columns from given tables as $field_select
205 * are added to central list otherwise the $field_select is considered as
206 * list of columns and these columns are added to central list if not already added
208 * @param array $field_select if $isTable is true selected tables list
209 * otherwise selected columns list
210 * @param bool $isTable if passed array is of tables or columns
211 * @param string $table if $isTable is false,
212 * then table name to which columns belong
214 * @return true|PMA\libraries\Message
216 function PMA_syncUniqueColumns($field_select, $isTable=true, $table=null)
218 $cfgCentralColumns = PMA_centralColumnsGetParams();
219 if (empty($cfgCentralColumns)) {
220 return PMA_configErrorMessage();
222 $db = $_REQUEST['db'];
223 $pmadb = $cfgCentralColumns['db'];
224 $central_list_table = $cfgCentralColumns['table'];
225 $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
226 $existingCols = array();
227 $cols = "";
228 $insQuery = array();
229 $fields = array();
230 $message = true;
231 if ($isTable) {
232 foreach ($field_select as $table) {
233 $fields[$table] = (array) $GLOBALS['dbi']->getColumns(
234 $db, $table, null, true, $GLOBALS['userlink']
236 foreach ($fields[$table] as $field => $def) {
237 $cols .= "'" . $GLOBALS['dbi']->escapeString($field) . "',";
241 $has_list = PMA_findExistingColNames($db, trim($cols, ','));
242 foreach ($field_select as $table) {
243 foreach ($fields[$table] as $field => $def) {
244 if (!in_array($field, $has_list)) {
245 $has_list[] = $field;
246 $insQuery[] = PMA_getInsertQuery(
247 $field, $def, $db, $central_list_table
249 } else {
250 $existingCols[] = "'" . $field . "'";
254 } else {
255 if ($table === null) {
256 $table = $_REQUEST['table'];
258 foreach ($field_select as $column) {
259 $cols .= "'" . $GLOBALS['dbi']->escapeString($column) . "',";
261 $has_list = PMA_findExistingColNames($db, trim($cols, ','));
262 foreach ($field_select as $column) {
263 if (!in_array($column, $has_list)) {
264 $has_list[] = $column;
265 $field = (array) $GLOBALS['dbi']->getColumns(
266 $db, $table, $column,
267 true, $GLOBALS['userlink']
269 $insQuery[] = PMA_getInsertQuery(
270 $column, $field, $db, $central_list_table
272 } else {
273 $existingCols[] = "'" . $column . "'";
277 if (! empty($existingCols)) {
278 $existingCols = implode(",", array_unique($existingCols));
279 $message = Message::notice(
280 sprintf(
282 'Could not add %1$s as they already exist in central list!'
283 ), htmlspecialchars($existingCols)
286 $message->addMessage(
287 Message::notice(
288 "Please remove them first "
289 . "from central list if you want to update above columns"
293 $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
294 if (! empty($insQuery)) {
295 foreach ($insQuery as $query) {
296 if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['controllink'])) {
297 $message = Message::error(__('Could not add columns!'));
298 $message->addMessage(
299 Message::rawError(
300 $GLOBALS['dbi']->getError($GLOBALS['controllink'])
303 break;
307 return $message;
311 * if $isTable is true it removes all columns of given tables as $field_select from
312 * central columns list otherwise $field_select is columns list and it removes
313 * given columns if present in central list
315 * @param array $field_select if $isTable selected list of tables otherwise
316 * selected list of columns to remove from central list
317 * @param bool $isTable if passed array is of tables or columns
319 * @return true|PMA\libraries\Message
321 function PMA_deleteColumnsFromList($field_select, $isTable=true)
323 $cfgCentralColumns = PMA_centralColumnsGetParams();
324 if (empty($cfgCentralColumns)) {
325 return PMA_configErrorMessage();
327 $db = $_REQUEST['db'];
328 $pmadb = $cfgCentralColumns['db'];
329 $central_list_table = $cfgCentralColumns['table'];
330 $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
331 $message = true;
332 $colNotExist = array();
333 $fields = array();
334 if ($isTable) {
335 $cols = '';
336 foreach ($field_select as $table) {
337 $fields[$table] = (array) $GLOBALS['dbi']->getColumnNames(
338 $db, $table, $GLOBALS['userlink']
340 foreach ($fields[$table] as $col_select) {
341 $cols .= '\'' . $GLOBALS['dbi']->escapeString($col_select) . '\',';
344 $cols = trim($cols, ',');
345 $has_list = PMA_findExistingColNames($db, $cols);
346 foreach ($field_select as $table) {
347 foreach ($fields[$table] as $column) {
348 if (!in_array($column, $has_list)) {
349 $colNotExist[] = "'" . $column . "'";
354 } else {
355 $cols = '';
356 foreach ($field_select as $col_select) {
357 $cols .= '\'' . $GLOBALS['dbi']->escapeString($col_select) . '\',';
359 $cols = trim($cols, ',');
360 $has_list = PMA_findExistingColNames($db, $cols);
361 foreach ($field_select as $column) {
362 if (!in_array($column, $has_list)) {
363 $colNotExist[] = "'" . $column . "'";
367 if (!empty($colNotExist)) {
368 $colNotExist = implode(",", array_unique($colNotExist));
369 $message = Message::notice(
370 sprintf(
372 'Couldn\'t remove Column(s) %1$s '
373 . 'as they don\'t exist in central columns list!'
374 ), htmlspecialchars($colNotExist)
378 $GLOBALS['dbi']->selectDb($pmadb, $GLOBALS['controllink']);
380 $query = 'DELETE FROM ' . Util::backquote($central_list_table) . ' '
381 . 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
383 if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['controllink'])) {
384 $message = Message::error(__('Could not remove columns!'));
385 $message->addHtml('<br />' . htmlspecialchars($cols) . '<br />');
386 $message->addMessage(
387 Message::rawError(
388 $GLOBALS['dbi']->getError($GLOBALS['controllink'])
392 return $message;
396 * make the columns of given tables consistent with central list of columns.
397 * Updates only those columns which are not being referenced.
399 * @param string $db current database
400 * @param array $selected_tables list of selected tables.
402 * @return true|PMA\libraries\Message
404 function PMA_makeConsistentWithList($db, $selected_tables)
406 $message = true;
407 foreach ($selected_tables as $table) {
408 $query = 'ALTER TABLE ' . Util::backquote($table);
409 $has_list = PMA_getCentralColumnsFromTable($db, $table, true);
410 $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
411 foreach ($has_list as $column) {
412 $column_status = PMA_checkChildForeignReferences(
413 $db, $table, $column['col_name']
415 //column definition can only be changed if
416 //it is not referenced by another column
417 if ($column_status['isEditable']) {
418 $query .= ' MODIFY ' . Util::backquote($column['col_name']) . ' '
419 . $GLOBALS['dbi']->escapeString($column['col_type']);
420 if ($column['col_length']) {
421 $query .= '(' . $column['col_length'] . ')';
424 $query .= ' ' . $column['col_attribute'];
425 if ($column['col_isNull']) {
426 $query .= ' NULL';
427 } else {
428 $query .= ' NOT NULL';
431 $query .= ' ' . $column['col_extra'];
432 if ($column['col_default']) {
433 if ($column['col_default'] != 'CURRENT_TIMESTAMP') {
434 $query .= ' DEFAULT \'' . $GLOBALS['dbi']->escapeString(
435 $column['col_default']
436 ) . '\'';
437 } else {
438 $query .= ' DEFAULT ' . $GLOBALS['dbi']->escapeString(
439 $column['col_default']
443 $query .= ',';
446 $query = trim($query, " ,") . ";";
447 if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['userlink'])) {
448 if ($message === true) {
449 $message = Message::error(
450 $GLOBALS['dbi']->getError($GLOBALS['userlink'])
452 } else {
453 $message->addText(
454 $GLOBALS['dbi']->getError($GLOBALS['userlink']),
455 '<br />'
460 return $message;
464 * return the columns present in central list of columns for a given
465 * table of a given database
467 * @param string $db given database
468 * @param string $table given table
469 * @param boolean $allFields set if need all the fields of existing columns,
470 * otherwise only column_name is returned
472 * @return array columns present in central list from given table of given db.
474 function PMA_getCentralColumnsFromTable($db, $table, $allFields=false)
476 $cfgCentralColumns = PMA_centralColumnsGetParams();
477 if (empty($cfgCentralColumns)) {
478 return array();
480 $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
481 $fields = (array) $GLOBALS['dbi']->getColumnNames(
482 $db, $table, $GLOBALS['userlink']
484 $cols = '';
485 foreach ($fields as $col_select) {
486 $cols .= '\'' . $GLOBALS['dbi']->escapeString($col_select) . '\',';
488 $cols = trim($cols, ',');
489 $has_list = PMA_findExistingColNames($db, $cols, $allFields);
490 if (! empty($has_list)) {
491 return (array)$has_list;
492 } else {
493 return array();
498 * update a column in central columns list if a edit is requested
500 * @param string $db current database
501 * @param string $orig_col_name original column name before edit
502 * @param string $col_name new column name
503 * @param string $col_type new column type
504 * @param string $col_attribute new column attribute
505 * @param string $col_length new column length
506 * @param int $col_isNull value 1 if new column isNull is true, 0 otherwise
507 * @param string $collation new column collation
508 * @param string $col_extra new column extra property
509 * @param string $col_default new column default value
511 * @return true|PMA\libraries\Message
513 function PMA_updateOneColumn($db, $orig_col_name, $col_name, $col_type,
514 $col_attribute,$col_length, $col_isNull, $collation, $col_extra, $col_default
516 $cfgCentralColumns = PMA_centralColumnsGetParams();
517 if (empty($cfgCentralColumns)) {
518 return PMA_configErrorMessage();
520 $centralTable = $cfgCentralColumns['table'];
521 $GLOBALS['dbi']->selectDb($cfgCentralColumns['db'], $GLOBALS['controllink']);
522 if ($orig_col_name == "") {
523 $def = array();
524 $def['Type'] = $col_type;
525 if ($col_length) {
526 $def['Type'] .= '(' . $col_length . ')';
528 $def['Collation'] = $collation;
529 $def['Null'] = $col_isNull?__('YES'):__('NO');
530 $def['Extra'] = $col_extra;
531 $def['Attribute'] = $col_attribute;
532 $def['Default'] = $col_default;
533 $query = PMA_getInsertQuery($col_name, $def, $db, $centralTable);
534 } else {
535 $query = 'UPDATE ' . Util::backquote($centralTable)
536 . ' SET col_type = \'' . $GLOBALS['dbi']->escapeString($col_type) . '\''
537 . ', col_name = \'' . $GLOBALS['dbi']->escapeString($col_name) . '\''
538 . ', col_length = \'' . $GLOBALS['dbi']->escapeString($col_length) . '\''
539 . ', col_isNull = ' . $col_isNull
540 . ', col_collation = \'' . $GLOBALS['dbi']->escapeString($collation) . '\''
541 . ', col_extra = \''
542 . implode(',', array($col_extra, $col_attribute)) . '\''
543 . ', col_default = \'' . $GLOBALS['dbi']->escapeString($col_default) . '\''
544 . ' WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\' '
545 . 'AND col_name = \'' . $GLOBALS['dbi']->escapeString($orig_col_name)
546 . '\'';
548 if (!$GLOBALS['dbi']->tryQuery($query, $GLOBALS['controllink'])) {
549 return Message::error(
550 $GLOBALS['dbi']->getError($GLOBALS['controllink'])
553 return true;
557 * Update Multiple column in central columns list if a chnage is requested
559 * @return true|PMA\libraries\Message
561 function PMA_updateMultipleColumn()
563 $db = $_POST['db'];
564 $col_name = $_POST['field_name'];
565 $orig_col_name = $_POST['orig_col_name'];
566 $col_default = $_POST['field_default_type'];
567 $col_length = $_POST['field_length'];
568 $col_attribute = $_POST['field_attribute'];
569 $col_type = $_POST['field_type'];
570 $collation = $_POST['field_collation'];
571 $col_isNull = array();
572 $col_extra = array();
573 $num_central_fields = count($orig_col_name);
574 for ($i = 0; $i < $num_central_fields ; $i++) {
575 $col_isNull[$i] = isset($_POST['field_null'][$i]) ? 1 : 0;
576 $col_extra[$i] = isset($_POST['col_extra'][$i])
577 ? $_POST['col_extra'][$i] : '';
579 if ($col_default[$i] == 'NONE') {
580 $col_default[$i] = "";
581 } else if ($col_default[$i] == 'USER_DEFINED') {
582 $col_default[$i] = $_POST['field_default_value'][$i];
585 $message = PMA_updateOneColumn(
586 $db, $orig_col_name[$i], $col_name[$i], $col_type[$i],
587 $col_attribute[$i], $col_length[$i], $col_isNull[$i], $collation[$i],
588 $col_extra[$i], $col_default[$i]
590 if (!is_bool($message)) {
591 return $message;
594 return true;
598 * get the html for table navigation in Central columns page
600 * @param int $total_rows total number of rows in complete result set
601 * @param int $pos offset of first result with complete result set
602 * @param string $db current database
604 * @return string html for table navigation in Central columns page
606 function PMA_getHTMLforTableNavigation($total_rows, $pos, $db)
608 $max_rows = $GLOBALS['cfg']['MaxRows'];
609 $pageNow = ($pos / $max_rows) + 1;
610 $nbTotalPage = ceil($total_rows / $max_rows);
611 $table_navigation_html = '<table style="display:inline-block;max-width:49%" '
612 . 'class="navigation nospacing nopadding">'
613 . '<tr>'
614 . '<td class="navigation_separator"></td>';
615 if ($pos - $max_rows >= 0) {
616 $table_navigation_html .= '<td>'
617 . '<form action="db_central_columns.php" method="post">'
618 . URL::getHiddenInputs(
621 . '<input type="hidden" name="pos" value="' . ($pos - $max_rows) . '" />'
622 . '<input type="hidden" name="total_rows" value="' . $total_rows . '"/>'
623 . '<input type="submit" name="navig"'
624 . ' class="ajax" '
625 . 'value="&lt" />'
626 . '</form>'
627 . '</td>';
629 if ($nbTotalPage > 1) {
630 $table_navigation_html .= '<td>';
631 $table_navigation_html .= '<form action="db_central_columns.php'
632 . '" method="post">'
633 . URL::getHiddenInputs(
636 . '<input type="hidden" name="total_rows" value="' . $total_rows . '"/>';
637 $table_navigation_html .= Util::pageselector(
638 'pos', $max_rows, $pageNow, $nbTotalPage
640 $table_navigation_html .= '</form>'
641 . '</td>';
643 if ($pos + $max_rows < $total_rows) {
644 $table_navigation_html .= '<td>'
645 . '<form action="db_central_columns.php" method="post">'
646 . URL::getHiddenInputs(
649 . '<input type="hidden" name="pos" value="' . ($pos + $max_rows) . '" />'
650 . '<input type="hidden" name="total_rows" value="' . $total_rows . '"/>'
651 . '<input type="submit" name="navig"'
652 . ' class="ajax" '
653 . 'value="&gt" />'
654 . '</form>'
655 . '</td>';
657 $table_navigation_html .= '</form>'
658 . '</td>'
659 . '<td class="navigation_separator"></td>'
660 . '<td>'
661 . '<span>' . __('Filter rows') . ':</span>'
662 . '<input type="text" class="filter_rows" placeholder="'
663 . __('Search this table') . '">'
664 . '</td>'
665 . '<td class="navigation_separator"></td>'
666 . '</tr>'
667 . '</table>';
669 return $table_navigation_html;
673 * function generate and return the table header for central columns page
675 * @param string $class styling class of 'th' elements
676 * @param string $title title of the 'th' elements
677 * @param integer $actionCount number of actions
679 * @return string html for table header in central columns view/edit page
681 function PMA_getCentralColumnsTableHeader($class='', $title='', $actionCount=0)
683 $action = '';
684 if ($actionCount > 0) {
685 $action .= '<th class="column_action" colspan="' . $actionCount . '">'
686 . __('Action') . '</th>';
688 $tableheader = '<thead>';
689 $tableheader .= '<tr>'
690 . '<th class="' . $class . '"></th>'
691 . '<th class="" style="display:none"></th>'
692 . $action
693 . '<th class="' . $class . '" title="' . $title . '" data-column="name">'
694 . __('Name') . '<div class="sorticon"></div></th>'
695 . '<th class="' . $class . '" title="' . $title . '" data-column="type">'
696 . __('Type') . '<div class="sorticon"></div></th>'
697 . '<th class="' . $class . '" title="' . $title . '" data-column="length">'
698 . __('Length/Values') . '<div class="sorticon"></div></th>'
699 . '<th class="' . $class . '" title="' . $title . '" data-column="default">'
700 . __('Default') . '<div class="sorticon"></div></th>'
701 . '<th class="' . $class . '" title="' . $title . '" data-column="collation"'
702 . '>' . __('Collation') . '<div class="sorticon"></div></th>'
703 . '<th class="' . $class . '" title="' . $title
704 . '" data-column="attribute">'
705 . __('Attribute') . '<div class="sorticon"></div></th>'
706 . '<th class="' . $class . '" title="' . $title . '" data-column="isnull">'
707 . __('Null') . '<div class="sorticon"></div></th>'
708 . '<th class="' . $class . '" title="' . $title . '" data-column="extra">'
709 . __('A_I') . '<div class="sorticon"></div></th>'
710 . '</tr>';
711 $tableheader .= '</thead>';
712 return $tableheader;
716 * Function generate and return the table header for
717 * multiple edit central columns page
719 * @param array $header_cells headers list
721 * @return string html for table header in central columns multi edit page
723 function PMA_getCentralColumnsEditTableHeader($header_cells)
725 $html = '<table id="table_columns" class="noclick"'
726 . ' style="min-width: 100%;">';
727 $html .= '<caption class="tblHeaders">' . __('Structure');
728 $html .= '<tr>';
729 foreach ($header_cells as $header_val) {
730 $html .= '<th>' . $header_val . '</th>';
732 $html .= '</tr>';
733 return $html;
737 * build the dropdown select html for tables of given database
739 * @param string $db current database
741 * @return string html dropdown for selecting table
743 function PMA_getHTMLforTableDropdown($db)
745 $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
746 $tables = $GLOBALS['dbi']->getTables($db, $GLOBALS['userlink']);
747 $selectHtml = '<select name="table-select" id="table-select">'
748 . '<option value="" disabled="disabled" selected="selected">'
749 . __('Select a table') . '</option>';
750 foreach ($tables as $table) {
751 $selectHtml .= '<option value="' . htmlspecialchars($table) . '">'
752 . htmlspecialchars($table) . '</option>';
754 $selectHtml .= '</select>';
755 return $selectHtml;
759 * build dropdown select html to select column in selected table,
760 * include only columns which are not already in central list
762 * @param string $db current database to which selected table belongs
763 * @param string $selected_tbl selected table
765 * @return string html to select column
767 function PMA_getHTMLforColumnDropdown($db, $selected_tbl)
769 $existing_cols = PMA_getCentralColumnsFromTable($db, $selected_tbl);
770 $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
771 $columns = (array) $GLOBALS['dbi']->getColumnNames(
772 $db, $selected_tbl, $GLOBALS['userlink']
774 $selectColHtml = "";
775 foreach ($columns as $column) {
776 if (!in_array($column, $existing_cols)) {
777 $selectColHtml .= '<option value="' . htmlspecialchars($column) . '">'
778 . htmlspecialchars($column)
779 . '</option>';
782 return $selectColHtml;
786 * html to display the form that let user to add a column on Central columns page
788 * @param int $total_rows total number of rows in complete result set
789 * @param int $pos offset of first result with complete result set
790 * @param string $db current database
792 * @return string html to add a column in the central list
794 function PMA_getHTMLforAddCentralColumn($total_rows, $pos, $db)
796 $columnAdd = '<table style="display:inline-block;margin-left:1%;max-width:50%" '
797 . 'class="navigation nospacing nopadding">'
798 . '<tr>'
799 . '<td class="navigation_separator"></td>'
800 . '<td style="padding:1.5% 0em">'
801 . Util::getIcon(
802 'centralColumns_add.png',
803 __('Add column')
805 . '<form id="add_column" action="db_central_columns.php" method="post">'
806 . URL::getHiddenInputs(
809 . '<input type="hidden" name="add_column" value="add">'
810 . '<input type="hidden" name="pos" value="' . $pos . '" />'
811 . '<input type="hidden" name="total_rows" value="' . $total_rows . '"/>'
812 . PMA_getHTMLforTableDropdown($db)
813 . '<select name="column-select" id="column-select">'
814 . '<option value="" selected="selected">'
815 . __('Select a column.') . '</option>'
816 . '</select></form>'
817 . '</td>'
818 . '<td class="navigation_separator"></td>'
819 . '</tr>'
820 . '</table>';
822 return $columnAdd;
826 * build html for a row in central columns table
828 * @param array $row array contains complete information of
829 * a particular row of central list table
830 * @param int $row_num position the row in the table
831 * @param string $db current database
833 * @return string html of a particular row in the central columns table.
835 function PMA_getHTMLforCentralColumnsTableRow($row, $row_num, $db)
837 $tableHtml = '<tr data-rownum="' . $row_num . '" id="f_' . $row_num . '">'
838 . URL::getHiddenInputs(
841 . '<input type="hidden" name="edit_save" value="save">'
842 . '<td class="nowrap">'
843 . '<input type="checkbox" class="checkall" name="selected_fld[]" '
844 . 'value="' . htmlspecialchars($row['col_name']) . '" '
845 . 'id="checkbox_row_' . $row_num . '"/>'
846 . '</td>'
847 . '<td id="edit_' . $row_num . '" class="edit center">'
848 . '<a href="#">' . Util::getIcon('b_edit.png', __('Edit')) . '</a></td>'
849 . '<td class="del_row" data-rownum = "' . $row_num . '">'
850 . '<a hrf="#">' . Util::getIcon('b_drop.png', __('Delete')) . '</a>'
851 . '<input type="submit" data-rownum = "' . $row_num . '"'
852 . ' class="edit_cancel_form" value="Cancel"></td>'
853 . '<td id="save_' . $row_num . '" style="display:none">'
854 . '<input type="submit" data-rownum = "' . $row_num . '"'
855 . ' class="edit_save_form" value="Save"></td>';
857 $tableHtml .=
858 '<td name="col_name" class="nowrap">'
859 . '<span>' . htmlspecialchars($row['col_name']) . '</span>'
860 . '<input name="orig_col_name" type="hidden" '
861 . 'value="' . htmlspecialchars($row['col_name']) . '">'
862 . PMA\libraries\Template::get('columns_definitions/column_name')
863 ->render(
864 array(
865 'columnNumber' => $row_num,
866 'ci' => 0,
867 'ci_offset' => 0,
868 'columnMeta' => array(
869 'Field'=>$row['col_name']
871 'cfgRelation' => array(
872 'centralcolumnswork' => false
876 . '</td>';
877 $tableHtml .=
878 '<td name = "col_type" class="nowrap"><span>'
879 . htmlspecialchars($row['col_type']) . '</span>'
880 . PMA\libraries\Template::get('columns_definitions/column_type')
881 ->render(
882 array(
883 'columnNumber' => $row_num,
884 'ci' => 1,
885 'ci_offset' => 0,
886 'type_upper' => mb_strtoupper($row['col_type']),
887 'columnMeta' => array()
890 . '</td>';
891 $tableHtml .=
892 '<td class="nowrap" name="col_length">'
893 . '<span>' . ($row['col_length']?htmlspecialchars($row['col_length']):"")
894 . '</span>'
895 . PMA\libraries\Template::get('columns_definitions/column_length')->render(
896 array(
897 'columnNumber' => $row_num,
898 'ci' => 2,
899 'ci_offset' => 0,
900 'length_values_input_size' => 8,
901 'length_to_display' => $row['col_length']
904 . '</td>';
906 $meta = array();
907 if (!isset($row['col_default']) || $row['col_default'] == '') {
908 $meta['DefaultType'] = 'NONE';
909 } else {
910 if ($row['col_default'] == 'CURRENT_TIMESTAMP'
911 || $row['col_default'] == 'NULL'
913 $meta['DefaultType'] = $row['col_default'];
914 } else {
915 $meta['DefaultType'] = 'USER_DEFINED';
916 $meta['DefaultValue'] = $row['col_default'];
919 $tableHtml .=
920 '<td class="nowrap" name="col_default"><span>' . (isset($row['col_default'])
921 ? htmlspecialchars($row['col_default']) : 'None')
922 . '</span>'
923 . PMA\libraries\Template::get('columns_definitions/column_default')
924 ->render(
925 array(
926 'columnNumber' => $row_num,
927 'ci' => 3,
928 'ci_offset' => 0,
929 'type_upper' => mb_strtoupper($row['col_type']),
930 'columnMeta' => $meta
933 . '</td>';
935 $tableHtml .=
936 '<td name="collation" class="nowrap">'
937 . '<span>' . htmlspecialchars($row['col_collation']) . '</span>'
938 . Charsets::getCollationDropdownBox(
939 'field_collation[' . $row_num . ']',
940 'field_' . $row_num . '_4', $row['col_collation'], false
942 . '</td>';
943 $tableHtml .=
944 '<td class="nowrap" name="col_attribute">'
945 . '<span>' .
946 ($row['col_attribute']
947 ? htmlspecialchars($row['col_attribute']) : "" )
948 . '</span>'
949 . PMA\libraries\Template::get('columns_definitions/column_attribute')
950 ->render(
951 array(
952 'columnNumber' => $row_num,
953 'ci' => 5,
954 'ci_offset' => 0,
955 'extracted_columnspec' => array(),
956 'columnMeta' => $row['col_attribute'],
957 'submit_attribute' => false,
960 . '</td>';
961 $tableHtml .=
962 '<td class="nowrap" name="col_isNull">'
963 . '<span>' . ($row['col_isNull'] ? __('Yes') : __('No'))
964 . '</span>'
965 . PMA\libraries\Template::get('columns_definitions/column_null')
966 ->render(
967 array(
968 'columnNumber' => $row_num,
969 'ci' => 6,
970 'ci_offset' => 0,
971 'columnMeta' => array(
972 'Null' => $row['col_isNull']
976 . '</td>';
978 $tableHtml .=
979 '<td class="nowrap" name="col_extra"><span>'
980 . htmlspecialchars($row['col_extra']) . '</span>'
981 . PMA\libraries\Template::get('columns_definitions/column_extra')->render(
982 array(
983 'columnNumber' => $row_num,
984 'ci' => 7,
985 'ci_offset' => 0,
986 'columnMeta' => array('Extra'=>$row['col_extra'])
989 . '</td>';
991 $tableHtml .= '</tr>';
993 return $tableHtml;
997 * build html for editing a row in central columns table
999 * @param array $row array contains complete information of
1000 * a particular row of central list table
1001 * @param int $row_num position the row in the table
1003 * @return string html of a particular row in the central columns table.
1005 function PMA_getHTMLforCentralColumnsEditTableRow($row, $row_num)
1007 $tableHtml = '<tr>'
1008 . '<input name="orig_col_name[' . $row_num . ']" type="hidden" '
1009 . 'value="' . htmlspecialchars($row['col_name']) . '">'
1010 . '<td name="col_name" class="nowrap">'
1011 . PMA\libraries\Template::get('columns_definitions/column_name')
1012 ->render(
1013 array(
1014 'columnNumber' => $row_num,
1015 'ci' => 0,
1016 'ci_offset' => 0,
1017 'columnMeta' => array(
1018 'Field' => $row['col_name']
1020 'cfgRelation' => array(
1021 'centralcolumnswork' => false
1025 . '</td>';
1026 $tableHtml .=
1027 '<td name = "col_type" class="nowrap">'
1028 . PMA\libraries\Template::get('columns_definitions/column_type')
1029 ->render(
1030 array(
1031 'columnNumber' => $row_num,
1032 'ci' => 1,
1033 'ci_offset' => 0,
1034 'type_upper' => mb_strtoupper($row['col_type']),
1035 'columnMeta' => array()
1038 . '</td>';
1039 $tableHtml .=
1040 '<td class="nowrap" name="col_length">'
1041 . PMA\libraries\Template::get('columns_definitions/column_length')->render(
1042 array(
1043 'columnNumber' => $row_num,
1044 'ci' => 2,
1045 'ci_offset' => 0,
1046 'length_values_input_size' => 8,
1047 'length_to_display' => $row['col_length']
1050 . '</td>';
1051 $meta = array();
1052 if (!isset($row['col_default']) || $row['col_default'] == '') {
1053 $meta['DefaultType'] = 'NONE';
1054 } else {
1055 if ($row['col_default'] == 'CURRENT_TIMESTAMP'
1056 || $row['col_default'] == 'NULL'
1058 $meta['DefaultType'] = $row['col_default'];
1059 } else {
1060 $meta['DefaultType'] = 'USER_DEFINED';
1061 $meta['DefaultValue'] = $row['col_default'];
1064 $tableHtml .=
1065 '<td class="nowrap" name="col_default">'
1066 . PMA\libraries\Template::get('columns_definitions/column_default')
1067 ->render(
1068 array(
1069 'columnNumber' => $row_num,
1070 'ci' => 3,
1071 'ci_offset' => 0,
1072 'type_upper' => mb_strtoupper($row['col_default']),
1073 'columnMeta' => $meta
1076 . '</td>';
1077 $tableHtml .=
1078 '<td name="collation" class="nowrap">'
1079 . Charsets::getCollationDropdownBox(
1080 'field_collation[' . $row_num . ']',
1081 'field_' . $row_num . '_4', $row['col_collation'], false
1083 . '</td>';
1084 $tableHtml .=
1085 '<td class="nowrap" name="col_attribute">'
1086 . PMA\libraries\Template::get('columns_definitions/column_attribute')
1087 ->render(
1088 array(
1089 'columnNumber' => $row_num,
1090 'ci' => 5,
1091 'ci_offset' => 0,
1092 'extracted_columnspec' => array(
1093 'attribute' => $row['col_attribute']
1095 'columnMeta' => array(),
1096 'submit_attribute' => false,
1099 . '</td>';
1100 $tableHtml .=
1101 '<td class="nowrap" name="col_isNull">'
1102 . PMA\libraries\Template::get('columns_definitions/column_null')
1103 ->render(
1104 array(
1105 'columnNumber' => $row_num,
1106 'ci' => 6,
1107 'ci_offset' => 0,
1108 'columnMeta' => array(
1109 'Null' => $row['col_isNull']
1113 . '</td>';
1115 $tableHtml .=
1116 '<td class="nowrap" name="col_extra">'
1117 . PMA\libraries\Template::get('columns_definitions/column_extra')->render(
1118 array(
1119 'columnNumber' => $row_num,
1120 'ci' => 7,
1121 'ci_offset' => 0,
1122 'columnMeta' => array('Extra' => $row['col_extra'])
1125 . '</td>';
1126 $tableHtml .= '</tr>';
1127 return $tableHtml;
1131 * get the list of columns in given database excluding
1132 * the columns present in current table
1134 * @param string $db selected database
1135 * @param string $table current table name
1137 * @return string encoded list of columns present in central list for the given
1138 * database
1140 function PMA_getCentralColumnsListRaw($db, $table)
1142 $cfgCentralColumns = PMA_centralColumnsGetParams();
1143 if (empty($cfgCentralColumns)) {
1144 return json_encode(array());
1146 $centralTable = $cfgCentralColumns['table'];
1147 if (empty($table) || $table == '') {
1148 $query = 'SELECT * FROM ' . Util::backquote($centralTable) . ' '
1149 . 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\';';
1150 } else {
1151 $GLOBALS['dbi']->selectDb($db, $GLOBALS['userlink']);
1152 $columns = (array) $GLOBALS['dbi']->getColumnNames(
1153 $db, $table, $GLOBALS['userlink']
1155 $cols = '';
1156 foreach ($columns as $col_select) {
1157 $cols .= '\'' . $GLOBALS['dbi']->escapeString($col_select) . '\',';
1159 $cols = trim($cols, ',');
1160 $query = 'SELECT * FROM ' . Util::backquote($centralTable) . ' '
1161 . 'WHERE db_name = \'' . $GLOBALS['dbi']->escapeString($db) . '\'';
1162 if ($cols) {
1163 $query .= ' AND col_name NOT IN (' . $cols . ')';
1165 $query .= ';';
1167 $GLOBALS['dbi']->selectDb($cfgCentralColumns['db'], $GLOBALS['controllink']);
1168 $columns_list = (array)$GLOBALS['dbi']->fetchResult(
1169 $query, null, null, $GLOBALS['controllink']
1171 PMA_handleColumnExtra($columns_list);
1172 return json_encode($columns_list);
1176 * Get HTML for "check all" check box with "with selected" dropdown
1178 * @param string $pmaThemeImage pma theme image url
1179 * @param string $text_dir url for text directory
1181 * @return string $html_output
1183 function PMA_getCentralColumnsTableFooter($pmaThemeImage, $text_dir)
1185 $html_output = PMA\libraries\Template::get('select_all')
1186 ->render(
1187 array(
1188 'pmaThemeImage' => $pmaThemeImage,
1189 'text_dir' => $text_dir,
1190 'formName' => 'tableslistcontainer',
1193 $html_output .= Util::getButtonOrImage(
1194 'edit_central_columns', 'mult_submit change_central_columns',
1195 __('Edit'), 'b_edit.png', 'edit central columns'
1197 $html_output .= Util::getButtonOrImage(
1198 'delete_central_columns', 'mult_submit',
1199 __('Delete'), 'b_drop.png',
1200 'remove_from_central_columns'
1202 return $html_output;
1206 * function generate and return the table footer for
1207 * multiple edit central columns page
1209 * @return string html for table footer in central columns multi edit page
1211 function PMA_getCentralColumnsEditTableFooter()
1213 $html_output = '<fieldset class="tblFooters">'
1214 . '<input type="submit" '
1215 . 'name="save_multi_central_column_edit" value="' . __('Save') . '" />'
1216 . '</fieldset>';
1217 return $html_output;
1220 * Column `col_extra` is used to store both extra and attributes for a column.
1221 * This method separates them.
1223 * @param array &$columns_list columns list
1225 * @return void
1227 function PMA_handleColumnExtra(&$columns_list)
1229 foreach ($columns_list as &$row) {
1230 $vals = explode(',', $row['col_extra']);
1232 if (in_array('BINARY', $vals)) {
1233 $row['col_attribute'] = 'BINARY';
1234 } elseif (in_array('UNSIGNED', $vals)) {
1235 $row['col_attribute'] = 'UNSIGNED';
1236 } elseif (in_array('UNSIGNED ZEROFILL', $vals)) {
1237 $row['col_attribute'] = 'UNSIGNED ZEROFILL';
1238 } elseif (in_array('on update CURRENT_TIMESTAMP', $vals)) {
1239 $row['col_attribute'] = 'on update CURRENT_TIMESTAMP';
1240 } else {
1241 $row['col_attribute'] = '';
1244 if (in_array('auto_increment', $vals)) {
1245 $row['col_extra'] = 'auto_increment';
1246 } else {
1247 $row['col_extra'] = '';
1253 * build html for adding a new user defined column to central list
1255 * @param string $db current database
1257 * @return string html of the form to let user add a new user defined column to the
1258 * list
1260 function PMA_getHTMLforAddNewColumn($db)
1262 $addNewColumn = '<div id="add_col_div" class="topmargin"><a href="#">'
1263 . '<span>+</span> ' . __('Add new column') . '</a>'
1264 . '<form id="add_new" style="min-width:100%;display:none" '
1265 . 'method="post" action="db_central_columns.php">'
1266 . URL::getHiddenInputs(
1269 . '<input type="hidden" name="add_new_column" value="add_new_column">'
1270 . '<table>';
1271 $addNewColumn .= PMA_getCentralColumnsTableHeader();
1272 $addNewColumn .= '<tr>'
1273 . '<td></td>'
1274 . '<td name="col_name" class="nowrap">'
1275 . PMA\libraries\Template::get('columns_definitions/column_name')
1276 ->render(
1277 array(
1278 'columnNumber' => 0,
1279 'ci' => 0,
1280 'ci_offset' => 0,
1281 'columnMeta' => array(),
1282 'cfgRelation' => array(
1283 'centralcolumnswork' => false
1287 . '</td>'
1288 . '<td name = "col_type" class="nowrap">'
1289 . PMA\libraries\Template::get('columns_definitions/column_type')
1290 ->render(
1291 array(
1292 'columnNumber' => 0,
1293 'ci' => 1,
1294 'ci_offset' => 0,
1295 'type_upper' => '',
1296 'columnMeta' => array()
1299 . '</td>'
1300 . '<td class="nowrap" name="col_length">'
1301 . PMA\libraries\Template::get('columns_definitions/column_length')->render(
1302 array(
1303 'columnNumber' => 0,
1304 'ci' => 2,
1305 'ci_offset' => 0,
1306 'length_values_input_size' => 8,
1307 'length_to_display' => ''
1310 . '</td>'
1311 . '<td class="nowrap" name="col_default">'
1312 . PMA\libraries\Template::get('columns_definitions/column_default')
1313 ->render(
1314 array(
1315 'columnNumber' => 0,
1316 'ci' => 3,
1317 'ci_offset' => 0,
1318 'type_upper' => '',
1319 'columnMeta' => array()
1322 . '</td>'
1323 . '<td name="collation" class="nowrap">'
1324 . Charsets::getCollationDropdownBox(
1325 'field_collation[0]',
1326 'field_0_4', null, false
1328 . '</td>'
1329 . '<td class="nowrap" name="col_attribute">'
1330 . PMA\libraries\Template::get('columns_definitions/column_attribute')
1331 ->render(
1332 array(
1333 'columnNumber' => 0,
1334 'ci' => 5,
1335 'ci_offset' => 0,
1336 'extracted_columnspec' => array(),
1337 'columnMeta' => array(),
1338 'submit_attribute' => false,
1341 . '</td>'
1342 . '<td class="nowrap" name="col_isNull">'
1343 . PMA\libraries\Template::get('columns_definitions/column_null')
1344 ->render(
1345 array(
1346 'columnNumber' => 0,
1347 'ci' => 6,
1348 'ci_offset' => 0,
1349 'columnMeta' => array()
1352 . '</td>'
1353 . '<td class="nowrap" name="col_extra">'
1354 . PMA\libraries\Template::get('columns_definitions/column_extra')->render(
1355 array(
1356 'columnNumber' => 0,
1357 'ci' => 7,
1358 'ci_offset' => 0,
1359 'columnMeta' => array()
1362 . '</td>'
1363 . ' <td>'
1364 . '<input id="add_column_save" type="submit" '
1365 . ' value="Save"/></td>'
1366 . '</tr>';
1367 $addNewColumn .= '</table></form></div>';
1368 return $addNewColumn;
1372 * Get HTML for editing page central columns
1374 * @param array $selected_fld Array containing the selected fields
1375 * @param string $selected_db String containing the name of database
1377 * @return string HTML for complete editing page for central columns
1379 function PMA_getHTMLforEditingPage($selected_fld,$selected_db)
1381 $html = '<form id="multi_edit_central_columns">';
1382 $header_cells = array(
1383 __('Name'), __('Type'), __('Length/Values'), __('Default'),
1384 __('Collation'), __('Attributes'), __('Null'), __('A_I')
1386 $html .= PMA_getCentralColumnsEditTableHeader($header_cells);
1387 $selected_fld_safe = array();
1388 foreach ($selected_fld as $key) {
1389 $selected_fld_safe[] = $GLOBALS['dbi']->escapeString($key);
1391 $columns_list = implode("','", $selected_fld_safe);
1392 $columns_list = "'" . $columns_list . "'";
1393 $list_detail_cols = PMA_findExistingColNames($selected_db, $columns_list, true);
1394 $row_num = 0;
1395 foreach ($list_detail_cols as $row) {
1396 $tableHtmlRow = PMA_getHTMLforCentralColumnsEditTableRow(
1397 $row, $row_num
1399 $html .= $tableHtmlRow;
1400 $row_num++;
1402 $html .= '</table>';
1403 $html .= PMA_getCentralColumnsEditTableFooter();
1404 $html .= '</form>';
1405 return $html;