2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Display form for changing/adding table fields/columns.
5 * Included by tbl_addfield.php and tbl_create.php
9 if (!defined('PHPMYADMIN')) {
16 require_once 'libraries/di/Container.class.php';
17 require_once 'libraries/Util.class.php';
18 require_once 'libraries/Template.class.php';
19 require_once 'libraries/util.lib.php';
23 PMA_Util
::checkParameters(array('server', 'db', 'table', 'action', 'num_fields'));
28 * Initialize to avoid code execution path warnings
31 if (!isset($num_fields)) {
34 if (!isset($mime_map)) {
37 if (!isset($columnMeta)) {
38 $columnMeta = array();
42 // Get available character sets and storage engines
43 require_once './libraries/mysql_charsets.inc.php';
44 require_once './libraries/StorageEngine.class.php';
47 * Class for partition management
49 require_once './libraries/Partition.class.php';
51 /** @var PMA_String $pmaString */
52 $pmaString = $GLOBALS['PMA_String'];
54 $length_values_input_size = 8;
56 $content_cells = array();
58 /** @var string $db */
63 if ($action == 'tbl_create.php') {
64 $form_params['reload'] = 1;
66 if ($action == 'tbl_addfield.php') {
67 $form_params = array_merge(
69 'field_where' => Util\
get($_REQUEST, 'field_where'))
71 if (isset($_REQUEST['field_where'])) {
72 $form_params['after_field'] = $_REQUEST['after_field'];
75 $form_params['table'] = $table;
78 if (isset($num_fields)) {
79 $form_params['orig_num_fields'] = $num_fields;
82 $form_params = array_merge(
85 'orig_field_where' => Util\
get($_REQUEST, 'field_where'),
86 'orig_after_field' => Util\
get($_REQUEST, 'after_field'),
90 if (isset($selected) && is_array($selected)) {
91 foreach ($selected as $o_fld_nr => $o_fld_val) {
92 $form_params['selected[' . $o_fld_nr . ']'] = $o_fld_val;
96 $is_backup = ($action != 'tbl_create.php' && $action != 'tbl_addfield.php');
98 require_once './libraries/transformations.lib.php';
99 $cfgRelation = PMA_getRelationsParam();
101 $comments_map = PMA_getComments($db, $table);
103 $move_columns = array();
104 if (isset($fields_meta)) {
105 /** @var PMA_DatabaseInterface $dbi */
106 $dbi = \PMA\DI\Container
::getDefaultContainer()->get('dbi');
107 $move_columns = $dbi->getTable($db, $table)->getColumnsMeta();
110 $available_mime = array();
111 if ($cfgRelation['mimework'] && $GLOBALS['cfg']['BrowseMIME']) {
112 $mime_map = PMA_getMIME($db, $table);
113 $available_mime = PMA_getAvailableMIMEtypes();
116 // workaround for field_fulltext, because its submitted indices contain
117 // the index as a value, not a key. Inserted here for easier maintenance
118 // and less code to change in existing files.
119 if (isset($field_fulltext) && is_array($field_fulltext)) {
120 foreach ($field_fulltext as $fulltext_nr => $fulltext_indexkey) {
121 $submit_fulltext[$fulltext_indexkey] = $fulltext_indexkey;
124 if (isset($_REQUEST['submit_num_fields'])) {
125 //if adding new fields, set regenerate to keep the original values
129 $foreigners = PMA_getForeigners($db, $table, '', 'foreign');
130 $child_references = null;
131 // From MySQL 5.6.6 onwards columns with foreign keys can be renamed.
132 // Hence, no need to get child references
133 if (PMA_MYSQL_INT_VERSION
< 50606) {
134 $child_references = PMA_getChildReferences($db, $table);
137 for ($columnNumber = 0; $columnNumber < $num_fields; $columnNumber++
) {
141 $columnMeta = array();
142 $submit_attribute = null;
143 $extracted_columnspec = array();
145 if (!empty($regenerate)) {
147 $columnMeta = array_merge(
151 $_REQUEST, "field_name.${columnNumber}", false
154 $_REQUEST, "field_type.${columnNumber}", false
156 'Collation' => Util\
get(
157 $_REQUEST, "field_collation.${columnNumber}", ''
160 $_REQUEST, "field_null.${columnNumber}", ''
162 'DefaultType' => Util\
get(
163 $_REQUEST, "field_default_type.${columnNumber}", 'NONE'
165 'DefaultValue' => Util\
get(
166 $_REQUEST, "field_default_value.${columnNumber}", ''
169 $_REQUEST, "field_extra.${columnNumber}", false
171 'Virtuality' => Util\
get(
172 $_REQUEST, "field_virtuality.${columnNumber}", ''
174 'Expression' => Util\
get(
175 $_REQUEST, "field_expression.${columnNumber}", ''
180 $columnMeta['Key'] = '';
182 '_', Util\
get($_REQUEST, "field_key.${columnNumber}", ''), 2
184 if (count($parts) == 2 && $parts[1] == $columnNumber) {
185 $columnMeta['Key'] = Util\
get(
190 'fulltext' => 'FULLTEXT',
191 'spatial' => 'SPATIAL'
197 $columnMeta['Comment']
198 = isset($submit_fulltext[$columnNumber])
199 && ($submit_fulltext[$columnNumber] == $columnNumber)
200 ?
'FULLTEXT' : false;
202 switch ($columnMeta['DefaultType']) {
204 $columnMeta['Default'] = null;
207 $columnMeta['Default'] = $columnMeta['DefaultValue'];
210 case 'CURRENT_TIMESTAMP':
211 $columnMeta['Default'] = $columnMeta['DefaultType'];
215 $length = Util\
get($_REQUEST, "field_length.${columnNumber}", $length);
216 $submit_attribute = Util\
get(
217 $_REQUEST, "field_attribute.${columnNumber}", false
219 $comments_map[$columnMeta['Field']] = Util\
get(
220 $_REQUEST, "field_comments.${columnNumber}"
223 $mime_map[$columnMeta['Field']] = array_merge(
224 $mime_map[$columnMeta['Field']],
226 'mimetype' => Util\
get($_REQUEST, "field_mimetype.${$columnNumber}"),
227 'transformation' => Util\
get(
228 $_REQUEST, "field_transformation.${$columnNumber}"
230 'transformation_options' => Util\
get(
231 $_REQUEST, "field_transformation_options.${$columnNumber}"
236 } elseif (isset($fields_meta[$columnNumber])) {
237 $columnMeta = $fields_meta[$columnNumber];
239 'VIRTUAL', 'PERSISTENT', 'VIRTUAL GENERATED', 'STORED GENERATED'
241 if (in_array($columnMeta['Extra'], $virtual)) {
242 $tableObj = new PMA_Table($GLOBALS['table'], $GLOBALS['db']);
243 $expressions = $tableObj->getColumnGenerationExpression(
246 $columnMeta['Expression'] = $expressions[$columnMeta['Field']];
248 switch ($columnMeta['Default']) {
250 if (is_null($columnMeta['Default'])) { // null
251 if ($columnMeta['Null'] == 'YES') {
252 $columnMeta['DefaultType'] = 'NULL';
253 $columnMeta['DefaultValue'] = '';
255 $columnMeta['DefaultType'] = 'NONE';
256 $columnMeta['DefaultValue'] = '';
259 $columnMeta['DefaultType'] = 'USER_DEFINED';
260 $columnMeta['DefaultValue'] = $columnMeta['Default'];
263 case 'CURRENT_TIMESTAMP':
264 $columnMeta['DefaultType'] = 'CURRENT_TIMESTAMP';
265 $columnMeta['DefaultValue'] = '';
268 $columnMeta['DefaultType'] = 'USER_DEFINED';
269 $columnMeta['DefaultValue'] = $columnMeta['Default'];
274 if (isset($columnMeta['Type'])) {
275 $extracted_columnspec = PMA_Util
::extractColumnSpec($columnMeta['Type']);
276 if ($extracted_columnspec['type'] == 'bit') {
277 $columnMeta['Default']
278 = PMA_Util
::convertBitDefaultValue($columnMeta['Default']);
280 $type = $extracted_columnspec['type'];
282 $length = $extracted_columnspec['spec_in_brackets'];
286 $columnMeta['Type'] = '';
289 // Variable tell if current column is bound in a foreign key constraint or not.
290 // MySQL version from 5.6.6 allow renaming columns with foreign keys
291 if (isset($columnMeta['Field'])
292 && isset($form_params['table'])
293 && PMA_MYSQL_INT_VERSION
< 50606
295 $columnMeta['column_status'] = PMA_checkChildForeignReferences(
297 $form_params['table'],
298 $columnMeta['Field'],
304 // some types, for example longtext, are reported as
305 // "longtext character set latin7" when their charset and / or collation
306 // differs from the ones of the corresponding database.
307 // rtrim the type, for cases like "float unsigned"
309 mb_ereg_replace('[\w\W]character set[\w\W]*', '', $type)
313 * old column attributes
318 if (isset($columnMeta['Field'])) {
319 $form_params['field_orig[' . $columnNumber . ']']
320 = $columnMeta['Field'];
321 if (isset($columnMeta['column_status'])
322 && !$columnMeta['column_status']['isEditable']
324 $form_params['field_name[' . $columnNumber . ']']
325 = $columnMeta['Field'];
328 $form_params['field_orig[' . $columnNumber . ']'] = '';
332 if (isset($columnMeta['Type'])) {
333 // keep in uppercase because the new type will be in uppercase
334 $form_params['field_type_orig[' . $columnNumber . ']']
336 mb_strtoupper($type);
337 if (isset($columnMeta['column_status'])
338 && !$columnMeta['column_status']['isEditable']
340 $form_params['field_type[' . $columnNumber . ']']
342 mb_strtoupper($type);
345 $form_params['field_type_orig[' . $columnNumber . ']'] = '';
349 $form_params['field_length_orig[' . $columnNumber . ']'] = $length;
351 // old column default
352 $form_params = array_merge(
355 "field_default_value_orig[${columnNumber}]" => Util\
get(
356 $columnMeta, 'Default', ''
358 "field_default_type_orig[${columnNumber}]" => Util\
get(
359 $columnMeta, 'DefaultType', ''
361 "field_collation_orig[${columnNumber}]" => Util\
get(
362 $columnMeta, 'Collation', ''
364 "field_attribute_orig[${columnNumber}]" => trim(
365 Util\
get($extracted_columnspec, 'attribute', '')
367 "field_null_orig[${columnNumber}]" => Util\
get(
368 $columnMeta, 'Null', ''
370 "field_extra_orig[${columnNumber}]" => Util\
get(
371 $columnMeta, 'Extra', ''
373 "field_comments_orig[${columnNumber}]" => Util\
get(
374 $columnMeta, 'Comment', ''
376 "field_virtuality_orig[${columnNumber}]" => Util\
get(
377 $columnMeta, 'Virtuality', ''
379 "field_expression_orig[${columnNumber}]" => Util\
get(
380 $columnMeta, 'Expression', ''
386 $content_cells[$columnNumber] = array(
387 'columnNumber' => $columnNumber,
388 'columnMeta' => $columnMeta,
389 'type_upper' => /*overload*/mb_strtoupper($type),
390 'length_values_input_size' => $length_values_input_size,
392 'extracted_columnspec' => $extracted_columnspec,
393 'submit_attribute' => $submit_attribute,
394 'comments_map' => $comments_map,
395 'fields_meta' => isset($fields_meta) ?
$fields_meta : null,
396 'is_backup' => $is_backup,
397 'move_columns' => $move_columns,
398 'cfgRelation' => $cfgRelation,
399 'available_mime' => $available_mime,
400 'mime_map' => isset($mime_map) ?
$mime_map : array()
404 $html = PMA\Template
::get('columns_definitions/column_definitions_form')->render(
406 'is_backup' => $is_backup,
407 'fields_meta' => isset($fields_meta) ?
$fields_meta : null,
408 'mimework' => $cfgRelation['mimework'],
410 'form_params' => $form_params,
411 'content_cells' => $content_cells,
417 $response = PMA_Response
::getInstance();
418 $response->getHeader()->getScripts()->addFiles(
420 'jquery/jquery.uitablefilter.js',
424 $response->addHTML($html);