2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Functions for displaying user preferences pages
10 use PhpMyAdmin\Charsets
;
11 use PhpMyAdmin\DatabaseInterface
;
12 use PhpMyAdmin\Message
;
13 use PhpMyAdmin\Relation
;
14 use PhpMyAdmin\Template
;
19 * PhpMyAdmin\CentralColumns class
26 * DatabaseInterface instance
28 * @var DatabaseInterface
40 * Number of rows displayed when browsing a result set
47 * Which editor should be used for CHAR/VARCHAR fields
54 * Disable use of INFORMATION_SCHEMA
68 * @param DatabaseInterface $dbi DatabaseInterface instance
70 public function __construct(DatabaseInterface
$dbi)
74 $this->user
= $GLOBALS['cfg']['Server']['user'];
75 $this->maxRows
= (int) $GLOBALS['cfg']['MaxRows'];
76 $this->charEditing
= $GLOBALS['cfg']['CharEditing'];
77 $this->disableIs
= (bool) $GLOBALS['cfg']['Server']['DisableIS'];
79 $this->relation
= new Relation();
83 * Defines the central_columns parameters for the current user
85 * @return array the central_columns parameters for the current user
88 public function getParams()
90 static $cfgCentralColumns = null;
92 if (null !== $cfgCentralColumns) {
93 return $cfgCentralColumns;
96 $cfgRelation = $this->relation
->getRelationsParam();
98 if ($cfgRelation['centralcolumnswork']) {
99 $cfgCentralColumns = array(
100 'user' => $this->user
,
101 'db' => $cfgRelation['db'],
102 'table' => $cfgRelation['central_columns'],
105 $cfgCentralColumns = false;
108 return $cfgCentralColumns;
112 * get $num columns of given database from central columns list
113 * starting at offset $from
115 * @param string $db selected database
116 * @param int $from starting offset of first result
117 * @param int $num maximum number of results to return
119 * @return array list of $num columns present in central columns list
120 * starting at offset $from for the given database
122 public function getColumnsList($db, $from = 0, $num = 25)
124 $cfgCentralColumns = $this->getParams();
125 if (empty($cfgCentralColumns)) {
128 $pmadb = $cfgCentralColumns['db'];
129 $this->dbi
->selectDb($pmadb, DatabaseInterface
::CONNECT_CONTROL
);
130 $central_list_table = $cfgCentralColumns['table'];
131 //get current values of $db from central column list
133 $query = 'SELECT * FROM ' . Util
::backquote($central_list_table) . ' '
134 . 'WHERE db_name = \'' . $this->dbi
->escapeString($db) . '\';';
136 $query = 'SELECT * FROM ' . Util
::backquote($central_list_table) . ' '
137 . 'WHERE db_name = \'' . $this->dbi
->escapeString($db) . '\' '
138 . 'LIMIT ' . $from . ', ' . $num . ';';
140 $has_list = (array) $this->dbi
->fetchResult(
141 $query, null, null, DatabaseInterface
::CONNECT_CONTROL
143 $this->handleColumnExtra($has_list);
148 * Get the number of columns present in central list for given db
150 * @param string $db current database
152 * @return int number of columns in central list of columns for $db
154 public function getCount($db)
156 $cfgCentralColumns = $this->getParams();
157 if (empty($cfgCentralColumns)) {
160 $pmadb = $cfgCentralColumns['db'];
161 $this->dbi
->selectDb($pmadb, DatabaseInterface
::CONNECT_CONTROL
);
162 $central_list_table = $cfgCentralColumns['table'];
163 $query = 'SELECT count(db_name) FROM ' .
164 Util
::backquote($central_list_table) . ' '
165 . 'WHERE db_name = \'' . $this->dbi
->escapeString($db) . '\';';
166 $res = $this->dbi
->fetchResult(
167 $query, null, null, DatabaseInterface
::CONNECT_CONTROL
169 if (isset($res[0])) {
177 * return the existing columns in central list among the given list of columns
179 * @param string $db the selected database
180 * @param string $cols comma separated list of given columns
181 * @param boolean $allFields set if need all the fields of existing columns,
182 * otherwise only column_name is returned
184 * @return array list of columns in central columns among given set of columns
186 private function findExistingColNames(
191 $cfgCentralColumns = $this->getParams();
192 if (empty($cfgCentralColumns)) {
195 $pmadb = $cfgCentralColumns['db'];
196 $this->dbi
->selectDb($pmadb, DatabaseInterface
::CONNECT_CONTROL
);
197 $central_list_table = $cfgCentralColumns['table'];
199 $query = 'SELECT * FROM ' . Util
::backquote($central_list_table) . ' '
200 . 'WHERE db_name = \'' . $this->dbi
->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
201 $has_list = (array) $this->dbi
->fetchResult(
202 $query, null, null, DatabaseInterface
::CONNECT_CONTROL
204 $this->handleColumnExtra($has_list);
206 $query = 'SELECT col_name FROM '
207 . Util
::backquote($central_list_table) . ' '
208 . 'WHERE db_name = \'' . $this->dbi
->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
209 $has_list = (array) $this->dbi
->fetchResult(
210 $query, null, null, DatabaseInterface
::CONNECT_CONTROL
218 * return error message to be displayed if central columns
219 * configuration storage is not completely configured
223 private function configErrorMessage()
225 return Message
::error(
227 'The configuration storage is not ready for the central list'
228 . ' of columns feature.'
234 * build the insert query for central columns list given PMA storage
235 * db, central_columns table, column name and corresponding definition to be added
237 * @param string $column column to add into central list
238 * @param array $def list of attributes of the column being added
239 * @param string $db PMA configuration storage database name
240 * @param string $central_list_table central columns configuration storage table name
242 * @return string query string to insert the given column
243 * with definition into central list
245 private function getInsertQuery(
254 if (isset($def['Type'])) {
255 $extracted_columnspec = Util
::extractColumnSpec($def['Type']);
256 $attribute = trim($extracted_columnspec[ 'attribute']);
257 $type = $extracted_columnspec['type'];
258 $length = $extracted_columnspec['spec_in_brackets'];
260 if (isset($def['Attribute'])) {
261 $attribute = $def['Attribute'];
263 $collation = isset($def['Collation'])?
$def['Collation']:"";
264 $isNull = ($def['Null'] == "NO")?
0:1;
265 $extra = isset($def['Extra'])?
$def['Extra']:"";
266 $default = isset($def['Default'])?
$def['Default']:"";
267 $insQuery = 'INSERT INTO '
268 . Util
::backquote($central_list_table) . ' '
269 . 'VALUES ( \'' . $this->dbi
->escapeString($db) . '\' ,'
270 . '\'' . $this->dbi
->escapeString($column) . '\',\''
271 . $this->dbi
->escapeString($type) . '\','
272 . '\'' . $this->dbi
->escapeString($length) . '\',\''
273 . $this->dbi
->escapeString($collation) . '\','
274 . '\'' . $this->dbi
->escapeString($isNull) . '\','
275 . '\'' . implode(',', array($extra, $attribute))
276 . '\',\'' . $this->dbi
->escapeString($default) . '\');';
281 * If $isTable is true then unique columns from given tables as $field_select
282 * are added to central list otherwise the $field_select is considered as
283 * list of columns and these columns are added to central list if not already added
285 * @param array $field_select if $isTable is true selected tables list
286 * otherwise selected columns list
287 * @param bool $isTable if passed array is of tables or columns
288 * @param string $table if $isTable is false, then table name to
289 * which columns belong
291 * @return true|PhpMyAdmin\Message
293 public function syncUniqueColumns(
298 $cfgCentralColumns = $this->getParams();
299 if (empty($cfgCentralColumns)) {
300 return $this->configErrorMessage();
303 $pmadb = $cfgCentralColumns['db'];
304 $central_list_table = $cfgCentralColumns['table'];
305 $this->dbi
->selectDb($db);
306 $existingCols = array();
312 foreach ($field_select as $table) {
313 $fields[$table] = (array) $this->dbi
->getColumns(
314 $db, $table, null, true
316 foreach ($fields[$table] as $field => $def) {
317 $cols .= "'" . $this->dbi
->escapeString($field) . "',";
321 $has_list = $this->findExistingColNames($db, trim($cols, ','));
322 foreach ($field_select as $table) {
323 foreach ($fields[$table] as $field => $def) {
324 if (!in_array($field, $has_list)) {
325 $has_list[] = $field;
326 $insQuery[] = $this->getInsertQuery(
327 $field, $def, $db, $central_list_table
330 $existingCols[] = "'" . $field . "'";
335 if ($table === null) {
336 $table = $_POST['table'];
338 foreach ($field_select as $column) {
339 $cols .= "'" . $this->dbi
->escapeString($column) . "',";
341 $has_list = $this->findExistingColNames($db, trim($cols, ','));
342 foreach ($field_select as $column) {
343 if (!in_array($column, $has_list)) {
344 $has_list[] = $column;
345 $field = (array) $this->dbi
->getColumns(
346 $db, $table, $column,
349 $insQuery[] = $this->getInsertQuery(
350 $column, $field, $db, $central_list_table
353 $existingCols[] = "'" . $column . "'";
357 if (! empty($existingCols)) {
358 $existingCols = implode(",", array_unique($existingCols));
359 $message = Message
::notice(
362 'Could not add %1$s as they already exist in central list!'
363 ), htmlspecialchars($existingCols)
366 $message->addMessage(
368 "Please remove them first "
369 . "from central list if you want to update above columns"
373 $this->dbi
->selectDb($pmadb, DatabaseInterface
::CONNECT_CONTROL
);
374 if (! empty($insQuery)) {
375 foreach ($insQuery as $query) {
376 if (!$this->dbi
->tryQuery($query, DatabaseInterface
::CONNECT_CONTROL
)) {
377 $message = Message
::error(__('Could not add columns!'));
378 $message->addMessage(
380 $this->dbi
->getError(DatabaseInterface
::CONNECT_CONTROL
)
391 * if $isTable is true it removes all columns of given tables as $field_select from
392 * central columns list otherwise $field_select is columns list and it removes
393 * given columns if present in central list
395 * @param array $field_select if $isTable selected list of tables otherwise
396 * selected list of columns to remove from central list
397 * @param bool $isTable if passed array is of tables or columns
399 * @return true|PhpMyAdmin\Message
401 public function deleteColumnsFromList(
405 $cfgCentralColumns = $this->getParams();
406 if (empty($cfgCentralColumns)) {
407 return $this->configErrorMessage();
410 $pmadb = $cfgCentralColumns['db'];
411 $central_list_table = $cfgCentralColumns['table'];
412 $this->dbi
->selectDb($db);
414 $colNotExist = array();
418 foreach ($field_select as $table) {
419 $fields[$table] = (array) $this->dbi
->getColumnNames(
422 foreach ($fields[$table] as $col_select) {
423 $cols .= '\'' . $this->dbi
->escapeString($col_select) . '\',';
426 $cols = trim($cols, ',');
427 $has_list = $this->findExistingColNames($db, $cols);
428 foreach ($field_select as $table) {
429 foreach ($fields[$table] as $column) {
430 if (!in_array($column, $has_list)) {
431 $colNotExist[] = "'" . $column . "'";
438 foreach ($field_select as $col_select) {
439 $cols .= '\'' . $this->dbi
->escapeString($col_select) . '\',';
441 $cols = trim($cols, ',');
442 $has_list = $this->findExistingColNames($db, $cols);
443 foreach ($field_select as $column) {
444 if (!in_array($column, $has_list)) {
445 $colNotExist[] = "'" . $column . "'";
449 if (!empty($colNotExist)) {
450 $colNotExist = implode(",", array_unique($colNotExist));
451 $message = Message
::notice(
454 'Couldn\'t remove Column(s) %1$s '
455 . 'as they don\'t exist in central columns list!'
456 ), htmlspecialchars($colNotExist)
460 $this->dbi
->selectDb($pmadb, DatabaseInterface
::CONNECT_CONTROL
);
462 $query = 'DELETE FROM ' . Util
::backquote($central_list_table) . ' '
463 . 'WHERE db_name = \'' . $this->dbi
->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
465 if (!$this->dbi
->tryQuery($query, DatabaseInterface
::CONNECT_CONTROL
)) {
466 $message = Message
::error(__('Could not remove columns!'));
467 $message->addHtml('<br />' . htmlspecialchars($cols) . '<br />');
468 $message->addMessage(
470 $this->dbi
->getError(DatabaseInterface
::CONNECT_CONTROL
)
478 * Make the columns of given tables consistent with central list of columns.
479 * Updates only those columns which are not being referenced.
481 * @param string $db current database
482 * @param array $selected_tables list of selected tables.
484 * @return true|PhpMyAdmin\Message
486 public function makeConsistentWithList(
488 array $selected_tables
491 foreach ($selected_tables as $table) {
492 $query = 'ALTER TABLE ' . Util
::backquote($table);
493 $has_list = $this->getFromTable($db, $table, true);
494 $this->dbi
->selectDb($db);
495 foreach ($has_list as $column) {
496 $column_status = $this->relation
->checkChildForeignReferences(
497 $db, $table, $column['col_name']
499 //column definition can only be changed if
500 //it is not referenced by another column
501 if ($column_status['isEditable']) {
502 $query .= ' MODIFY ' . Util
::backquote($column['col_name']) . ' '
503 . $this->dbi
->escapeString($column['col_type']);
504 if ($column['col_length']) {
505 $query .= '(' . $column['col_length'] . ')';
508 $query .= ' ' . $column['col_attribute'];
509 if ($column['col_isNull']) {
512 $query .= ' NOT NULL';
515 $query .= ' ' . $column['col_extra'];
516 if ($column['col_default']) {
517 if ($column['col_default'] != 'CURRENT_TIMESTAMP'
518 ||
$column['col_default'] != 'current_timestamp()') {
519 $query .= ' DEFAULT \'' . $this->dbi
->escapeString(
520 $column['col_default']
523 $query .= ' DEFAULT ' . $this->dbi
->escapeString(
524 $column['col_default']
531 $query = trim($query, " ,") . ";";
532 if (!$this->dbi
->tryQuery($query)) {
533 if ($message === true) {
534 $message = Message
::error(
535 $this->dbi
->getError()
539 $this->dbi
->getError(),
549 * return the columns present in central list of columns for a given
550 * table of a given database
552 * @param string $db given database
553 * @param string $table given table
554 * @param boolean $allFields set if need all the fields of existing columns,
555 * otherwise only column_name is returned
557 * @return array columns present in central list from given table of given db.
559 public function getFromTable(
564 $cfgCentralColumns = $this->getParams();
565 if (empty($cfgCentralColumns)) {
568 $this->dbi
->selectDb($db);
569 $fields = (array) $this->dbi
->getColumnNames(
573 foreach ($fields as $col_select) {
574 $cols .= '\'' . $this->dbi
->escapeString($col_select) . '\',';
576 $cols = trim($cols, ',');
577 $has_list = $this->findExistingColNames($db, $cols, $allFields);
578 if (! empty($has_list)) {
579 return (array)$has_list;
586 * update a column in central columns list if a edit is requested
588 * @param string $db current database
589 * @param string $orig_col_name original column name before edit
590 * @param string $col_name new column name
591 * @param string $col_type new column type
592 * @param string $col_attribute new column attribute
593 * @param string $col_length new column length
594 * @param int $col_isNull value 1 if new column isNull is true, 0 otherwise
595 * @param string $collation new column collation
596 * @param string $col_extra new column extra property
597 * @param string $col_default new column default value
599 * @return true|PhpMyAdmin\Message
601 public function updateOneColumn(
613 $cfgCentralColumns = $this->getParams();
614 if (empty($cfgCentralColumns)) {
615 return $this->configErrorMessage();
617 $centralTable = $cfgCentralColumns['table'];
618 $this->dbi
->selectDb($cfgCentralColumns['db'], DatabaseInterface
::CONNECT_CONTROL
);
619 if ($orig_col_name == "") {
621 $def['Type'] = $col_type;
623 $def['Type'] .= '(' . $col_length . ')';
625 $def['Collation'] = $collation;
626 $def['Null'] = $col_isNull?
__('YES'):__('NO');
627 $def['Extra'] = $col_extra;
628 $def['Attribute'] = $col_attribute;
629 $def['Default'] = $col_default;
630 $query = $this->getInsertQuery($col_name, $def, $db, $centralTable);
632 $query = 'UPDATE ' . Util
::backquote($centralTable)
633 . ' SET col_type = \'' . $this->dbi
->escapeString($col_type) . '\''
634 . ', col_name = \'' . $this->dbi
->escapeString($col_name) . '\''
635 . ', col_length = \'' . $this->dbi
->escapeString($col_length) . '\''
636 . ', col_isNull = ' . $col_isNull
637 . ', col_collation = \'' . $this->dbi
->escapeString($collation) . '\''
639 . implode(',', array($col_extra, $col_attribute)) . '\''
640 . ', col_default = \'' . $this->dbi
->escapeString($col_default) . '\''
641 . ' WHERE db_name = \'' . $this->dbi
->escapeString($db) . '\' '
642 . 'AND col_name = \'' . $this->dbi
->escapeString($orig_col_name)
645 if (!$this->dbi
->tryQuery($query, DatabaseInterface
::CONNECT_CONTROL
)) {
646 return Message
::error(
647 $this->dbi
->getError(DatabaseInterface
::CONNECT_CONTROL
)
654 * Update Multiple column in central columns list if a chnage is requested
656 * @return true|PhpMyAdmin\Message
658 public function updateMultipleColumn()
661 $col_name = $_POST['field_name'];
662 $orig_col_name = $_POST['orig_col_name'];
663 $col_default = $_POST['field_default_type'];
664 $col_length = $_POST['field_length'];
665 $col_attribute = $_POST['field_attribute'];
666 $col_type = $_POST['field_type'];
667 $collation = $_POST['field_collation'];
668 $col_isNull = array();
669 $col_extra = array();
670 $num_central_fields = count($orig_col_name);
671 for ($i = 0; $i < $num_central_fields ; $i++
) {
672 $col_isNull[$i] = isset($_POST['field_null'][$i]) ?
1 : 0;
673 $col_extra[$i] = isset($_POST['col_extra'][$i])
674 ?
$_POST['col_extra'][$i] : '';
676 if ($col_default[$i] == 'NONE') {
677 $col_default[$i] = "";
678 } elseif ($col_default[$i] == 'USER_DEFINED') {
679 $col_default[$i] = $_POST['field_default_value'][$i];
682 $message = $this->updateOneColumn(
683 $db, $orig_col_name[$i], $col_name[$i], $col_type[$i],
684 $col_attribute[$i], $col_length[$i], $col_isNull[$i], $collation[$i],
685 $col_extra[$i], $col_default[$i]
687 if (!is_bool($message)) {
695 * get the html for table navigation in Central columns page
697 * @param int $total_rows total number of rows in complete result set
698 * @param int $pos offset of first result with complete result set
699 * @param string $db current database
701 * @return string html for table navigation in Central columns page
703 public function getHtmlForTableNavigation($total_rows, $pos, $db)
705 $pageNow = ($pos / $this->maxRows
) +
1;
706 $nbTotalPage = ceil($total_rows / $this->maxRows
);
707 $page_selector = ($nbTotalPage > 1)?
(Util
::pageselector(
708 'pos', $this->maxRows
, $pageNow, $nbTotalPage
710 return Template
::get('database/central_columns/table_navigation')->render(array(
712 "max_rows" => $this->maxRows
,
714 "total_rows" => $total_rows,
715 "nb_total_page" => $nbTotalPage,
716 "page_selector" => $page_selector,
721 * function generate and return the table header for central columns page
723 * @param string $class styling class of 'th' elements
724 * @param string $title title of the 'th' elements
725 * @param integer $actionCount number of actions
727 * @return string html for table header in central columns view/edit page
729 public function getTableHeader($class = '', $title = '', $actionCount = 0)
732 if ($actionCount > 0) {
733 $action .= '<th class="column_action" colspan="' . $actionCount . '">'
734 . __('Action') . '</th>';
736 $tableheader = '<thead>';
737 $tableheader .= '<tr>'
738 . '<th class="' . $class . '"></th>'
739 . '<th class="hide"></th>'
741 . '<th class="' . $class . '" title="' . $title . '" data-column="name">'
742 . __('Name') . '<div class="sorticon"></div></th>'
743 . '<th class="' . $class . '" title="' . $title . '" data-column="type">'
744 . __('Type') . '<div class="sorticon"></div></th>'
745 . '<th class="' . $class . '" title="' . $title . '" data-column="length">'
746 . __('Length/Values') . '<div class="sorticon"></div></th>'
747 . '<th class="' . $class . '" title="' . $title . '" data-column="default">'
748 . __('Default') . '<div class="sorticon"></div></th>'
749 . '<th class="' . $class . '" title="' . $title . '" data-column="collation"'
750 . '>' . __('Collation') . '<div class="sorticon"></div></th>'
751 . '<th class="' . $class . '" title="' . $title
752 . '" data-column="attribute">'
753 . __('Attribute') . '<div class="sorticon"></div></th>'
754 . '<th class="' . $class . '" title="' . $title . '" data-column="isnull">'
755 . __('Null') . '<div class="sorticon"></div></th>'
756 . '<th class="' . $class . '" title="' . $title . '" data-column="extra">'
757 . __('A_I') . '<div class="sorticon"></div></th>'
759 $tableheader .= '</thead>';
764 * Function generate and return the table header for
765 * multiple edit central columns page
767 * @param array $headers headers list
769 * @return string html for table header in central columns multi edit page
771 private function getEditTableHeader(array $headers)
773 return Template
::get(
774 'database/central_columns/edit_table_header'
776 'headers' => $headers,
781 * build the dropdown select html for tables of given database
783 * @param string $db current database
785 * @return string html dropdown for selecting table
787 private function getHtmlForTableDropdown($db)
789 $this->dbi
->selectDb($db);
790 $tables = $this->dbi
->getTables($db);
791 $selectHtml = '<select name="table-select" id="table-select">'
792 . '<option value="" disabled="disabled" selected="selected">'
793 . __('Select a table') . '</option>';
794 foreach ($tables as $table) {
795 $selectHtml .= '<option value="' . htmlspecialchars($table) . '">'
796 . htmlspecialchars($table) . '</option>';
798 $selectHtml .= '</select>';
803 * build dropdown select html to select column in selected table,
804 * include only columns which are not already in central list
806 * @param string $db current database to which selected table belongs
807 * @param string $selected_tbl selected table
809 * @return string html to select column
811 public function getHtmlForColumnDropdown($db, $selected_tbl)
813 $existing_cols = $this->getFromTable($db, $selected_tbl);
814 $this->dbi
->selectDb($db);
815 $columns = (array) $this->dbi
->getColumnNames(
819 foreach ($columns as $column) {
820 if (!in_array($column, $existing_cols)) {
821 $selectColHtml .= '<option value="' . htmlspecialchars($column) . '">'
822 . htmlspecialchars($column)
826 return $selectColHtml;
830 * HTML to display the form that let user to add a column on Central columns page
832 * @param int $total_rows total number of rows in complete result set
833 * @param int $pos offset of first result with complete result set
834 * @param string $db current database
836 * @return string html to add a column in the central list
838 public function getHtmlForAddColumn(
843 $icon = Util
::getIcon(
844 'centralColumns_add',
847 $table_drop_down = $this->getHtmlForTableDropdown($db);
848 return Template
::get('database/central_columns/add_column')->render(array(
852 'total_rows' => $total_rows,
853 'table_drop_down' => $table_drop_down,
858 * build html for a row in central columns table
860 * @param array $row array contains complete information of a particular row of central list table
861 * @param int $row_num position the row in the table
862 * @param string $db current database
864 * @return string html of a particular row in the central columns table.
866 public function getHtmlForTableRow(array $row, $row_num, $db)
868 $tableHtml = '<tr data-rownum="' . $row_num . '" id="f_' . $row_num . '">'
869 . Url
::getHiddenInputs(
872 . '<input type="hidden" name="edit_save" value="save">'
873 . '<td class="nowrap">'
874 . '<input type="checkbox" class="checkall" name="selected_fld[]" '
875 . 'value="' . htmlspecialchars($row['col_name']) . '" '
876 . 'id="checkbox_row_' . $row_num . '"/>'
878 . '<td id="edit_' . $row_num . '" class="edit center">'
879 . '<a href="#">' . Util
::getIcon('b_edit', __('Edit')) . '</a></td>'
880 . '<td class="del_row" data-rownum = "' . $row_num . '">'
881 . '<a hrf="#">' . Util
::getIcon('b_drop', __('Delete')) . '</a>'
882 . '<input type="submit" data-rownum = "' . $row_num . '"'
883 . ' class="edit_cancel_form" value="Cancel"></td>'
884 . '<td id="save_' . $row_num . '" class="hide">'
885 . '<input type="submit" data-rownum = "' . $row_num . '"'
886 . ' class="edit_save_form" value="Save"></td>';
889 '<td name="col_name" class="nowrap">'
890 . '<span>' . htmlspecialchars($row['col_name']) . '</span>'
891 . '<input name="orig_col_name" type="hidden" '
892 . 'value="' . htmlspecialchars($row['col_name']) . '">'
893 . Template
::get('columns_definitions/column_name')->render(array(
894 'column_number' => $row_num,
897 'column_meta' => array(
898 'Field'=>$row['col_name']
900 'cfg_relation' => array(
901 'centralcolumnswork' => false
903 'max_rows' => $this->maxRows
,
907 '<td name = "col_type" class="nowrap"><span>'
908 . htmlspecialchars($row['col_type']) . '</span>'
909 . Template
::get('columns_definitions/column_type')
912 'column_number' => $row_num,
915 'type_upper' => mb_strtoupper($row['col_type']),
916 'column_meta' => array()
921 '<td class="nowrap" name="col_length">'
922 . '<span>' . ($row['col_length']?
htmlspecialchars($row['col_length']):"")
924 . Template
::get('columns_definitions/column_length')->render(
926 'column_number' => $row_num,
929 'length_values_input_size' => 8,
930 'length_to_display' => $row['col_length']
936 if (!isset($row['col_default']) ||
$row['col_default'] == '') {
937 $meta['DefaultType'] = 'NONE';
939 if ($row['col_default'] == 'CURRENT_TIMESTAMP'
940 ||
$row['col_default'] == 'current_timestamp()'
942 $meta['DefaultType'] = 'CURRENT_TIMESTAMP';
943 } elseif ($row['col_default'] == 'NULL') {
944 $meta['DefaultType'] = $row['col_default'];
946 $meta['DefaultType'] = 'USER_DEFINED';
947 $meta['DefaultValue'] = $row['col_default'];
951 '<td class="nowrap" name="col_default"><span>' . (isset($row['col_default'])
952 ?
htmlspecialchars($row['col_default']) : 'None')
954 . Template
::get('columns_definitions/column_default')
957 'column_number' => $row_num,
960 'type_upper' => mb_strtoupper($row['col_type']),
961 'column_meta' => $meta,
962 'char_editing' => $this->charEditing
,
968 '<td name="collation" class="nowrap">'
969 . '<span>' . htmlspecialchars($row['col_collation']) . '</span>'
970 . Charsets
::getCollationDropdownBox(
973 'field_collation[' . $row_num . ']',
974 'field_' . $row_num . '_4', $row['col_collation'], false
978 '<td class="nowrap" name="col_attribute">'
980 ($row['col_attribute']
981 ?
htmlspecialchars($row['col_attribute']) : "" )
983 . Template
::get('columns_definitions/column_attribute')
986 'column_number' => $row_num,
989 'extracted_columnspec' => array(),
990 'column_meta' => $row['col_attribute'],
991 'submit_attribute' => false,
992 'attribute_types' => $this->dbi
->types
->getAttributes(),
997 '<td class="nowrap" name="col_isNull">'
998 . '<span>' . ($row['col_isNull'] ?
__('Yes') : __('No'))
1000 . Template
::get('columns_definitions/column_null')
1003 'column_number' => $row_num,
1006 'column_meta' => array(
1007 'Null' => $row['col_isNull']
1014 '<td class="nowrap" name="col_extra"><span>'
1015 . htmlspecialchars($row['col_extra']) . '</span>'
1016 . Template
::get('columns_definitions/column_extra')->render(
1018 'column_number' => $row_num,
1021 'column_meta' => array('Extra'=>$row['col_extra'])
1026 $tableHtml .= '</tr>';
1032 * build html for editing a row in central columns table
1034 * @param array $row array contains complete information of a
1035 * particular row of central list table
1036 * @param int $row_num position the row in the table
1038 * @return string html of a particular row in the central columns table.
1040 private function getHtmlForEditTableRow(array $row, $row_num)
1043 . '<input name="orig_col_name[' . $row_num . ']" type="hidden" '
1044 . 'value="' . htmlspecialchars($row['col_name']) . '">'
1045 . '<td name="col_name" class="nowrap">'
1046 . Template
::get('columns_definitions/column_name')->render(array(
1047 'column_number' => $row_num,
1050 'column_meta' => array(
1051 'Field' => $row['col_name']
1053 'cfg_relation' => array(
1054 'centralcolumnswork' => false
1056 'max_rows' => $this->maxRows
,
1060 '<td name = "col_type" class="nowrap">'
1061 . Template
::get('columns_definitions/column_type')
1064 'column_number' => $row_num,
1067 'type_upper' => mb_strtoupper($row['col_type']),
1068 'column_meta' => array()
1073 '<td class="nowrap" name="col_length">'
1074 . Template
::get('columns_definitions/column_length')->render(
1076 'column_number' => $row_num,
1079 'length_values_input_size' => 8,
1080 'length_to_display' => $row['col_length']
1085 if (!isset($row['col_default']) ||
$row['col_default'] == '') {
1086 $meta['DefaultType'] = 'NONE';
1088 if ($row['col_default'] == 'CURRENT_TIMESTAMP'
1089 ||
$row['col_default'] == 'current_timestamp()'
1091 $meta['DefaultType'] = 'CURRENT_TIMESTAMP';
1092 } elseif ($row['col_default'] == 'NULL') {
1093 $meta['DefaultType'] = $row['col_default'];
1095 $meta['DefaultType'] = 'USER_DEFINED';
1096 $meta['DefaultValue'] = $row['col_default'];
1100 '<td class="nowrap" name="col_default">'
1101 . Template
::get('columns_definitions/column_default')
1104 'column_number' => $row_num,
1107 'type_upper' => mb_strtoupper($row['col_default']),
1108 'column_meta' => $meta,
1109 'char_editing' => $this->charEditing
,
1114 '<td name="collation" class="nowrap">'
1115 . Charsets
::getCollationDropdownBox(
1118 'field_collation[' . $row_num . ']',
1119 'field_' . $row_num . '_4', $row['col_collation'], false
1123 '<td class="nowrap" name="col_attribute">'
1124 . Template
::get('columns_definitions/column_attribute')
1127 'column_number' => $row_num,
1130 'extracted_columnspec' => array(
1131 'attribute' => $row['col_attribute']
1133 'column_meta' => array(),
1134 'submit_attribute' => false,
1135 'attribute_types' => $this->dbi
->types
->getAttributes(),
1140 '<td class="nowrap" name="col_isNull">'
1141 . Template
::get('columns_definitions/column_null')
1144 'column_number' => $row_num,
1147 'column_meta' => array(
1148 'Null' => $row['col_isNull']
1155 '<td class="nowrap" name="col_extra">'
1156 . Template
::get('columns_definitions/column_extra')->render(
1158 'column_number' => $row_num,
1161 'column_meta' => array('Extra' => $row['col_extra'])
1165 $tableHtml .= '</tr>';
1170 * get the list of columns in given database excluding
1171 * the columns present in current table
1173 * @param string $db selected database
1174 * @param string $table current table name
1176 * @return string encoded list of columns present in central list for the given
1179 public function getListRaw($db, $table)
1181 $cfgCentralColumns = $this->getParams();
1182 if (empty($cfgCentralColumns)) {
1183 return json_encode(array());
1185 $centralTable = $cfgCentralColumns['table'];
1186 if (empty($table) ||
$table == '') {
1187 $query = 'SELECT * FROM ' . Util
::backquote($centralTable) . ' '
1188 . 'WHERE db_name = \'' . $this->dbi
->escapeString($db) . '\';';
1190 $this->dbi
->selectDb($db);
1191 $columns = (array) $this->dbi
->getColumnNames(
1195 foreach ($columns as $col_select) {
1196 $cols .= '\'' . $this->dbi
->escapeString($col_select) . '\',';
1198 $cols = trim($cols, ',');
1199 $query = 'SELECT * FROM ' . Util
::backquote($centralTable) . ' '
1200 . 'WHERE db_name = \'' . $this->dbi
->escapeString($db) . '\'';
1202 $query .= ' AND col_name NOT IN (' . $cols . ')';
1206 $this->dbi
->selectDb($cfgCentralColumns['db'], DatabaseInterface
::CONNECT_CONTROL
);
1207 $columns_list = (array)$this->dbi
->fetchResult(
1208 $query, null, null, DatabaseInterface
::CONNECT_CONTROL
1210 $this->handleColumnExtra($columns_list);
1211 return json_encode($columns_list);
1215 * Get HTML for "check all" check box with "with selected" dropdown
1217 * @param string $pmaThemeImage pma theme image url
1218 * @param string $text_dir url for text directory
1220 * @return string $html_output
1222 public function getTableFooter($pmaThemeImage, $text_dir)
1224 $html_output = Template
::get('select_all')
1227 'pma_theme_image' => $pmaThemeImage,
1228 'text_dir' => $text_dir,
1229 'form_name' => 'tableslistcontainer',
1232 $html_output .= Util
::getButtonOrImage(
1233 'edit_central_columns', 'mult_submit change_central_columns',
1234 __('Edit'), 'b_edit', 'edit central columns'
1236 $html_output .= Util
::getButtonOrImage(
1237 'delete_central_columns', 'mult_submit',
1238 __('Delete'), 'b_drop',
1239 'remove_from_central_columns'
1241 return $html_output;
1245 * function generate and return the table footer for
1246 * multiple edit central columns page
1248 * @return string html for table footer in central columns multi edit page
1250 private function getEditTableFooter()
1252 $html_output = '<fieldset class="tblFooters">'
1253 . '<input type="submit" '
1254 . 'name="save_multi_central_column_edit" value="' . __('Save') . '" />'
1256 return $html_output;
1260 * Column `col_extra` is used to store both extra and attributes for a column.
1261 * This method separates them.
1263 * @param array &$columns_list columns list
1267 private function handleColumnExtra(array &$columns_list)
1269 foreach ($columns_list as &$row) {
1270 $vals = explode(',', $row['col_extra']);
1272 if (in_array('BINARY', $vals)) {
1273 $row['col_attribute'] = 'BINARY';
1274 } elseif (in_array('UNSIGNED', $vals)) {
1275 $row['col_attribute'] = 'UNSIGNED';
1276 } elseif (in_array('UNSIGNED ZEROFILL', $vals)) {
1277 $row['col_attribute'] = 'UNSIGNED ZEROFILL';
1278 } elseif (in_array('on update CURRENT_TIMESTAMP', $vals)) {
1279 $row['col_attribute'] = 'on update CURRENT_TIMESTAMP';
1281 $row['col_attribute'] = '';
1284 if (in_array('auto_increment', $vals)) {
1285 $row['col_extra'] = 'auto_increment';
1287 $row['col_extra'] = '';
1293 * build html for adding a new user defined column to central list
1295 * @param string $db current database
1296 * @param integer $total_rows number of rows in central columns
1298 * @return string html of the form to let user add a new user defined column to the
1301 public function getHtmlForAddNewColumn($db, $total_rows)
1303 $addNewColumn = '<div id="add_col_div" class="topmargin"><a href="#">'
1304 . '<span>+</span> ' . __('Add new column') . '</a>'
1305 . '<form id="add_new" class="new_central_col '
1306 . ($total_rows != 0 ?
'hide"' : '"')
1307 . 'method="post" action="db_central_columns.php">'
1308 . Url
::getHiddenInputs(
1311 . '<input type="hidden" name="add_new_column" value="add_new_column">'
1312 . '<div class="responsivetable">'
1314 $addNewColumn .= $this->getTableHeader();
1315 $addNewColumn .= '<tr>'
1317 . '<td name="col_name" class="nowrap">'
1318 . Template
::get('columns_definitions/column_name')->render(array(
1319 'column_number' => 0,
1322 'column_meta' => array(),
1323 'cfg_relation' => array(
1324 'centralcolumnswork' => false
1326 'max_rows' => $this->maxRows
,
1329 . '<td name = "col_type" class="nowrap">'
1330 . Template
::get('columns_definitions/column_type')
1333 'column_number' => 0,
1337 'column_meta' => array()
1341 . '<td class="nowrap" name="col_length">'
1342 . Template
::get('columns_definitions/column_length')->render(
1344 'column_number' => 0,
1347 'length_values_input_size' => 8,
1348 'length_to_display' => ''
1352 . '<td class="nowrap" name="col_default">'
1353 . Template
::get('columns_definitions/column_default')
1356 'column_number' => 0,
1360 'column_meta' => array(),
1361 'char_editing' => $this->charEditing
,
1365 . '<td name="collation" class="nowrap">'
1366 . Charsets
::getCollationDropdownBox(
1369 'field_collation[0]',
1370 'field_0_4', null, false
1373 . '<td class="nowrap" name="col_attribute">'
1374 . Template
::get('columns_definitions/column_attribute')
1377 'column_number' => 0,
1380 'extracted_columnspec' => array(),
1381 'column_meta' => array(),
1382 'submit_attribute' => false,
1383 'attribute_types' => $this->dbi
->types
->getAttributes(),
1387 . '<td class="nowrap" name="col_isNull">'
1388 . Template
::get('columns_definitions/column_null')
1391 'column_number' => 0,
1394 'column_meta' => array()
1398 . '<td class="nowrap" name="col_extra">'
1399 . Template
::get('columns_definitions/column_extra')->render(
1401 'column_number' => 0,
1404 'column_meta' => array()
1409 . '<input id="add_column_save" type="submit" '
1410 . ' value="Save"/></td>'
1412 $addNewColumn .= '</table></div></form></div>';
1413 return $addNewColumn;
1417 * Get HTML for editing page central columns
1419 * @param array $selected_fld Array containing the selected fields
1420 * @param string $selected_db String containing the name of database
1422 * @return string HTML for complete editing page for central columns
1424 public function getHtmlForEditingPage(array $selected_fld, $selected_db)
1426 $html = '<form id="multi_edit_central_columns">';
1427 $header_cells = array(
1428 __('Name'), __('Type'), __('Length/Values'), __('Default'),
1429 __('Collation'), __('Attributes'), __('Null'), __('A_I')
1431 $html .= $this->getEditTableHeader($header_cells);
1432 $selected_fld_safe = array();
1433 foreach ($selected_fld as $key) {
1434 $selected_fld_safe[] = $this->dbi
->escapeString($key);
1436 $columns_list = implode("','", $selected_fld_safe);
1437 $columns_list = "'" . $columns_list . "'";
1438 $list_detail_cols = $this->findExistingColNames($selected_db, $columns_list, true);
1440 foreach ($list_detail_cols as $row) {
1441 $tableHtmlRow = $this->getHtmlForEditTableRow(
1445 $html .= $tableHtmlRow;
1448 $html .= '</table>';
1449 $html .= $this->getEditTableFooter();