Upgraded phpmyadmin to 4.0.4 (All Languages) - No modifications yet
[openemr.git] / phpmyadmin / libraries / insert_edit.lib.php
blobaf5cb90be744ccccc7af874737721f5c77657d0d
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * set of functions with the insert/edit features in pma
6 * @package PhpMyAdmin
7 */
9 if (! defined('PHPMYADMIN')) {
10 exit;
13 /**
14 * Retrieve form parameters for insert/edit form
16 * @param string $db name of the database
17 * @param string $table name of the table
18 * @param array $where_clauses where clauses
19 * @param array $where_clause_array array of where clauses
20 * @param string $err_url error url
22 * @return array $_form_params array of insert/edit form parameters
24 function PMA_getFormParametersForInsertForm($db, $table, $where_clauses,
25 $where_clause_array, $err_url
26 ) {
27 $_form_params = array(
28 'db' => $db,
29 'table' => $table,
30 'goto' => $GLOBALS['goto'],
31 'err_url' => $err_url,
32 'sql_query' => $_REQUEST['sql_query'],
34 if (isset($where_clauses)) {
35 foreach ($where_clause_array as $key_id => $where_clause) {
36 $_form_params['where_clause[' . $key_id . ']'] = trim($where_clause);
39 if (isset($_REQUEST['clause_is_unique'])) {
40 $_form_params['clause_is_unique'] = $_REQUEST['clause_is_unique'];
42 return $_form_params;
45 /**
46 * Creates array of where clauses
48 * @param array $where_clause where clause
50 * @return whereClauseArray array of where clauses
52 function PMA_getWhereClauseArray($where_clause)
54 if (isset ($where_clause)) {
55 if (is_array($where_clause)) {
56 return $where_clause;
57 } else {
58 return array(0 => $where_clause);
63 /**
64 * Analysing where clauses array
66 * @param array $where_clause_array array of where clauses
67 * @param string $table name of the table
68 * @param string $db name of the database
70 * @return array $where_clauses, $result, $rows
72 function PMA_analyzeWhereClauses(
73 $where_clause_array, $table, $db
74 ) {
75 $rows = array();
76 $result = array();
77 $where_clauses = array();
78 $found_unique_key = false;
79 foreach ($where_clause_array as $key_id => $where_clause) {
81 $local_query = 'SELECT * FROM '
82 . PMA_Util::backquote($db) . '.'
83 . PMA_Util::backquote($table)
84 . ' WHERE ' . $where_clause . ';';
85 $result[$key_id] = PMA_DBI_query($local_query, null, PMA_DBI_QUERY_STORE);
86 $rows[$key_id] = PMA_DBI_fetch_assoc($result[$key_id]);
88 $where_clauses[$key_id] = str_replace('\\', '\\\\', $where_clause);
89 $has_unique_condition = PMA_showEmptyResultMessageOrSetUniqueCondition(
90 $rows, $key_id, $where_clause_array, $local_query, $result
92 if ($has_unique_condition) {
93 $found_unique_key = true;
96 return array($where_clauses, $result, $rows, $found_unique_key);
99 /**
100 * Show message for empty reult or set the unique_condition
102 * @param array $rows MySQL returned rows
103 * @param string $key_id ID in current key
104 * @param array $where_clause_array array of where clauses
105 * @param string $local_query query performed
106 * @param array $result MySQL result handle
108 * @return boolean $has_unique_condition
110 function PMA_showEmptyResultMessageOrSetUniqueCondition($rows, $key_id,
111 $where_clause_array, $local_query, $result
113 $has_unique_condition = false;
115 // No row returned
116 if (! $rows[$key_id]) {
117 unset($rows[$key_id], $where_clause_array[$key_id]);
118 PMA_Response::getInstance()->addHtml(
119 PMA_Util::getMessage(
120 __('MySQL returned an empty result set (i.e. zero rows).'),
121 $local_query
125 * @todo not sure what should be done at this point, but we must not
126 * exit if we want the message to be displayed
128 } else {// end if (no row returned)
129 $meta = PMA_DBI_get_fields_meta($result[$key_id]);
131 list($unique_condition, $tmp_clause_is_unique)
132 = PMA_Util::getUniqueCondition(
133 $result[$key_id], count($meta), $meta, $rows[$key_id], true
136 if (! empty($unique_condition)) {
137 $has_unique_condition = true;
139 unset($unique_condition, $tmp_clause_is_unique);
141 return $has_unique_condition;
145 * No primary key given, just load first row
147 * @param string $table name of the table
148 * @param string $db name of the database
150 * @return array containing $result and $rows arrays
152 function PMA_loadFirstRow($table, $db)
154 $result = PMA_DBI_query(
155 'SELECT * FROM ' . PMA_Util::backquote($db)
156 . '.' . PMA_Util::backquote($table) . ' LIMIT 1;',
157 null,
158 PMA_DBI_QUERY_STORE
160 $rows = array_fill(0, $GLOBALS['cfg']['InsertRows'], false);
161 return array($result, $rows);
165 * Add some url parameters
167 * @param array $url_params containing $db and $table as url parameters
168 * @param array $where_clause_array where clauses array
169 * @param string $where_clause where clause
171 * @return array Add some url parameters to $url_params array and return it
173 function PMA_urlParamsInEditMode($url_params, $where_clause_array, $where_clause)
175 if (isset($where_clause)) {
176 foreach ($where_clause_array as $where_clause) {
177 $url_params['where_clause'] = trim($where_clause);
180 if (! empty($_REQUEST['sql_query'])) {
181 $url_params['sql_query'] = $_REQUEST['sql_query'];
183 return $url_params;
187 * Show function fields in data edit view in pma
189 * @param array $url_params containing url parameters
190 * @param boolean $showFuncFields whether to show function field
192 * @return string an html snippet
194 function PMA_showFunctionFieldsInEditMode($url_params, $showFuncFields)
196 $params = array();
197 if (! $showFuncFields) {
198 $params['ShowFunctionFields'] = 1;
199 } else {
200 $params['ShowFunctionFields'] = 0;
202 $params['ShowFieldTypesInDataEditView']
203 = $GLOBALS['cfg']['ShowFieldTypesInDataEditView'];
204 $params['goto'] = 'sql.php';
205 $this_url_params = array_merge($url_params, $params);
206 if (! $showFuncFields) {
207 return ' : <a href="tbl_change.php'
208 . PMA_generate_common_url($this_url_params) . '">'
209 . __('Function')
210 . '</a>' . "\n";
212 return '<th><a href="tbl_change.php'
213 . PMA_generate_common_url($this_url_params)
214 . '" title="' . __('Hide') . '">'
215 . __('Function')
216 . '</a></th>' . "\n";
220 * Show field types in data edit view in pma
222 * @param array $url_params containing url parameters
223 * @param boolean $showColumnType whether to show column type
225 * @return string an html snippet
227 function PMA_showColumnTypesInDataEditView($url_params, $showColumnType)
229 $params = array();
230 if (! $showColumnType) {
231 $params['ShowFieldTypesInDataEditView'] = 1;
232 } else {
233 $params['ShowFieldTypesInDataEditView'] = 0;
235 $params['ShowFunctionFields'] = $GLOBALS['cfg']['ShowFunctionFields'];
236 $params['goto'] = 'sql.php';
237 $this_other_url_params = array_merge($url_params, $params);
238 if (! $showColumnType) {
239 return ' : <a href="tbl_change.php'
240 . PMA_generate_common_url($this_other_url_params) . '">'
241 . __('Type') . '</a>' . "\n";
243 return '<th><a href="tbl_change.php'
244 . PMA_generate_common_url($this_other_url_params)
245 . '" title="' . __('Hide') . '">' . __('Type') . '</a></th>' . "\n";
250 * Retrieve the default for datetime data type
252 * @param array $column containing column type, Default and null
254 * @return nothing
256 function PMA_getDefaultForDatetime($column)
258 // d a t e t i m e
260 // Current date should not be set as default if the field is NULL
261 // for the current row, but do not put here the current datetime
262 // if there is a default value (the real default value will be set
263 // in the Default value logic below)
265 // Note: (tested in MySQL 4.0.16): when lang is some UTF-8,
266 // $column['Default'] is not set if it contains NULL:
267 // Array ([Field] => d [Type] => datetime [Null] => YES [Key] =>
268 // [Extra] => [True_Type] => datetime)
269 // but, look what we get if we switch to iso: (Default is NULL)
270 // Array ([Field] => d [Type] => datetime [Null] => YES [Key] =>
271 // [Default] => [Extra] => [True_Type] => datetime)
272 // so I force a NULL into it (I don't think it's possible
273 // to have an empty default value for DATETIME)
274 // then, the "if" after this one will work
275 if ($column['Type'] == 'datetime'
276 && ! isset($column['Default'])
277 && isset($column['Null'])
278 && $column['Null'] == 'YES'
280 $column['Default'] = null;
285 * Analyze the table column array
287 * @param array $column description of column in given table
288 * @param array $comments_map comments for every column that has a comment
289 * @param boolean $timestamp_seen whether a timestamp has been seen
291 * @return array description of column in given table
293 function PMA_analyzeTableColumnsArray($column, $comments_map, $timestamp_seen)
295 $column['Field_html'] = htmlspecialchars($column['Field']);
296 $column['Field_md5'] = md5($column['Field']);
297 // True_Type contains only the type (stops at first bracket)
298 $column['True_Type'] = preg_replace('@\(.*@s', '', $column['Type']);
299 PMA_getDefaultForDatetime($column);
300 $column['len'] = preg_match('@float|double@', $column['Type']) ? 100 : -1;
301 $column['Field_title'] = PMA_getColumnTitle($column, $comments_map);
302 $column['is_binary'] = PMA_isColumnBinary($column);
303 $column['is_blob'] = PMA_isColumnBlob($column);
304 $column['is_char'] = PMA_isColumnChar($column);
305 list($column['pma_type'], $column['wrap'], $column['first_timestamp'])
306 = PMA_getEnumSetAndTimestampColumns($column, $timestamp_seen);
308 return $column;
312 * Retrieve the column title
314 * @param array $column description of column in given table
315 * @param array $comments_map comments for every column that has a comment
317 * @return string column title
319 function PMA_getColumnTitle($column, $comments_map)
321 if (isset($comments_map[$column['Field']])) {
322 return '<span style="border-bottom: 1px dashed black;" title="'
323 . htmlspecialchars($comments_map[$column['Field']]) . '">'
324 . $column['Field_html'] . '</span>';
325 } else {
326 return $column['Field_html'];
331 * check whether the column is a bainary
333 * @param array $column description of column in given table
335 * @return boolean If check to ensure types such as "enum('one','two','binary',..)"
336 * or "enum('one','two','varbinary',..)" are not categorized as
337 * binary.
339 function PMA_isColumnBinary($column)
341 // The type column.
342 // Fix for bug #3152931 'ENUM and SET cannot have "Binary" option'
343 if (stripos($column['Type'], 'binary') === 0
344 || stripos($column['Type'], 'varbinary') === 0
346 return stristr($column['Type'], 'binary');
347 } else {
348 return false;
354 * check whether the column is a blob
356 * @param array $column description of column in given table
358 * @return boolean If check to ensure types such as "enum('one','two','blob',..)"
359 * or "enum('one','two','tinyblob',..)" etc. are not categorized
360 * as blob.
362 function PMA_isColumnBlob($column)
364 if (stripos($column['Type'], 'blob') === 0
365 || stripos($column['Type'], 'tinyblob') === 0
366 || stripos($column['Type'], 'mediumblob') === 0
367 || stripos($column['Type'], 'longblob') === 0
369 return stristr($column['Type'], 'blob');
370 } else {
371 return false;
376 * check is table column char
378 * @param array $column description of column in given table
380 * @return boolean If check to ensure types such as "enum('one','two','char',..)" or
381 * "enum('one','two','varchar',..)" are not categorized as char.
383 function PMA_isColumnChar($column)
385 if (stripos($column['Type'], 'char') === 0
386 || stripos($column['Type'], 'varchar') === 0
388 return stristr($column['Type'], 'char');
389 } else {
390 return false;
394 * Retrieve set, enum, timestamp table columns
396 * @param array $column description of column in given table
397 * @param boolean $timestamp_seen whether a timestamp has been seen
399 * @return array $column['pma_type'], $column['wrap'], $column['first_timestamp']
401 function PMA_getEnumSetAndTimestampColumns($column, $timestamp_seen)
403 $column['first_timestamp'] = false;
404 switch ($column['True_Type']) {
405 case 'set':
406 $column['pma_type'] = 'set';
407 $column['wrap'] = '';
408 break;
409 case 'enum':
410 $column['pma_type'] = 'enum';
411 $column['wrap'] = '';
412 break;
413 case 'timestamp':
414 if (! $timestamp_seen) { // can only occur once per table
415 $timestamp_seen = true;
416 $column['first_timestamp'] = true;
418 $column['pma_type'] = $column['Type'];
419 $column['wrap'] = ' nowrap';
420 break;
422 default:
423 $column['pma_type'] = $column['Type'];
424 $column['wrap'] = ' nowrap';
425 break;
427 return array($column['pma_type'], $column['wrap'], $column['first_timestamp']);
431 * The function column
432 * We don't want binary data to be destroyed
433 * Note: from the MySQL manual: "BINARY doesn't affect how the column is
434 * stored or retrieved" so it does not mean that the contents is binary
436 * @param array $column description of column in given table
437 * @param boolean $is_upload upload or no
438 * @param string $column_name_appendix the name atttibute
439 * @param string $unnullify_trigger validation string
440 * @param array $no_support_types list of datatypes that are not (yet)
441 * handled by PMA
442 * @param integer $tabindex_for_function +3000
443 * @param integer $tabindex tab index
444 * @param integer $idindex id index
445 * @param boolean $insert_mode insert mode or edit mode
447 * @return string an html sippet
449 function PMA_getFunctionColumn($column, $is_upload, $column_name_appendix,
450 $unnullify_trigger, $no_support_types, $tabindex_for_function,
451 $tabindex, $idindex, $insert_mode
453 $html_output = '';
454 if (($GLOBALS['cfg']['ProtectBinary'] && $column['is_blob'] && ! $is_upload)
455 || ($GLOBALS['cfg']['ProtectBinary'] === 'all' && $column['is_binary'])
456 || ($GLOBALS['cfg']['ProtectBinary'] === 'noblob' && ! $column['is_blob'])
458 $html_output .= '<td class="center">' . __('Binary') . '</td>' . "\n";
459 } elseif (strstr($column['True_Type'], 'enum')
460 || strstr($column['True_Type'], 'set')
461 || in_array($column['pma_type'], $no_support_types)
463 $html_output .= '<td class="center">--</td>' . "\n";
464 } else {
465 $html_output .= '<td>' . "\n";
467 $html_output .= '<select name="funcs' . $column_name_appendix . '"'
468 . ' ' . $unnullify_trigger
469 . ' tabindex="' . ($tabindex + $tabindex_for_function) . '"'
470 . ' id="field_' . $idindex . '_1">';
471 $html_output .= PMA_Util::getFunctionsForField($column, $insert_mode) . "\n";
473 $html_output .= '</select>' . "\n";
474 $html_output .= '</td>' . "\n";
476 return $html_output;
480 * The null column
482 * @param array $column description of column in given table
483 * @param string $column_name_appendix the name atttibute
484 * @param array $real_null_value is column value null or not null
485 * @param integer $tabindex tab index
486 * @param integer $tabindex_for_null +6000
487 * @param integer $idindex id index
488 * @param array $vkey [multi_edit]['row_id']
489 * @param array $foreigners keys into foreign fields
490 * @param array $foreignData data about the foreign keys
492 * @return string an html snippet
494 function PMA_getNullColumn($column, $column_name_appendix, $real_null_value,
495 $tabindex, $tabindex_for_null, $idindex, $vkey, $foreigners, $foreignData
497 if ($column['Null'] != 'YES') {
498 return "<td></td>\n";
500 $html_output = '';
501 $html_output .= '<td>' . "\n";
502 $html_output .= '<input type="hidden" name="fields_null_prev'
503 . $column_name_appendix . '"';
504 if ($real_null_value && !$column['first_timestamp']) {
505 $html_output .= ' value="on"';
507 $html_output .= ' />' . "\n";
509 $html_output .= '<input type="checkbox" class="checkbox_null" tabindex="'
510 . ($tabindex + $tabindex_for_null) . '"'
511 . ' name="fields_null' . $column_name_appendix . '"';
512 if ($real_null_value) {
513 $html_output .= ' checked="checked"';
515 $html_output .= ' id="field_' . ($idindex) . '_2" />';
517 // nullify_code is needed by the js nullify() function
518 $nullify_code = PMA_getNullifyCodeForNullColumn(
519 $column, $foreigners, $foreignData
521 // to be able to generate calls to nullify() in jQuery
522 $html_output .= '<input type="hidden" class="nullify_code" name="nullify_code'
523 . $column_name_appendix . '" value="' . $nullify_code . '" />';
524 $html_output .= '<input type="hidden" class="hashed_field" name="hashed_field'
525 . $column_name_appendix . '" value="' . $column['Field_md5'] . '" />';
526 $html_output .= '<input type="hidden" class="multi_edit" name="multi_edit'
527 . $column_name_appendix . '" value="' . PMA_escapeJsString($vkey) . '" />';
528 $html_output .= '</td>' . "\n";
530 return $html_output;
534 * Retrieve the nullify code for the null column
536 * @param array $column description of column in given table
537 * @param array $foreigners keys into foreign fields
538 * @param array $foreignData data about the foreign keys
540 * @return integer $nullify_code
542 function PMA_getNullifyCodeForNullColumn($column, $foreigners, $foreignData)
544 if (strstr($column['True_Type'], 'enum')) {
545 if (strlen($column['Type']) > 20) {
546 $nullify_code = '1';
547 } else {
548 $nullify_code = '2';
550 } elseif (strstr($column['True_Type'], 'set')) {
551 $nullify_code = '3';
552 } elseif ($foreigners
553 && isset($foreigners[$column['Field']])
554 && $foreignData['foreign_link'] == false
556 // foreign key in a drop-down
557 $nullify_code = '4';
558 } elseif ($foreigners
559 && isset($foreigners[$column['Field']])
560 && $foreignData['foreign_link'] == true
562 // foreign key with a browsing icon
563 $nullify_code = '6';
564 } else {
565 $nullify_code = '5';
567 return $nullify_code;
571 * Get the HTML elements for value column in insert form
573 * @param array $column description of column in given table
574 * @param string $backup_field hidden input field
575 * @param string $column_name_appendix the name atttibute
576 * @param string $unnullify_trigger validation string
577 * @param integer $tabindex tab index
578 * @param integer $tabindex_for_value offset for the values tabindex
579 * @param integer $idindex id index
580 * @param array $data description of the column field
581 * @param array $special_chars special characters
582 * @param array $foreignData data about the foreign keys
583 * @param boolean $odd_row whether row is odd
584 * @param array $paramTableDbArray array containing $table and $db
585 * @param array $rownumber_param &amp;rownumber=row_id
586 * @param array $titles An HTML IMG tag for a particular icon from
587 * a theme, which may be an actual file or
588 * an icon from a sprite
589 * @param array $text_dir text direction
590 * @param string $special_chars_encoded replaced char if the string starts
591 * with a \r\n pair (0x0d0a) add an extra \n
592 * @param string $vkey [multi_edit]['row_id']
593 * @param boolean $is_upload is upload or not
594 * @param integer $biggest_max_file_size 0 intger
595 * @param string $default_char_editing default char editing mode which is stroe
596 * in the config.inc.php script
597 * @param array $no_support_types list of datatypes that are not (yet)
598 * handled by PMA
599 * @param array $gis_data_types list of GIS data types
600 * @param array $extracted_columnspec associative array containing type,
601 * spec_in_brackets and possibly
602 * enum_set_values (another array)
604 * @return string an html snippet
606 function PMA_getValueColumn($column, $backup_field, $column_name_appendix,
607 $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
608 $special_chars, $foreignData, $odd_row, $paramTableDbArray, $rownumber_param,
609 $titles, $text_dir, $special_chars_encoded, $vkey,
610 $is_upload, $biggest_max_file_size,
611 $default_char_editing, $no_support_types, $gis_data_types, $extracted_columnspec
613 $html_output = '';
615 if ($foreignData['foreign_link'] == true) {
616 $html_output .= PMA_getForeignLink(
617 $column, $backup_field, $column_name_appendix,
618 $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
619 $paramTableDbArray, $rownumber_param, $titles
622 } elseif (is_array($foreignData['disp_row'])) {
623 $html_output .= PMA_dispRowForeignData(
624 $backup_field, $column_name_appendix,
625 $unnullify_trigger, $tabindex, $tabindex_for_value,
626 $idindex, $data, $foreignData
629 } elseif ($GLOBALS['cfg']['LongtextDoubleTextarea']
630 && strstr($column['pma_type'], 'longtext')
632 $html_output = '&nbsp;</td>';
633 $html_output .= '</tr>';
634 $html_output .= '<tr class="' . ($odd_row ? 'odd' : 'even') . '">'
635 . '<td colspan="5" class="right">';
636 $html_output .= PMA_getTextarea(
637 $column, $backup_field, $column_name_appendix, $unnullify_trigger,
638 $tabindex, $tabindex_for_value, $idindex, $text_dir,
639 $special_chars_encoded
642 } elseif (strstr($column['pma_type'], 'text')) {
644 $html_output .= PMA_getTextarea(
645 $column, $backup_field, $column_name_appendix, $unnullify_trigger,
646 $tabindex, $tabindex_for_value, $idindex, $text_dir,
647 $special_chars_encoded
649 $html_output .= "\n";
650 if (strlen($special_chars) > 32000) {
651 $html_output .= "</td>\n";
652 $html_output .= '<td>' . __(
653 'Because of its length,<br /> this column might not be editable'
657 } elseif ($column['pma_type'] == 'enum') {
658 $html_output .= PMA_getPmaTypeEnum(
659 $column, $backup_field, $column_name_appendix, $extracted_columnspec,
660 $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data
663 } elseif ($column['pma_type'] == 'set') {
664 $html_output .= PMA_getPmaTypeSet(
665 $column, $extracted_columnspec, $backup_field,
666 $column_name_appendix, $unnullify_trigger, $tabindex,
667 $tabindex_for_value, $idindex, $data
670 } elseif ($column['is_binary'] || $column['is_blob']) {
671 $html_output .= PMA_getBinaryAndBlobColumn(
672 $column, $data, $special_chars, $biggest_max_file_size,
673 $backup_field, $column_name_appendix, $unnullify_trigger, $tabindex,
674 $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
675 $vkey, $is_upload
678 } elseif (! in_array($column['pma_type'], $no_support_types)) {
679 $html_output .= PMA_getNoSupportTypes(
680 $column, $default_char_editing, $backup_field,
681 $column_name_appendix, $unnullify_trigger, $tabindex, $special_chars,
682 $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
683 $data, $extracted_columnspec
687 if (in_array($column['pma_type'], $gis_data_types)) {
688 $html_output .= PMA_getHTMLforGisDataTypes();
691 return $html_output;
695 * Get HTML for foreign link in insert form
697 * @param array $column description of column in given table
698 * @param string $backup_field hidden input field
699 * @param string $column_name_appendix the name atttibute
700 * @param string $unnullify_trigger validation string
701 * @param integer $tabindex tab index
702 * @param integer $tabindex_for_value offset for the values tabindex
703 * @param integer $idindex id index
704 * @param array $data data to edit
705 * @param array $paramTableDbArray array containing $table and $db
706 * @param array $rownumber_param &amp;rownumber=row_id
707 * @param array $titles An HTML IMG tag for a particular icon from
708 * a theme, which may be an actual file or
709 * an icon from a sprite
711 * @return string an html snippet
713 function PMA_getForeignLink($column, $backup_field, $column_name_appendix,
714 $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
715 $paramTableDbArray, $rownumber_param, $titles
717 list($table, $db) = $paramTableDbArray;
718 $html_output = '';
719 $html_output .= $backup_field . "\n";
721 $html_output .= '<input type="hidden" name="fields_type'
722 . $column_name_appendix . '" value="foreign" />';
724 $html_output .= '<input type="text" name="fields' . $column_name_appendix . '" '
725 . 'class="textfield" '
726 . $unnullify_trigger . ' '
727 . 'tabindex="' . ($tabindex + $tabindex_for_value) . '" '
728 . 'id="field_' . ($idindex) . '_3" '
729 . 'value="' . htmlspecialchars($data) . '" />';
731 $html_output .= '<a class="foreign_values_anchor" target="_blank" '
732 . 'onclick="window.open(this.href,\'foreigners\', \'width=640,height=240,'
733 . 'scrollbars=yes,resizable=yes\'); return false;" '
734 . 'href="browse_foreigners.php?'
735 . PMA_generate_common_url($db, $table) . '&amp;field='
736 . PMA_escapeJsString(urlencode($column['Field']) . $rownumber_param) . '">'
737 . str_replace("'", "\'", $titles['Browse']) . '</a>';
738 return $html_output;
742 * Get HTML to display foreign data
744 * @param string $backup_field hidden input field
745 * @param string $column_name_appendix the name atttibute
746 * @param string $unnullify_trigger validation string
747 * @param integer $tabindex tab index
748 * @param integer $tabindex_for_value offset for the values tabindex
749 * @param integer $idindex id index
750 * @param array $data data to edit
751 * @param array $foreignData data about the foreign keys
753 * @return string an html snippet
755 function PMA_dispRowForeignData($backup_field, $column_name_appendix,
756 $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex, $data,
757 $foreignData
759 $html_output = '';
760 $html_output .= $backup_field . "\n";
761 $html_output .= '<input type="hidden"'
762 . ' name="fields_type' . $column_name_appendix . '"'
763 . ' value="foreign" />';
765 $html_output .= '<select name="fields' . $column_name_appendix . '"'
766 . ' ' . $unnullify_trigger
767 . ' class="textfield"'
768 . ' tabindex="' . ($tabindex + $tabindex_for_value). '"'
769 . ' id="field_' . $idindex . '_3">';
770 $html_output .= PMA_foreignDropdown(
771 $foreignData['disp_row'], $foreignData['foreign_field'],
772 $foreignData['foreign_display'], $data,
773 $GLOBALS['cfg']['ForeignKeyMaxLimit']
775 $html_output .= '</select>';
777 return $html_output;
781 * Get HTML textarea for insert form
783 * @param array $column column information
784 * @param string $backup_field hidden input field
785 * @param string $column_name_appendix the name atttibute
786 * @param string $unnullify_trigger validation string
787 * @param integer $tabindex tab index
788 * @param integer $tabindex_for_value offset for the values tabindex
789 * @param integer $idindex id index
790 * @param array $text_dir text direction
791 * @param array $special_chars_encoded replaced char if the string starts
792 * with a \r\n pair (0x0d0a) add an extra \n
794 * @return string an html snippet
796 function PMA_getTextarea($column, $backup_field, $column_name_appendix,
797 $unnullify_trigger,
798 $tabindex, $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded
800 $the_class = '';
801 $textAreaRows = $GLOBALS['cfg']['TextareaRows'];
802 $textareaCols = $GLOBALS['cfg']['TextareaCols'];
804 if ($column['is_char']) {
805 $the_class = 'char';
806 $textAreaRows = $GLOBALS['cfg']['CharTextareaRows'];
807 $textareaCols = $GLOBALS['cfg']['CharTextareaCols'];
808 } elseif ($GLOBALS['cfg']['LongtextDoubleTextarea']
809 && strstr($column['pma_type'], 'longtext')
811 $textAreaRows = $GLOBALS['cfg']['TextareaRows'] * 2;
812 $textareaCols = $GLOBALS['cfg']['TextareaCols'] * 2;
814 $html_output = $backup_field . "\n"
815 . '<textarea name="fields' . $column_name_appendix . '"'
816 . ' class="' . $the_class . '"'
817 . ' rows="' . $textAreaRows . '"'
818 . ' cols="' . $textareaCols . '"'
819 . ' dir="' . $text_dir . '"'
820 . ' id="field_' . ($idindex) . '_3"'
821 . ' ' . $unnullify_trigger
822 . ' tabindex="' . ($tabindex + $tabindex_for_value) . '">'
823 . $special_chars_encoded
824 . '</textarea>';
826 return $html_output;
830 * Get HTML for enum type
832 * @param type $column description of column in given table
833 * @param type $backup_field hidden input field
834 * @param type $column_name_appendix the name atttibute
835 * @param type $extracted_columnspec associative array containing type,
836 * spec_in_brackets and possibly
837 * enum_set_values (another array)
838 * @param type $unnullify_trigger validation string
839 * @param type $tabindex tab index
840 * @param type $tabindex_for_value offset for the values tabindex
841 * @param type $idindex id index
842 * @param type $data data to edit
844 * @return type string an html snippet
846 function PMA_getPmaTypeEnum($column, $backup_field, $column_name_appendix,
847 $extracted_columnspec, $unnullify_trigger, $tabindex, $tabindex_for_value,
848 $idindex, $data
850 $html_output = '';
851 if (! isset($column['values'])) {
852 $column['values'] = PMA_getColumnEnumValues(
853 $column, $extracted_columnspec
856 $column_enum_values = $column['values'];
857 $html_output .= '<input type="hidden" name="fields_type'
858 . $column_name_appendix. '" value="enum" />';
859 $html_output .= '<input type="hidden" name="fields'
860 . $column_name_appendix . '" value="" />';
861 $html_output .= "\n" . ' ' . $backup_field . "\n";
862 if (strlen($column['Type']) > 20) {
863 $html_output .= PMA_getDropDownDependingOnLength(
864 $column, $column_name_appendix, $unnullify_trigger,
865 $tabindex, $tabindex_for_value, $idindex, $data, $column_enum_values
867 } else {
868 $html_output .= PMA_getRadioButtonDependingOnLength(
869 $column_name_appendix, $unnullify_trigger,
870 $tabindex, $column, $tabindex_for_value,
871 $idindex, $data, $column_enum_values
874 return $html_output;
878 * Get column values
880 * @param array $column description of column in given table
881 * @param array $extracted_columnspec associative array containing type,
882 * spec_in_brackets and possibly enum_set_values
883 * (another array)
885 * @return array column values as an associative array
887 function PMA_getColumnEnumValues($column, $extracted_columnspec)
889 $column['values'] = array();
890 foreach ($extracted_columnspec['enum_set_values'] as $val) {
891 $column['values'][] = array(
892 'plain' => $val,
893 'html' => htmlspecialchars($val),
896 return $column['values'];
900 * Get HTML drop down for more than 20 string length
902 * @param array $column description of column in given table
903 * @param string $column_name_appendix the name atttibute
904 * @param string $unnullify_trigger validation string
905 * @param integer $tabindex tab index
906 * @param integer $tabindex_for_value offset for the values tabindex
907 * @param integer $idindex id index
908 * @param array $data data to edit
909 * @param array $column_enum_values $column['values']
911 * @return string an html snippet
913 function PMA_getDropDownDependingOnLength(
914 $column, $column_name_appendix, $unnullify_trigger,
915 $tabindex, $tabindex_for_value, $idindex, $data, $column_enum_values
917 $html_output = '<select name="fields' . $column_name_appendix . '"'
918 . ' ' . $unnullify_trigger
919 . ' class="textfield"'
920 . ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
921 . ' id="field_' . ($idindex) . '_3">';
922 $html_output .= '<option value="">&nbsp;</option>' . "\n";
924 foreach ($column_enum_values as $enum_value) {
925 $html_output .= '<option value="' . $enum_value['html'] . '"';
926 if ($data == $enum_value['plain']
927 || ($data == ''
928 && (! isset($_REQUEST['where_clause']) || $column['Null'] != 'YES')
929 && isset($column['Default'])
930 && $enum_value['plain'] == $column['Default'])
932 $html_output .= ' selected="selected"';
934 $html_output .= '>' . $enum_value['html'] . '</option>' . "\n";
936 $html_output .= '</select>';
937 return $html_output;
941 * Get HTML radio button for less than 20 string length
943 * @param string $column_name_appendix the name atttibute
944 * @param string $unnullify_trigger validation string
945 * @param integer $tabindex tab index
946 * @param array $column description of column in given table
947 * @param integer $tabindex_for_value offset for the values tabindex
948 * @param integer $idindex id index
949 * @param array $data data to edit
950 * @param array $column_enum_values $column['values']
952 * @return string an html snippet
954 function PMA_getRadioButtonDependingOnLength(
955 $column_name_appendix, $unnullify_trigger,
956 $tabindex, $column, $tabindex_for_value, $idindex, $data, $column_enum_values
958 $j = 0;
959 $html_output = '';
960 foreach ($column_enum_values as $enum_value) {
961 $html_output .= ' '
962 . '<input type="radio" name="fields' . $column_name_appendix . '"'
963 . ' class="textfield"'
964 . ' value="' . $enum_value['html'] . '"'
965 . ' id="field_' . ($idindex) . '_3_' . $j . '"'
966 . ' ' . $unnullify_trigger;
967 if ($data == $enum_value['plain']
968 || ($data == ''
969 && (! isset($_REQUEST['where_clause']) || $column['Null'] != 'YES')
970 && isset($column['Default'])
971 && $enum_value['plain'] == $column['Default'])
973 $html_output .= ' checked="checked"';
975 $html_output .= ' tabindex="' . ($tabindex + $tabindex_for_value) . '" />';
976 $html_output .= '<label for="field_' . $idindex . '_3_' . $j . '">'
977 . $enum_value['html'] . '</label>' . "\n";
978 $j++;
980 return $html_output;
984 * Get the HTML for 'set' pma type
986 * @param array $column description of column in given table
987 * @param array $extracted_columnspec associative array containing type,
988 * spec_in_brackets and possibly
989 * enum_set_values (another array)
990 * @param string $backup_field hidden input field
991 * @param string $column_name_appendix the name atttibute
992 * @param string $unnullify_trigger validation string
993 * @param integer $tabindex tab index
994 * @param integer $tabindex_for_value offset for the values tabindex
995 * @param integer $idindex id index
996 * @param array $data description of the column field
998 * @return string an html snippet
1000 function PMA_getPmaTypeSet(
1001 $column, $extracted_columnspec, $backup_field,
1002 $column_name_appendix, $unnullify_trigger, $tabindex,
1003 $tabindex_for_value, $idindex, $data
1005 list($column_set_values, $select_size) = PMA_getColumnSetValueAndSelectSize(
1006 $column, $extracted_columnspec
1008 $vset = array_flip(explode(',', $data));
1009 $html_output = $backup_field . "\n";
1010 $html_output .= '<input type="hidden" name="fields_type'
1011 . $column_name_appendix . '" value="set" />';
1012 $html_output .= '<select name="fields' . $column_name_appendix . '[]' . '"'
1013 . ' class="textfield"'
1014 . ' size="' . $select_size . '"'
1015 . ' multiple="multiple"'
1016 . ' ' . $unnullify_trigger
1017 . ' tabindex="' . ($tabindex + $tabindex_for_value) . '"'
1018 . ' id="field_' . ($idindex) . '_3">';
1019 foreach ($column_set_values as $column_set_value) {
1020 $html_output .= '<option value="' . $column_set_value['html'] . '"';
1021 if (isset($vset[$column_set_value['plain']])) {
1022 $html_output .= ' selected="selected"';
1024 $html_output .= '>' . $column_set_value['html'] . '</option>' . "\n";
1026 $html_output .= '</select>';
1027 return $html_output;
1031 * Retrieve column 'set' value and select size
1033 * @param array $column description of column in given table
1034 * @param array $extracted_columnspec associative array containing type,
1035 * spec_in_brackets and possibly enum_set_values
1036 * (another array)
1038 * @return array $column['values'], $column['select_size']
1040 function PMA_getColumnSetValueAndSelectSize($column, $extracted_columnspec)
1042 if (! isset($column['values'])) {
1043 $column['values'] = array();
1044 foreach ($extracted_columnspec['enum_set_values'] as $val) {
1045 $column['values'][] = array(
1046 'plain' => $val,
1047 'html' => htmlspecialchars($val),
1050 $column['select_size'] = min(4, count($column['values']));
1052 return array($column['values'], $column['select_size']);
1056 * Get HTML for binary and blob column
1058 * @param array $column description of column in given table
1059 * @param array $data data to edit
1060 * @param array $special_chars special characters
1061 * @param integer $biggest_max_file_size biggest max file size for uploading
1062 * @param string $backup_field hidden input field
1063 * @param string $column_name_appendix the name atttibute
1064 * @param string $unnullify_trigger validation string
1065 * @param integer $tabindex tab index
1066 * @param integer $tabindex_for_value offset for the values tabindex
1067 * @param integer $idindex id index
1068 * @param string $text_dir text direction
1069 * @param string $special_chars_encoded replaced char if the string starts
1070 * with a \r\n pair (0x0d0a) add an extra \n
1071 * @param string $vkey [multi_edit]['row_id']
1072 * @param boolean $is_upload is upload or not
1074 * @return string an html snippet
1076 function PMA_getBinaryAndBlobColumn(
1077 $column, $data, $special_chars, $biggest_max_file_size,
1078 $backup_field, $column_name_appendix, $unnullify_trigger, $tabindex,
1079 $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded,
1080 $vkey, $is_upload
1082 $html_output = '';
1083 if (($GLOBALS['cfg']['ProtectBinary'] && $column['is_blob'])
1084 || ($GLOBALS['cfg']['ProtectBinary'] == 'all' && $column['is_binary'])
1085 || ($GLOBALS['cfg']['ProtectBinary'] == 'noblob' && !$column['is_blob'])
1087 $html_output .= __('Binary - do not edit');
1088 if (isset($data)) {
1089 $data_size = PMA_Util::formatByteDown(
1090 strlen(stripslashes($data)), 3, 1
1092 $html_output .= ' ('. $data_size [0] . ' ' . $data_size[1] . ')';
1093 unset($data_size);
1095 $html_output .= '<input type="hidden" name="fields_type'
1096 . $column_name_appendix . '" value="protected" />'
1097 . '<input type="hidden" name="fields'
1098 . $column_name_appendix . '" value="" />';
1099 } elseif ($column['is_blob']) {
1100 $html_output .= "\n" . PMA_getTextarea(
1101 $column, $backup_field, $column_name_appendix, $unnullify_trigger,
1102 $tabindex, $tabindex_for_value, $idindex, $text_dir,
1103 $special_chars_encoded
1105 } else {
1106 // field size should be at least 4 and max $GLOBALS['cfg']['LimitChars']
1107 $fieldsize = min(max($column['len'], 4), $GLOBALS['cfg']['LimitChars']);
1108 $html_output .= "\n" . $backup_field . "\n" . PMA_getHTMLinput(
1109 $column, $column_name_appendix, $special_chars, $fieldsize,
1110 $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex
1114 if ($is_upload && $column['is_blob']) {
1115 $html_output .= '<br />'
1116 . '<input type="file"'
1117 . ' name="fields_upload' . $vkey . '[' . $column['Field_md5'] . ']"'
1118 . ' class="textfield" id="field_' . $idindex . '_3" size="10"'
1119 . ' ' . $unnullify_trigger . '/>&nbsp;';
1120 list($html_out, $biggest_max_file_size) = PMA_getMaxUploadSize(
1121 $column, $biggest_max_file_size
1123 $html_output .= $html_out;
1126 if (!empty($GLOBALS['cfg']['UploadDir'])) {
1127 $html_output .= PMA_getSelectOptionForUpload($vkey, $column);
1130 return $html_output;
1134 * Get HTML input type
1136 * @param array $column description of column in given table
1137 * @param string $column_name_appendix the name atttibute
1138 * @param array $special_chars special characters
1139 * @param integer $fieldsize html field size
1140 * @param string $unnullify_trigger validation string
1141 * @param integer $tabindex tab index
1142 * @param integer $tabindex_for_value offset for the values tabindex
1143 * @param integer $idindex id index
1145 * @return string an html snippet
1147 function PMA_getHTMLinput($column, $column_name_appendix, $special_chars,
1148 $fieldsize, $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex
1150 $the_class = 'textfield';
1151 if ($column['pma_type'] == 'date') {
1152 $the_class .= ' datefield';
1153 } elseif ($column['pma_type'] == 'datetime'
1154 || substr($column['pma_type'], 0, 9) == 'timestamp'
1156 $the_class .= ' datetimefield';
1158 return '<input type="text" name="fields' . $column_name_appendix . '"'
1159 . ' value="' . $special_chars . '" size="' . $fieldsize . '"'
1160 . ' class="' . $the_class . '" ' . $unnullify_trigger
1161 . ' tabindex="' . ($tabindex + $tabindex_for_value). '"'
1162 . ' id="field_' . ($idindex) . '_3" />';
1166 * Get HTML select option for upload
1168 * @param string $vkey [multi_edit]['row_id']
1169 * @param array $column description of column in given table
1171 * @return string an html snippet
1173 function PMA_getSelectOptionForUpload($vkey, $column)
1175 $files = PMA_getFileSelectOptions(
1176 PMA_Util::userDir($GLOBALS['cfg']['UploadDir'])
1179 if ($files === false) {
1180 return '<font color="red">' . __('Error') . '</font><br />' . "\n"
1181 . __('The directory you set for upload work cannot be reached') . "\n";
1182 } elseif (!empty($files)) {
1183 return "<br />\n"
1184 . '<i>' . __('Or') . '</i>' . ' '
1185 . __('web server upload directory') . ':<br />' . "\n"
1186 . '<select size="1" name="fields_uploadlocal'
1187 . $vkey . '[' . $column['Field_md5'] . ']">' . "\n"
1188 . '<option value="" selected="selected"></option>' . "\n"
1189 . $files
1190 . '</select>' . "\n";
1195 * Retrieve the maximum upload file size
1197 * @param array $column description of column in given table
1198 * @param integer $biggest_max_file_size biggest max file size for uploading
1200 * @return array an html snippet and $biggest_max_file_size
1202 function PMA_getMaxUploadSize($column, $biggest_max_file_size)
1204 // find maximum upload size, based on field type
1206 * @todo with functions this is not so easy, as you can basically
1207 * process any data with function like MD5
1209 global $max_upload_size;
1210 $max_field_sizes = array(
1211 'tinyblob' => '256',
1212 'blob' => '65536',
1213 'mediumblob' => '16777216',
1214 'longblob' => '4294967296' // yeah, really
1217 $this_field_max_size = $max_upload_size; // from PHP max
1218 if ($this_field_max_size > $max_field_sizes[$column['pma_type']]) {
1219 $this_field_max_size = $max_field_sizes[$column['pma_type']];
1221 $html_output
1222 = PMA_Util::getFormattedMaximumUploadSize(
1223 $this_field_max_size
1224 ) . "\n";
1225 // do not generate here the MAX_FILE_SIZE, because we should
1226 // put only one in the form to accommodate the biggest field
1227 if ($this_field_max_size > $biggest_max_file_size) {
1228 $biggest_max_file_size = $this_field_max_size;
1230 return array($html_output, $biggest_max_file_size);
1234 * Get HTML for pma no support types
1236 * @param array $column description of column in given table
1237 * @param string $default_char_editing default char editing mode which is stroe
1238 * in the config.inc.php script
1239 * @param string $backup_field hidden input field
1240 * @param string $column_name_appendix the name atttibute
1241 * @param string $unnullify_trigger validation string
1242 * @param integer $tabindex tab index
1243 * @param array $special_chars apecial characters
1244 * @param integer $tabindex_for_value offset for the values tabindex
1245 * @param integer $idindex id index
1246 * @param string $text_dir text direction
1247 * @param array $special_chars_encoded replaced char if the string starts
1248 * with a \r\n pair (0x0d0a) add an extra \n
1249 * @param strign $data data to edit
1250 * @param array $extracted_columnspec associative array containing type,
1251 * spec_in_brackets and possibly
1252 * enum_set_values (another array)
1254 * @return string an html snippet
1256 function PMA_getNoSupportTypes($column, $default_char_editing, $backup_field,
1257 $column_name_appendix, $unnullify_trigger, $tabindex, $special_chars,
1258 $tabindex_for_value, $idindex, $text_dir, $special_chars_encoded, $data,
1259 $extracted_columnspec
1261 $fieldsize = PMA_getColumnSize($column, $extracted_columnspec);
1262 $html_output = $backup_field . "\n";
1263 if ($column['is_char']
1264 && ($GLOBALS['cfg']['CharEditing'] == 'textarea'
1265 || strpos($data, "\n") !== false)
1267 $html_output .= "\n";
1268 $GLOBALS['cfg']['CharEditing'] = $default_char_editing;
1269 $html_output .= PMA_getTextarea(
1270 $column, $backup_field, $column_name_appendix, $unnullify_trigger,
1271 $tabindex, $tabindex_for_value, $idindex, $text_dir,
1272 $special_chars_encoded
1274 } else {
1275 $html_output .= PMA_getHTMLinput(
1276 $column, $column_name_appendix, $special_chars,
1277 $fieldsize, $unnullify_trigger, $tabindex, $tabindex_for_value, $idindex
1280 if ($column['Extra'] == 'auto_increment') {
1281 $html_output .= '<input type="hidden" name="auto_increment'
1282 . $column_name_appendix . '" value="1" />';
1284 if (substr($column['pma_type'], 0, 9) == 'timestamp') {
1285 $html_output .= '<input type="hidden" name="fields_type'
1286 . $column_name_appendix . '" value="timestamp" />';
1288 if (substr($column['pma_type'], 0, 8) == 'datetime') {
1289 $html_output .= '<input type="hidden" name="fields_type'
1290 . $column_name_appendix . '" value="datetime" />';
1292 if ($column['True_Type'] == 'bit') {
1293 $html_output .= '<input type="hidden" name="fields_type'
1294 . $column_name_appendix . '" value="bit" />';
1296 if ($column['pma_type'] == 'date'
1297 || $column['pma_type'] == 'datetime'
1298 || substr($column['pma_type'], 0, 9) == 'timestamp'
1300 // the _3 suffix points to the date field
1301 // the _2 suffix points to the corresponding NULL checkbox
1302 // in dateFormat, 'yy' means the year with 4 digits
1305 return $html_output;
1309 * Get the field size
1311 * @param array $column description of column in given table
1312 * @param array $extracted_columnspec associative array containing type,
1313 * spec_in_brackets and possibly enum_set_values
1314 * (another array)
1316 * @return integer field size
1318 function PMA_getColumnSize($column, $extracted_columnspec)
1320 if ($column['is_char']) {
1321 $fieldsize = $extracted_columnspec['spec_in_brackets'];
1322 if ($fieldsize > $GLOBALS['cfg']['MaxSizeForInputField']) {
1324 * This case happens for CHAR or VARCHAR columns which have
1325 * a size larger than the maximum size for input field.
1327 $GLOBALS['cfg']['CharEditing'] = 'textarea';
1329 } else {
1331 * This case happens for example for INT or DATE columns;
1332 * in these situations, the value returned in $column['len']
1333 * seems appropriate.
1335 $fieldsize = $column['len'];
1337 return min(
1338 max($fieldsize, $GLOBALS['cfg']['MinSizeForInputField']),
1339 $GLOBALS['cfg']['MaxSizeForInputField']
1344 * Get HTML for gis data types
1346 * @return string an html snippet
1348 function PMA_getHTMLforGisDataTypes()
1350 $edit_str = PMA_Util::getIcon('b_edit.png', __('Edit/Insert'));
1351 return '<span class="open_gis_editor">'
1352 . PMA_Util::linkOrButton(
1353 '#', $edit_str, array(), false, false, '_blank'
1355 . '</span>';
1359 * get html for continue insertion form
1361 * @param string $table name of the table
1362 * @param string $db name of the database
1363 * @param array $where_clause_array array of where clauses
1364 * @param string $err_url error url
1366 * @return string an html snippet
1368 function PMA_getContinueInsertionForm($table, $db, $where_clause_array, $err_url)
1370 $html_output = '<form id="continueForm" method="post"'
1371 . ' action="tbl_replace.php" name="continueForm">'
1372 . PMA_generate_common_hidden_inputs($db, $table)
1373 . '<input type="hidden" name="goto"'
1374 . ' value="' . htmlspecialchars($GLOBALS['goto']) . '" />'
1375 . '<input type="hidden" name="err_url"'
1376 . ' value="' . htmlspecialchars($err_url) . '" />'
1377 . '<input type="hidden" name="sql_query"'
1378 . ' value="' . htmlspecialchars($_REQUEST['sql_query']) . '" />';
1380 if (isset($_REQUEST['where_clause'])) {
1381 foreach ($where_clause_array as $key_id => $where_clause) {
1383 $html_output .= '<input type="hidden"'
1384 . ' name="where_clause[' . $key_id . ']"'
1385 . ' value="' . htmlspecialchars(trim($where_clause)) . '" />'. "\n";
1388 $tmp = '<select name="insert_rows" id="insert_rows">' . "\n";
1389 $option_values = array(1, 2, 5, 10, 15, 20, 30, 40);
1391 foreach ($option_values as $value) {
1392 $tmp .= '<option value="' . $value . '"';
1393 if ($value == $GLOBALS['cfg']['InsertRows']) {
1394 $tmp .= ' selected="selected"';
1396 $tmp .= '>' . $value . '</option>' . "\n";
1399 $tmp .= '</select>' . "\n";
1400 $html_output .= "\n" . sprintf(__('Continue insertion with %s rows'), $tmp);
1401 unset($tmp);
1402 $html_output .= '</form>' . "\n";
1403 return $html_output;
1407 * Get action panel
1409 * @param array $where_clause where clause
1410 * @param string $after_insert insert mode, e.g. new_insert, same_insert
1411 * @param integer $tabindex tab index
1412 * @param integer $tabindex_for_value offset for the values tabindex
1413 * @param boolean $found_unique_key boolean variable for unique key
1415 * @return string an html snippet
1417 function PMA_getActionsPanel($where_clause, $after_insert, $tabindex,
1418 $tabindex_for_value, $found_unique_key
1420 $html_output = '<fieldset id="actions_panel">'
1421 . '<table cellpadding="5" cellspacing="0">'
1422 . '<tr>'
1423 . '<td class="nowrap vmiddle">'
1424 . PMA_getSubmitTypeDropDown($where_clause, $tabindex, $tabindex_for_value)
1425 . "\n";
1427 $html_output .= '</td>'
1428 . '<td class="vmiddle">'
1429 . '&nbsp;&nbsp;&nbsp;<strong>'
1430 . __('and then') . '</strong>&nbsp;&nbsp;&nbsp;'
1431 . '</td>'
1432 . '<td class="nowrap vmiddle">'
1433 . PMA_getAfterInsertDropDown(
1434 $where_clause, $after_insert, $found_unique_key
1436 . '</td>'
1437 . '</tr>';
1438 $html_output .='<tr>'
1439 . PMA_getSumbitAndResetButtonForActionsPanel($tabindex, $tabindex_for_value)
1440 . '</tr>'
1441 . '</table>'
1442 . '</fieldset>';
1443 return $html_output;
1447 * Get a HTML drop down for submit types
1449 * @param array $where_clause where clause
1450 * @param integer $tabindex tab index
1451 * @param integer $tabindex_for_value offset for the values tabindex
1453 * @return string an html snippet
1455 function PMA_getSubmitTypeDropDown($where_clause, $tabindex, $tabindex_for_value)
1457 $html_output = '<select name="submit_type" class="control_at_footer" tabindex="'
1458 . ($tabindex + $tabindex_for_value + 1) . '">';
1459 if (isset($where_clause)) {
1460 $html_output .= '<option value="save">' . __('Save') . '</option>';
1462 $html_output .= '<option value="insert">'
1463 . __('Insert as new row')
1464 . '</option>'
1465 . '<option value="insertignore">'
1466 . __('Insert as new row and ignore errors')
1467 . '</option>'
1468 . '<option value="showinsert">'
1469 . __('Show insert query')
1470 . '</option>'
1471 . '</select>';
1472 return $html_output;
1476 * Get HTML drop down for after insert
1478 * @param array $where_clause where clause
1479 * @param string $after_insert insert mode, e.g. new_insert, same_insert
1480 * @param boolean $found_unique_key boolean variable for unique key
1482 * @return string an html snippet
1484 function PMA_getAfterInsertDropDown($where_clause, $after_insert, $found_unique_key)
1486 $html_output = '<select name="after_insert">'
1487 . '<option value="back" '
1488 . ($after_insert == 'back' ? 'selected="selected"' : '') . '>'
1489 . __('Go back to previous page') . '</option>'
1490 . '<option value="new_insert" '
1491 . ($after_insert == 'new_insert' ? 'selected="selected"' : '') . '>'
1492 . __('Insert another new row') . '</option>';
1494 if (isset($where_clause)) {
1495 $html_output .= '<option value="same_insert" '
1496 . ($after_insert == 'same_insert' ? 'selected="selected"' : '') . '>'
1497 . __('Go back to this page') . '</option>';
1499 // If we have just numeric primary key, we can also edit next
1500 // in 2.8.2, we were looking for `field_name` = numeric_value
1501 //if (preg_match('@^[\s]*`[^`]*` = [0-9]+@', $where_clause)) {
1502 // in 2.9.0, we are looking for `table_name`.`field_name` = numeric_value
1503 $is_numeric = false;
1504 if (! is_array($where_clause)) {
1505 $where_clause = array($where_clause);
1507 for ($i = 0; $i < count($where_clause); $i++) {
1508 $is_numeric = preg_match(
1509 '@^[\s]*`[^`]*`[\.]`[^`]*` = [0-9]+@',
1510 $where_clause[$i]
1512 if ($is_numeric == true) {
1513 break;
1516 if ($found_unique_key && $is_numeric) {
1517 $html_output .= '<option value="edit_next" '
1518 . ($after_insert == 'edit_next' ? 'selected="selected"' : '') . '>'
1519 . __('Edit next row') . '</option>';
1523 $html_output .= '</select>';
1524 return $html_output;
1529 * get Submit button and Reset button for action panel
1531 * @param integer $tabindex tab index
1532 * @param integer $tabindex_for_value offset for the values tabindex
1534 * @return string an html snippet
1536 function PMA_getSumbitAndResetButtonForActionsPanel($tabindex, $tabindex_for_value)
1538 return '<td>'
1539 . PMA_Util::showHint(
1541 'Use TAB key to move from value to value,'
1542 . ' or CTRL+arrows to move anywhere'
1545 . '</td>'
1546 . '<td colspan="3" class="right vmiddle">'
1547 . '<input type="submit" class="control_at_footer" value="' . __('Go') . '"'
1548 . 'tabindex="' . ($tabindex + $tabindex_for_value + 6) . '" id="buttonYes" />'
1549 . '<input type="reset" class="control_at_footer" value="' . __('Reset') . '"'
1550 . 'tabindex="' . ($tabindex + $tabindex_for_value + 7) . '" />'
1551 . '</td>';
1555 * Get table head and table foot for insert row table
1557 * @param array $url_params url parameters
1559 * @return string an html snippet
1561 function PMA_getHeadAndFootOfInsertRowTable($url_params)
1563 $html_output = '<table class="insertRowTable">'
1564 . '<thead>'
1565 . '<tr>'
1566 . '<th>' . __('Column') . '</th>';
1568 if ($GLOBALS['cfg']['ShowFieldTypesInDataEditView']) {
1569 $html_output .= PMA_showColumnTypesInDataEditView($url_params, true);
1571 if ($GLOBALS['cfg']['ShowFunctionFields']) {
1572 $html_output .= PMA_showFunctionFieldsInEditMode($url_params, true);
1575 $html_output .= '<th>'. __('Null') . '</th>'
1576 . '<th>' . __('Value') . '</th>'
1577 . '</tr>'
1578 . '</thead>'
1579 . ' <tfoot>'
1580 . '<tr>'
1581 . '<th colspan="5" class="tblFooters right">'
1582 . '<input type="submit" value="' . __('Go') . '" />'
1583 . '</th>'
1584 . '</tr>'
1585 . '</tfoot>';
1586 return $html_output;
1590 * Prepares the field value and retrieve special chars, backup field and data array
1592 * @param array $current_row a row of the table
1593 * @param array $column description of column in given table
1594 * @param array $extracted_columnspec associative array containing type,
1595 * spec_in_brackets and possibly
1596 * enum_set_values (another array)
1597 * @param boolean $real_null_value whether column value null or not null
1598 * @param array $gis_data_types list of GIS data types
1599 * @param string $column_name_appendix string to append to column name in input
1601 * @return array $real_null_value, $data, $special_chars, $backup_field,
1602 * $special_chars_encoded
1604 function PMA_getSpecialCharsAndBackupFieldForExistingRow(
1605 $current_row, $column, $extracted_columnspec,
1606 $real_null_value, $gis_data_types, $column_name_appendix
1608 $special_chars_encoded = '';
1609 // (we are editing)
1610 if (is_null($current_row[$column['Field']])) {
1611 $real_null_value = true;
1612 $current_row[$column['Field']] = '';
1613 $special_chars = '';
1614 $data = $current_row[$column['Field']];
1615 } elseif ($column['True_Type'] == 'bit') {
1616 $special_chars = PMA_Util::printableBitValue(
1617 $current_row[$column['Field']], $extracted_columnspec['spec_in_brackets']
1619 } elseif (in_array($column['True_Type'], $gis_data_types)) {
1620 // Convert gis data to Well Know Text format
1621 $current_row[$column['Field']] = PMA_Util::asWKT(
1622 $current_row[$column['Field']], true
1624 $special_chars = htmlspecialchars($current_row[$column['Field']]);
1625 } else {
1626 // special binary "characters"
1627 if ($column['is_binary']
1628 || ($column['is_blob'] && ! $GLOBALS['cfg']['ProtectBinary'])
1630 if ($_SESSION['tmp_user_values']['display_binary_as_hex']
1631 && $GLOBALS['cfg']['ShowFunctionFields']
1633 $current_row[$column['Field']] = bin2hex(
1634 $current_row[$column['Field']]
1636 $column['display_binary_as_hex'] = true;
1637 } else {
1638 $current_row[$column['Field']]
1639 = PMA_Util::replaceBinaryContents(
1640 $current_row[$column['Field']]
1643 } // end if
1644 $special_chars = htmlspecialchars($current_row[$column['Field']]);
1646 //We need to duplicate the first \n or otherwise we will lose
1647 //the first newline entered in a VARCHAR or TEXT column
1648 $special_chars_encoded
1649 = PMA_Util::duplicateFirstNewline($special_chars);
1651 $data = $current_row[$column['Field']];
1652 } // end if... else...
1654 //when copying row, it is useful to empty auto-increment column
1655 // to prevent duplicate key error
1656 if (isset($_REQUEST['default_action'])
1657 && $_REQUEST['default_action'] === 'insert'
1659 if ($column['Key'] === 'PRI'
1660 && strpos($column['Extra'], 'auto_increment') !== false
1662 $data = $special_chars_encoded = $special_chars = null;
1665 // If a timestamp field value is not included in an update
1666 // statement MySQL auto-update it to the current timestamp;
1667 // however, things have changed since MySQL 4.1, so
1668 // it's better to set a fields_prev in this situation
1669 $backup_field = '<input type="hidden" name="fields_prev'
1670 . $column_name_appendix . '" value="'
1671 . htmlspecialchars($current_row[$column['Field']]) . '" />';
1673 return array(
1674 $real_null_value,
1675 $special_chars_encoded,
1676 $special_chars,
1677 $data,
1678 $backup_field
1683 * display default values
1685 * @param type $column description of column in given table
1686 * @param boolean $real_null_value whether column value null or not null
1688 * @return array $real_null_value, $data, $special_chars,
1689 * $backup_field, $special_chars_encoded
1691 function PMA_getSpecialCharsAndBackupFieldForInsertingMode(
1692 $column, $real_null_value
1694 if (! isset($column['Default'])) {
1695 $column['Default'] = '';
1696 $real_null_value = true;
1697 $data = '';
1698 } else {
1699 $data = $column['Default'];
1702 if ($column['True_Type'] == 'bit') {
1703 $special_chars = PMA_Util::convertBitDefaultValue($column['Default']);
1704 } else {
1705 $special_chars = htmlspecialchars($column['Default']);
1707 $backup_field = '';
1708 $special_chars_encoded = PMA_Util::duplicateFirstNewline($special_chars);
1709 // this will select the UNHEX function while inserting
1710 if (($column['is_binary']
1711 || ($column['is_blob'] && ! $GLOBALS['cfg']['ProtectBinary']))
1712 && (isset($_SESSION['tmp_user_values']['display_binary_as_hex'])
1713 && $_SESSION['tmp_user_values']['display_binary_as_hex'])
1714 && $GLOBALS['cfg']['ShowFunctionFields']
1716 $column['display_binary_as_hex'] = true;
1718 return array(
1719 $real_null_value, $data, $special_chars,
1720 $backup_field, $special_chars_encoded
1725 * Prepares the update/insert of a row
1727 * @return array $loop_array, $using_key, $is_insert, $is_insertignore
1729 function PMA_getParamsForUpdateOrInsert()
1731 if (isset($_REQUEST['where_clause'])) {
1732 // we were editing something => use the WHERE clause
1733 $loop_array = is_array($_REQUEST['where_clause'])
1734 ? $_REQUEST['where_clause']
1735 : array($_REQUEST['where_clause']);
1736 $using_key = true;
1737 $is_insert = $_REQUEST['submit_type'] == 'insert'
1738 || $_REQUEST['submit_type'] == 'showinsert'
1739 || $_REQUEST['submit_type'] == 'insertignore';
1740 $is_insertignore = $_REQUEST['submit_type'] == 'insertignore';
1741 } else {
1742 // new row => use indexes
1743 $loop_array = array();
1744 foreach ($_REQUEST['fields']['multi_edit'] as $key => $dummy) {
1745 $loop_array[] = $key;
1747 $using_key = false;
1748 $is_insert = true;
1749 $is_insertignore = false;
1751 return array($loop_array, $using_key, $is_insert, $is_insertignore);
1755 * Check wether insert row mode and if so include tbl_changen script and set
1756 * global variables.
1758 * @return void
1760 function PMA_isInsertRow()
1762 if (isset($_REQUEST['insert_rows'])
1763 && is_numeric($_REQUEST['insert_rows'])
1764 && $_REQUEST['insert_rows'] != $GLOBALS['cfg']['InsertRows']
1766 $GLOBALS['cfg']['InsertRows'] = $_REQUEST['insert_rows'];
1767 $response = PMA_Response::getInstance();
1768 $header = $response->getHeader();
1769 $scripts = $header->getScripts();
1770 $scripts->addFile('tbl_change.js');
1771 include 'tbl_change.php';
1772 exit;
1777 * set $_SESSION for edit_next
1779 * @param string $one_where_clause one where clause from where clauses array
1781 * @return void
1783 function PMA_setSessionForEditNext($one_where_clause)
1785 $local_query = 'SELECT * FROM ' . PMA_Util::backquote($GLOBALS['db'])
1786 . '.' . PMA_Util::backquote($GLOBALS['table']) . ' WHERE '
1787 . str_replace('` =', '` >', $one_where_clause) . ' LIMIT 1;';
1789 $res = PMA_DBI_query($local_query);
1790 $row = PMA_DBI_fetch_row($res);
1791 $meta = PMA_DBI_get_fields_meta($res);
1792 // must find a unique condition based on unique key,
1793 // not a combination of all fields
1794 list($unique_condition, $clause_is_unique)
1795 = PMA_Util::getUniqueCondition(
1796 $res, count($meta), $meta, $row, true
1798 if (! empty($unique_condition)) {
1799 $_SESSION['edit_next'] = $unique_condition;
1801 unset($unique_condition, $clause_is_unique);
1805 * set $goto_include variable for different cases and retrieve like,
1806 * if $GLOBALS['goto'] empty, if $goto_include previously not defined
1807 * and new_insert, same_insert, edit_next
1809 * @param string $goto_include store some script for include, otherwise it is
1810 * boolean false
1812 * @return string $goto_include
1814 function PMA_getGotoInclude($goto_include)
1816 $valid_options = array('new_insert', 'same_insert', 'edit_next');
1817 if (isset($_REQUEST['after_insert'])
1818 && in_array($_REQUEST['after_insert'], $valid_options)
1820 $goto_include = 'tbl_change.php';
1821 } elseif (! empty($GLOBALS['goto'])) {
1822 if (! preg_match('@^[a-z_]+\.php$@', $GLOBALS['goto'])) {
1823 // this should NOT happen
1824 //$GLOBALS['goto'] = false;
1825 $goto_include = false;
1826 } else {
1827 $goto_include = $GLOBALS['goto'];
1829 if ($GLOBALS['goto'] == 'db_sql.php' && strlen($GLOBALS['table'])) {
1830 $GLOBALS['table'] = '';
1833 if (! $goto_include) {
1834 if (! strlen($GLOBALS['table'])) {
1835 $goto_include = 'db_sql.php';
1836 } else {
1837 $goto_include = 'tbl_sql.php';
1840 return $goto_include;
1844 * Defines the url to return in case of failure of the query
1846 * @param array $url_params url parameters
1848 * @return string error url for query failure
1850 function PMA_getErrorUrl($url_params)
1852 if (isset($_REQUEST['err_url'])) {
1853 return $_REQUEST['err_url'];
1854 } else {
1855 return 'tbl_change.php' . PMA_generate_common_url($url_params);
1860 * Builds the sql query
1862 * @param boolean $is_insertignore $_REQUEST['submit_type'] == 'insertignore'
1863 * @param array $query_fields column names array
1864 * @param array $value_sets array of query values
1866 * @return string a query
1868 function PMA_buildSqlQuery($is_insertignore, $query_fields, $value_sets)
1870 if ($is_insertignore) {
1871 $insert_command = 'INSERT IGNORE ';
1872 } else {
1873 $insert_command = 'INSERT ';
1875 $query[] = $insert_command . 'INTO '
1876 . PMA_Util::backquote($GLOBALS['db']) . '.'
1877 . PMA_Util::backquote($GLOBALS['table'])
1878 . ' (' . implode(', ', $query_fields) . ') VALUES ('
1879 . implode('), (', $value_sets) . ')';
1880 unset($insert_command, $query_fields);
1881 return $query;
1885 * Executes the sql query and get the result, then move back to the calling page
1887 * @param array $url_params url paramters array
1888 * @param string $query built query from PMA_buildSqlQuery()
1890 * @return array $url_params, $total_affected_rows, $last_messages
1891 * $warning_messages, $error_messages, $return_to_sql_query
1893 function PMA_executeSqlQuery($url_params, $query)
1895 $return_to_sql_query = '';
1896 if (! empty($GLOBALS['sql_query'])) {
1897 $url_params['sql_query'] = $GLOBALS['sql_query'];
1898 $return_to_sql_query = $GLOBALS['sql_query'];
1900 $GLOBALS['sql_query'] = implode('; ', $query) . ';';
1901 // to ensure that the query is displayed in case of
1902 // "insert as new row" and then "insert another new row"
1903 $GLOBALS['display_query'] = $GLOBALS['sql_query'];
1905 $total_affected_rows = 0;
1906 $last_messages = array();
1907 $warning_messages = array();
1908 $error_messages = array();
1910 foreach ($query as $single_query) {
1911 if ($_REQUEST['submit_type'] == 'showinsert') {
1912 $last_messages[] = PMA_Message::notice(__('Showing SQL query'));
1913 continue;
1915 if ($GLOBALS['cfg']['IgnoreMultiSubmitErrors']) {
1916 $result = PMA_DBI_try_query($single_query);
1917 } else {
1918 $result = PMA_DBI_query($single_query);
1920 if (! $result) {
1921 $error_messages[] = PMA_Message::sanitize(PMA_DBI_getError());
1922 } else {
1923 // The next line contains a real assignment, it's not a typo
1924 if ($tmp = @PMA_DBI_affected_rows()) {
1925 $total_affected_rows += $tmp;
1927 unset($tmp);
1929 $insert_id = PMA_DBI_insert_id();
1930 if ($insert_id != 0) {
1931 // insert_id is id of FIRST record inserted in one insert, so if we
1932 // inserted multiple rows, we had to increment this
1934 if ($total_affected_rows > 0) {
1935 $insert_id = $insert_id + $total_affected_rows - 1;
1937 $last_message = PMA_Message::notice(__('Inserted row id: %1$d'));
1938 $last_message->addParam($insert_id);
1939 $last_messages[] = $last_message;
1941 PMA_DBI_free_result($result);
1943 $warning_messages = PMA_getWarningMessages();
1945 return array(
1946 $url_params,
1947 $total_affected_rows,
1948 $last_messages,
1949 $warning_messages,
1950 $error_messages,
1951 $return_to_sql_query
1956 * get the warning messages array
1958 * @return array $warning_essages
1960 function PMA_getWarningMessages()
1962 $warning_essages = array();
1963 foreach (PMA_DBI_get_warnings() as $warning) {
1964 $warning_essages[] = PMA_Message::sanitize(
1965 $warning['Level'] . ': #' . $warning['Code'] . ' ' . $warning['Message']
1968 return $warning_essages;
1972 * Column to display from the foreign table?
1974 * @param string $where_comparison string that contain relation field value
1975 * @param string $relation_field_value relation field value
1976 * @param array $map all Relations to foreign tables for a given
1977 * table or optionally a given column in a table
1978 * @param string $relation_field relation field
1980 * @return string $dispval display value from the foreign table
1982 function PMA_getDisplayValueForForeignTableColumn($where_comparison,
1983 $relation_field_value, $map, $relation_field
1985 $display_field = PMA_getDisplayField(
1986 $map[$relation_field]['foreign_db'],
1987 $map[$relation_field]['foreign_table']
1989 // Field to display from the foreign table?
1990 if (isset($display_field) && strlen($display_field)) {
1991 $dispsql = 'SELECT ' . PMA_Util::backquote($display_field)
1992 . ' FROM ' . PMA_Util::backquote($map[$relation_field]['foreign_db'])
1993 . '.' . PMA_Util::backquote($map[$relation_field]['foreign_table'])
1994 . ' WHERE ' . PMA_Util::backquote($map[$relation_field]['foreign_field'])
1995 . $where_comparison;
1996 $dispresult = PMA_DBI_try_query($dispsql, null, PMA_DBI_QUERY_STORE);
1997 if ($dispresult && PMA_DBI_num_rows($dispresult) > 0) {
1998 list($dispval) = PMA_DBI_fetch_row($dispresult, 0);
2000 @PMA_DBI_free_result($dispresult);
2001 return $dispval;
2003 return '';
2007 * Display option in the cell according to user choises
2009 * @param array $map all Relations to foreign tables for a given
2010 * table or optionally a given column in a table
2011 * @param string $relation_field relation field
2012 * @param string $where_comparison string that contain relation field value
2013 * @param string $dispval display value from the foreign table
2014 * @param string $relation_field_value relation field value
2016 * @return string $output HTML <a> tag
2018 function PMA_getLinkForRelationalDisplayField($map, $relation_field,
2019 $where_comparison, $dispval, $relation_field_value
2021 if ('K' == $_SESSION['tmp_user_values']['relational_display']) {
2022 // user chose "relational key" in the display options, so
2023 // the title contains the display field
2024 $title = (! empty($dispval))
2025 ? ' title="' . htmlspecialchars($dispval) . '"'
2026 : '';
2027 } else {
2028 $title = ' title="' . htmlspecialchars($relation_field_value) . '"';
2030 $_url_params = array(
2031 'db' => $map[$relation_field]['foreign_db'],
2032 'table' => $map[$relation_field]['foreign_table'],
2033 'pos' => '0',
2034 'sql_query' => 'SELECT * FROM '
2035 . PMA_Util::backquote($map[$relation_field]['foreign_db'])
2036 . '.' . PMA_Util::backquote($map[$relation_field]['foreign_table'])
2037 . ' WHERE ' . PMA_Util::backquote($map[$relation_field]['foreign_field'])
2038 . $where_comparison
2040 $output = '<a href="sql.php'
2041 . PMA_generate_common_url($_url_params) . '"' . $title . '>';
2043 if ('D' == $_SESSION['tmp_user_values']['relational_display']) {
2044 // user chose "relational display field" in the
2045 // display options, so show display field in the cell
2046 $output .= (!empty($dispval)) ? htmlspecialchars($dispval) : '';
2047 } else {
2048 // otherwise display data in the cell
2049 $output .= htmlspecialchars($relation_field_value);
2051 $output .= '</a>';
2052 return $output;
2056 * Transform edited values
2058 * @param string $db db name
2059 * @param string $table table name
2060 * @param array $transformation mimetypes for all columns of a table
2061 * [field_name][field_key]
2062 * @param array $edited_values transform columns list and new values
2063 * @param string $file file containing the transformation plugin
2064 * @param string $column_name column name
2065 * @param array $extra_data extra data array
2067 * @return array $extra_data
2069 function PMA_transformEditedValues($db, $table,
2070 $transformation, $edited_values, $file, $column_name, $extra_data
2072 foreach ($edited_values as $cell_index => $curr_cell_edited_values) {
2073 if (isset($curr_cell_edited_values[$column_name])) {
2074 $column_data = $curr_cell_edited_values[$column_name];
2076 $_url_params = array(
2077 'db' => $db,
2078 'table' => $table,
2079 'where_clause' => $_REQUEST['where_clause'],
2080 'transform_key' => $column_name
2083 $include_file = 'libraries/plugins/transformations/' . $file;
2084 if (file_exists($include_file)) {
2085 include_once $include_file;
2087 $transform_options = PMA_transformation_getOptions(
2088 isset($transformation['transformation_options'])
2089 ? $transformation['transformation_options']
2090 : ''
2092 $transform_options['wrapper_link']
2093 = PMA_generate_common_url($_url_params);
2094 $class_name = str_replace('.class.php', '', $file);
2095 $plugin_manager = null;
2096 $transformation_plugin = new $class_name(
2097 $plugin_manager
2101 $extra_data['transformations'][$cell_index]
2102 = $transformation_plugin->applyTransformation(
2103 $column_data,
2104 $transform_options,
2108 } // end of loop for each transformation cell
2109 return $extra_data;
2113 * Get current value in multi edit mode
2115 * @param array $multi_edit_colummns multiple edit column array
2116 * @param array $multi_edit_columns_name multiple edit columns name array
2117 * @param array $multi_edit_funcs multiple edit functions array
2118 * @param array $gis_from_text_functions array that contains gis from text functions
2119 * @param string $current_value current value in the column
2120 * @param array $gis_from_wkb_functions initialy $val is $multi_edit_colummns[$key]
2121 * @param array $func_optional_param array('RAND','UNIX_TIMESTAMP')
2122 * @param array $func_no_param array of set of string
2123 * @param string $key an md5 of the column name
2125 * @return array $cur_value
2127 function PMA_getCurrentValueAsAnArrayForMultipleEdit($multi_edit_colummns,
2128 $multi_edit_columns_name, $multi_edit_funcs, $gis_from_text_functions,
2129 $current_value, $gis_from_wkb_functions, $func_optional_param,
2130 $func_no_param, $key
2132 if (empty($multi_edit_funcs[$key])) {
2133 return $current_value;
2134 } elseif ('UUID' === $multi_edit_funcs[$key]) {
2135 /* This way user will know what UUID new row has */
2136 $uuid = PMA_DBI_fetch_value('SELECT UUID()');
2137 return "'" . $uuid . "'";
2138 } elseif ((in_array($multi_edit_funcs[$key], $gis_from_text_functions)
2139 && substr($current_value, 0, 3) == "'''")
2140 || in_array($multi_edit_funcs[$key], $gis_from_wkb_functions)
2142 // Remove enclosing apostrophes
2143 $current_value = substr($current_value, 1, strlen($current_value) - 2);
2144 // Remove escaping apostrophes
2145 $current_value = str_replace("''", "'", $current_value);
2146 return $multi_edit_funcs[$key] . '(' . $current_value . ')';
2147 } elseif (! in_array($multi_edit_funcs[$key], $func_no_param)
2148 || ($current_value != "''"
2149 && in_array($multi_edit_funcs[$key], $func_optional_param))
2151 return $multi_edit_funcs[$key] . '(' . $current_value . ')';
2152 } else {
2153 return $multi_edit_funcs[$key] . '()';
2158 * Get query values array and query fileds array for insert and update in multi edit
2160 * @param array $multi_edit_columns_name multiple edit columns name array
2161 * @param array $multi_edit_columns_null multiple edit columns null array
2162 * @param string $current_value current value in the column in loop
2163 * @param array $multi_edit_columns_prev multiple edit previous columns array
2164 * @param array $multi_edit_funcs multiple edit functions array
2165 * @param boolean $is_insert boolean value whether insert or not
2166 * @param array $query_values SET part of the sql query
2167 * @param array $query_fields array of query fileds
2168 * @param string $current_value_as_an_array current value in the column
2169 * as an array
2170 * @param array $value_sets array of valu sets
2171 * @param string $key an md5 of the column name
2172 * @param array $multi_edit_columns_null_prev array of multiple edit columns
2173 * null previous
2175 * @return array ($query_values, $query_fields)
2177 function PMA_getQueryValuesForInsertAndUpdateInMultipleEdit($multi_edit_columns_name,
2178 $multi_edit_columns_null, $current_value, $multi_edit_columns_prev,
2179 $multi_edit_funcs,$is_insert, $query_values, $query_fields,
2180 $current_value_as_an_array, $value_sets, $key, $multi_edit_columns_null_prev
2182 // i n s e r t
2183 if ($is_insert) {
2184 // no need to add column into the valuelist
2185 if (strlen($current_value_as_an_array)) {
2186 $query_values[] = $current_value_as_an_array;
2187 // first inserted row so prepare the list of fields
2188 if (empty($value_sets)) {
2189 $query_fields[] = PMA_Util::backquote(
2190 $multi_edit_columns_name[$key]
2195 } elseif (! empty($multi_edit_columns_null_prev[$key])
2196 && ! isset($multi_edit_columns_null[$key])
2198 // u p d a t e
2200 // field had the null checkbox before the update
2201 // field no longer has the null checkbox
2202 $query_values[]
2203 = PMA_Util::backquote($multi_edit_columns_name[$key])
2204 . ' = ' . $current_value_as_an_array;
2205 } elseif (empty($multi_edit_funcs[$key])
2206 && isset($multi_edit_columns_prev[$key])
2207 && ("'" . PMA_Util::sqlAddSlashes($multi_edit_columns_prev[$key]) . "'"
2208 == $current_value)
2210 // No change for this column and no MySQL function is used -> next column
2211 } elseif (! empty($current_value)) {
2212 // avoid setting a field to NULL when it's already NULL
2213 // (field had the null checkbox before the update
2214 // field still has the null checkbox)
2215 if (empty($multi_edit_columns_null_prev[$key])
2216 || empty($multi_edit_columns_null[$key])
2218 $query_values[]
2219 = PMA_Util::backquote($multi_edit_columns_name[$key])
2220 . ' = ' . $current_value_as_an_array;
2223 return array($query_values, $query_fields);
2227 * Get the current column value in the form for different data types
2229 * @param string $possibly_uploaded_val uploaded file content
2230 * @param string $key an md5 of the column name
2231 * @param array $multi_edit_columns_type array of multi edit column types
2232 * @param string $current_value current column value in the form
2233 * @param array $multi_edit_auto_increment multi edit auto increment
2234 * @param string $rownumber index of where clause array
2235 * @param array $multi_edit_columns_name multi edit column names array
2236 * @param array $multi_edit_columns_null multi edit columns null array
2237 * @param array $multi_edit_columns_null_prev multi edit columns previous null
2238 * @param boolean $is_insert whether insert or not
2239 * @param boolean $using_key whether editing or new row
2240 * @param array $where_clause where clauses
2241 * @param string $table table name
2243 * @return string $current_value current column value in the form
2245 function PMA_getCurrentValueForDifferentTypes($possibly_uploaded_val, $key,
2246 $multi_edit_columns_type, $current_value, $multi_edit_auto_increment,
2247 $rownumber, $multi_edit_columns_name, $multi_edit_columns_null,
2248 $multi_edit_columns_null_prev, $is_insert, $using_key, $where_clause, $table
2250 // Fetch the current values of a row to use in case we have a protected field
2251 if ($is_insert
2252 && $using_key && isset($multi_edit_columns_type)
2253 && is_array($multi_edit_columns_type) && isset($where_clause)
2255 $protected_row = PMA_DBI_fetch_single_row(
2256 'SELECT * FROM ' . PMA_Util::backquote($table)
2257 . ' WHERE ' . $where_clause . ';'
2261 if (false !== $possibly_uploaded_val) {
2262 $current_value = $possibly_uploaded_val;
2263 } else {
2264 // c o l u m n v a l u e i n t h e f o r m
2265 if (isset($multi_edit_columns_type[$key])) {
2266 $type = $multi_edit_columns_type[$key];
2267 } else {
2268 $type = '';
2271 if ($type != 'protected' && $type != 'set' && 0 === strlen($current_value)) {
2272 // best way to avoid problems in strict mode
2273 // (works also in non-strict mode)
2274 if (isset($multi_edit_auto_increment)
2275 && isset($multi_edit_auto_increment[$key])
2277 $current_value = 'NULL';
2278 } else {
2279 $current_value = "''";
2281 } elseif ($type == 'set') {
2282 if (! empty($_REQUEST['fields']['multi_edit'][$rownumber][$key])) {
2283 $current_value = implode(
2284 ',', $_REQUEST['fields']['multi_edit'][$rownumber][$key]
2286 $current_value = "'" . PMA_Util::sqlAddSlashes($current_value) . "'";
2287 } else {
2288 $current_value = "''";
2290 } elseif ($type == 'protected') {
2291 // here we are in protected mode (asked in the config)
2292 // so tbl_change has put this special value in the
2293 // coulmns array, so we do not change the column value
2294 // but we can still handle column upload
2296 // when in UPDATE mode, do not alter field's contents. When in INSERT
2297 // mode, insert empty field because no values were submitted.
2298 // If protected blobs where set, insert original fields content.
2299 if (! empty($protected_row[$multi_edit_columns_name[$key]])) {
2300 $current_value = '0x'
2301 . bin2hex($protected_row[$multi_edit_columns_name[$key]]);
2302 } else {
2303 $current_value = '';
2305 } elseif ($type == 'bit') {
2306 $current_value = preg_replace('/[^01]/', '0', $current_value);
2307 $current_value = "b'" . PMA_Util::sqlAddSlashes($current_value) . "'";
2308 } elseif (! ($type == 'datetime' || $type == 'timestamp')
2309 || $current_value != 'CURRENT_TIMESTAMP'
2311 $current_value = "'" . PMA_Util::sqlAddSlashes($current_value) . "'";
2314 // Was the Null checkbox checked for this field?
2315 // (if there is a value, we ignore the Null checkbox: this could
2316 // be possible if Javascript is disabled in the browser)
2317 if (! empty($multi_edit_columns_null[$key])
2318 && ($current_value == "''" || $current_value == '')
2320 $current_value = 'NULL';
2323 // The Null checkbox was unchecked for this field
2324 if (empty($current_value)
2325 && ! empty($multi_edit_columns_null_prev[$key])
2326 && ! isset($multi_edit_columns_null[$key])
2328 $current_value = "''";
2330 } // end else (column value in the form)
2331 return $current_value;
2336 * Check whether inline edited value can be truncated or not,
2337 * and add additional parameters for extra_data array if needed
2339 * @param string $db Database name
2340 * @param string $table Table name
2341 * @param string $column_name Column name
2342 * @param array &$extra_data Extra data for ajax response
2344 * @return void
2346 function PMA_verifyWhetherValueCanBeTruncatedAndAppendExtraData(
2347 $db, $table, $column_name, &$extra_data
2350 $extra_data['isNeedToRecheck'] = true;
2352 $sql_for_real_value = 'SELECT '. PMA_Util::backquote($table) . '.'
2353 . PMA_Util::backquote($column_name)
2354 . ' FROM ' . PMA_Util::backquote($db) . '.'
2355 . PMA_Util::backquote($table)
2356 . ' WHERE ' . $_REQUEST['where_clause'][0];
2358 if (PMA_DBI_fetch_value($sql_for_real_value) !== false) {
2359 $extra_data['truncatableFieldValue'] = PMA_DBI_fetch_value($sql_for_real_value);
2360 } else {
2361 $extra_data['isNeedToRecheck'] = false;