Passed
Pull Request — master (#14116)
by
unknown
09:32
created

CentralColumns::getHtmlForTableNavigation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 13
nc 2
nop 3
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/* vim: set expandtab sw=4 ts=4 sts=4: */
3
/**
4
 * Functions for displaying user preferences pages
5
 *
6
 * @package PhpMyAdmin
7
 */
8
namespace PhpMyAdmin;
9
10
use PhpMyAdmin\Charsets;
11
use PhpMyAdmin\DatabaseInterface;
12
use PhpMyAdmin\Message;
13
use PhpMyAdmin\Relation;
14
use PhpMyAdmin\Template;
15
use PhpMyAdmin\Url;
16
use PhpMyAdmin\Util;
17
18
/**
19
 * PhpMyAdmin\CentralColumns class
20
 *
21
 * @package PhpMyAdmin
22
 */
23
class CentralColumns
24
{
25
    /**
26
     * DatabaseInterface instance
27
     *
28
     * @var DatabaseInterface
29
     */
30
    private $dbi;
31
32
    /**
33
     * Current user
34
     *
35
     * @var string
36
     */
37
    private $user;
38
39
    /**
40
     * Number of rows displayed when browsing a result set
41
     *
42
     * @var int
43
     */
44
    private $maxRows;
45
46
    /**
47
     * Which editor should be used for CHAR/VARCHAR fields
48
     *
49
     * @var string
50
     */
51
    private $charEditing;
52
53
    /**
54
     * Disable use of INFORMATION_SCHEMA
55
     *
56
     * @var boolean
57
     */
58
    private $disableIs;
59
60
    /**
61
     * Constructor
62
     *
63
     * @param DatabaseInterface $dbi DatabaseInterface instance
64
     */
65
    public function __construct(DatabaseInterface $dbi)
66
    {
67
        $this->dbi = $dbi;
68
69
        $this->user = $GLOBALS['cfg']['Server']['user'];
70
        $this->maxRows = (int) $GLOBALS['cfg']['MaxRows'];
71
        $this->charEditing = $GLOBALS['cfg']['CharEditing'];
72
        $this->disableIs = (bool) $GLOBALS['cfg']['Server']['DisableIS'];
73
    }
74
75
    /**
76
     * Defines the central_columns parameters for the current user
77
     *
78
     * @return array the central_columns parameters for the current user
79
     * @access public
80
     */
81 View Code Duplication
    public function getParams()
82
    {
83
        static $cfgCentralColumns = null;
84
85
        if (null !== $cfgCentralColumns) {
86
            return $cfgCentralColumns;
87
        }
88
89
        $cfgRelation = Relation::getRelationsParam();
90
91
        if ($cfgRelation['centralcolumnswork']) {
92
            $cfgCentralColumns = array(
93
                'user'  => $this->user,
94
                'db'    => $cfgRelation['db'],
95
                'table' => $cfgRelation['central_columns'],
96
            );
97
        } else {
98
            $cfgCentralColumns = false;
99
        }
100
101
        return $cfgCentralColumns;
102
    }
103
104
    /**
105
     * get $num columns of given database from central columns list
106
     * starting at offset $from
107
     *
108
     * @param string $db   selected database
109
     * @param int    $from starting offset of first result
110
     * @param int    $num  maximum number of results to return
111
     *
112
     * @return array list of $num columns present in central columns list
113
     * starting at offset $from for the given database
114
     */
115
    public function getColumnsList($db, $from = 0, $num = 25)
116
    {
117
        $cfgCentralColumns = $this->getParams();
118
        if (empty($cfgCentralColumns)) {
119
            return array();
120
        }
121
        $pmadb = $cfgCentralColumns['db'];
122
        $this->dbi->selectDb($pmadb, DatabaseInterface::CONNECT_CONTROL);
123
        $central_list_table = $cfgCentralColumns['table'];
124
        //get current values of $db from central column list
125
        if ($num == 0) {
126
            $query = 'SELECT * FROM ' . Util::backquote($central_list_table) . ' '
127
                . 'WHERE db_name = \'' . $this->dbi->escapeString($db) . '\';';
128
        } else {
129
            $query = 'SELECT * FROM ' . Util::backquote($central_list_table) . ' '
130
                . 'WHERE db_name = \'' . $this->dbi->escapeString($db) . '\' '
131
                . 'LIMIT ' . $from . ', ' . $num . ';';
132
        }
133
        $has_list = (array) $this->dbi->fetchResult(
134
            $query, null, null, DatabaseInterface::CONNECT_CONTROL
135
        );
136
        $this->handleColumnExtra($has_list);
137
        return $has_list;
138
    }
139
140
    /**
141
     * Get the number of columns present in central list for given db
142
     *
143
     * @param string $db current database
144
     *
145
     * @return int number of columns in central list of columns for $db
146
     */
147
    public function getCount($db)
148
    {
149
        $cfgCentralColumns = $this->getParams();
150
        if (empty($cfgCentralColumns)) {
151
            return 0;
152
        }
153
        $pmadb = $cfgCentralColumns['db'];
154
        $this->dbi->selectDb($pmadb, DatabaseInterface::CONNECT_CONTROL);
155
        $central_list_table = $cfgCentralColumns['table'];
156
        $query = 'SELECT count(db_name) FROM ' .
157
            Util::backquote($central_list_table) . ' '
158
            . 'WHERE db_name = \'' . $this->dbi->escapeString($db) . '\';';
159
        $res = $this->dbi->fetchResult(
160
            $query, null, null, DatabaseInterface::CONNECT_CONTROL
161
        );
162
        if (isset($res[0])) {
163
            return $res[0];
164
        }
165
166
        return 0;
167
    }
168
169
    /**
170
     * return the existing columns in central list among the given list of columns
171
     *
172
     * @param string  $db        the selected database
173
     * @param string  $cols      comma separated list of given columns
174
     * @param boolean $allFields set if need all the fields of existing columns,
175
     *                           otherwise only column_name is returned
176
     *
177
     * @return array list of columns in central columns among given set of columns
178
     */
179
    private function findExistingColNames(
180
        $db,
181
        $cols,
182
        $allFields = false
183
    ) {
184
        $cfgCentralColumns = $this->getParams();
185
        if (empty($cfgCentralColumns)) {
186
            return array();
187
        }
188
        $pmadb = $cfgCentralColumns['db'];
189
        $this->dbi->selectDb($pmadb, DatabaseInterface::CONNECT_CONTROL);
190
        $central_list_table = $cfgCentralColumns['table'];
191
        if ($allFields) {
192
            $query = 'SELECT * FROM ' . Util::backquote($central_list_table) . ' '
193
                . 'WHERE db_name = \'' . $this->dbi->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
194
            $has_list = (array) $this->dbi->fetchResult(
195
                $query, null, null, DatabaseInterface::CONNECT_CONTROL
196
            );
197
            $this->handleColumnExtra($has_list);
198
        } else {
199
            $query = 'SELECT col_name FROM '
200
                . Util::backquote($central_list_table) . ' '
201
                . 'WHERE db_name = \'' . $this->dbi->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
202
            $has_list = (array) $this->dbi->fetchResult(
203
                $query, null, null, DatabaseInterface::CONNECT_CONTROL
204
            );
205
        }
206
207
        return $has_list;
208
    }
209
210
    /**
211
     * return error message to be displayed if central columns
212
     * configuration storage is not completely configured
213
     *
214
     * @return Message
215
     */
216
    private function configErrorMessage()
217
    {
218
        return Message::error(
219
            __(
220
                'The configuration storage is not ready for the central list'
221
                . ' of columns feature.'
222
            )
223
        );
224
    }
225
226
    /**
227
     * build the insert query for central columns list given PMA storage
228
     * db, central_columns table, column name and corresponding definition to be added
229
     *
230
     * @param string $column             column to add into central list
231
     * @param array  $def                list of attributes of the column being added
232
     * @param string $db                 PMA configuration storage database name
233
     * @param string $central_list_table central columns configuration storage table name
234
     *
235
     * @return string query string to insert the given column
236
     * with definition into central list
237
     */
238
    private function getInsertQuery(
239
        $column,
240
        array $def,
241
        $db,
242
        $central_list_table
243
    ) {
244
        $type = "";
245
        $length = 0;
246
        $attribute = "";
247
        if (isset($def['Type'])) {
248
            $extracted_columnspec = Util::extractColumnSpec($def['Type']);
249
            $attribute = trim($extracted_columnspec[ 'attribute']);
250
            $type = $extracted_columnspec['type'];
251
            $length = $extracted_columnspec['spec_in_brackets'];
252
        }
253
        if (isset($def['Attribute'])) {
254
            $attribute = $def['Attribute'];
255
        };
256
        $collation = isset($def['Collation'])?$def['Collation']:"";
257
        $isNull = ($def['Null'] == "NO")?0:1;
258
        $extra = isset($def['Extra'])?$def['Extra']:"";
259
        $default = isset($def['Default'])?$def['Default']:"";
260
        $insQuery = 'INSERT INTO '
261
            . Util::backquote($central_list_table) . ' '
262
            . 'VALUES ( \'' . $this->dbi->escapeString($db) . '\' ,'
263
            . '\'' . $this->dbi->escapeString($column) . '\',\''
264
            . $this->dbi->escapeString($type) . '\','
265
            . '\'' . $this->dbi->escapeString($length) . '\',\''
266
            . $this->dbi->escapeString($collation) . '\','
267
            . '\'' . $this->dbi->escapeString($isNull) . '\','
268
            . '\'' . implode(',', array($extra, $attribute))
269
            . '\',\'' . $this->dbi->escapeString($default) . '\');';
270
        return $insQuery;
271
    }
272
273
    /**
274
     * If $isTable is true then unique columns from given tables as $field_select
275
     * are added to central list otherwise the $field_select is considered as
276
     * list of columns and these columns are added to central list if not already added
277
     *
278
     * @param array  $field_select if $isTable is true selected tables list
279
     *                             otherwise selected columns list
280
     * @param bool   $isTable      if passed array is of tables or columns
281
     * @param string $table        if $isTable is false, then table name to
282
     *                             which columns belong
283
     *
284
     * @return true|PhpMyAdmin\Message
285
     */
286
    public function syncUniqueColumns(
287
        array $field_select,
288
        $isTable = true,
289
        $table = null
290
    ) {
291
        $cfgCentralColumns = $this->getParams();
292
        if (empty($cfgCentralColumns)) {
293
            return $this->configErrorMessage();
294
        }
295
        $db = $_REQUEST['db'];
296
        $pmadb = $cfgCentralColumns['db'];
297
        $central_list_table = $cfgCentralColumns['table'];
298
        $this->dbi->selectDb($db);
299
        $existingCols = array();
300
        $cols = "";
301
        $insQuery = array();
302
        $fields = array();
303
        $message = true;
304
        if ($isTable) {
305 View Code Duplication
            foreach ($field_select as $table) {
306
                $fields[$table] = (array) $this->dbi->getColumns(
307
                    $db, $table, null, true
308
                );
309
                foreach ($fields[$table] as $field => $def) {
310
                    $cols .= "'" . $this->dbi->escapeString($field) . "',";
311
                }
312
            }
313
314
            $has_list = $this->findExistingColNames($db, trim($cols, ','));
315 View Code Duplication
            foreach ($field_select as $table) {
316
                foreach ($fields[$table] as $field => $def) {
317
                    if (!in_array($field, $has_list)) {
318
                        $has_list[] = $field;
319
                        $insQuery[] = $this->getInsertQuery(
320
                            $field, $def, $db, $central_list_table
321
                        );
322
                    } else {
323
                        $existingCols[] = "'" . $field . "'";
324
                    }
325
                }
326
            }
327
        } else {
328
            if ($table === null) {
329
                $table = $_REQUEST['table'];
330
            }
331
            foreach ($field_select as $column) {
332
                $cols .= "'" . $this->dbi->escapeString($column) . "',";
333
            }
334
            $has_list = $this->findExistingColNames($db, trim($cols, ','));
335 View Code Duplication
            foreach ($field_select as $column) {
336
                if (!in_array($column, $has_list)) {
337
                    $has_list[] = $column;
338
                    $field = (array) $this->dbi->getColumns(
339
                        $db, $table, $column,
340
                        true
341
                    );
342
                    $insQuery[] = $this->getInsertQuery(
343
                        $column, $field, $db, $central_list_table
344
                    );
345
                } else {
346
                    $existingCols[] = "'" . $column . "'";
347
                }
348
            }
349
        }
350 View Code Duplication
        if (! empty($existingCols)) {
351
            $existingCols = implode(",", array_unique($existingCols));
352
            $message = Message::notice(
353
                sprintf(
354
                    __(
355
                        'Could not add %1$s as they already exist in central list!'
356
                    ), htmlspecialchars($existingCols)
357
                )
358
            );
359
            $message->addMessage(
360
                Message::notice(
361
                    "Please remove them first "
362
                    . "from central list if you want to update above columns"
363
                )
364
            );
365
        }
366
        $this->dbi->selectDb($pmadb, DatabaseInterface::CONNECT_CONTROL);
367
        if (! empty($insQuery)) {
368 View Code Duplication
            foreach ($insQuery as $query) {
369
                if (!$this->dbi->tryQuery($query, DatabaseInterface::CONNECT_CONTROL)) {
370
                    $message = Message::error(__('Could not add columns!'));
371
                    $message->addMessage(
372
                        Message::rawError(
373
                            $this->dbi->getError(DatabaseInterface::CONNECT_CONTROL)
0 ignored issues
show
Bug introduced by
It seems like $this->dbi->getError(\Ph...rface::CONNECT_CONTROL) targeting PhpMyAdmin\DatabaseInterface::getError() can also be of type boolean; however, PhpMyAdmin\Message::rawError() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
374
                        )
375
                    );
376
                    break;
377
                }
378
            }
379
        }
380
        return $message;
381
    }
382
383
    /**
384
     * if $isTable is true it removes all columns of given tables as $field_select from
385
     * central columns list otherwise $field_select is columns list and it removes
386
     * given columns if present in central list
387
     *
388
     * @param array $field_select if $isTable selected list of tables otherwise
389
     *                            selected list of columns to remove from central list
390
     * @param bool  $isTable      if passed array is of tables or columns
391
     *
392
     * @return true|PhpMyAdmin\Message
393
     */
394
    public function deleteColumnsFromList(
395
        array $field_select,
396
        $isTable = true
397
    ) {
398
        $cfgCentralColumns = $this->getParams();
399
        if (empty($cfgCentralColumns)) {
400
            return $this->configErrorMessage();
401
        }
402
        $db = $_REQUEST['db'];
403
        $pmadb = $cfgCentralColumns['db'];
404
        $central_list_table = $cfgCentralColumns['table'];
405
        $this->dbi->selectDb($db);
406
        $message = true;
407
        $colNotExist = array();
408
        $fields = array();
409
        if ($isTable) {
410
            $cols = '';
411 View Code Duplication
            foreach ($field_select as $table) {
412
                $fields[$table] = (array) $this->dbi->getColumnNames(
413
                    $db, $table
414
                );
415
                foreach ($fields[$table] as $col_select) {
416
                    $cols .= '\'' . $this->dbi->escapeString($col_select) . '\',';
417
                }
418
            }
419
            $cols = trim($cols, ',');
420
            $has_list = $this->findExistingColNames($db, $cols);
421
            foreach ($field_select as $table) {
422
                foreach ($fields[$table] as $column) {
423
                    if (!in_array($column, $has_list)) {
424
                        $colNotExist[] = "'" . $column . "'";
425
                    }
426
                }
427
            }
428
429
        } else {
430
            $cols = '';
431
            foreach ($field_select as $col_select) {
432
                $cols .= '\'' . $this->dbi->escapeString($col_select) . '\',';
433
            }
434
            $cols = trim($cols, ',');
435
            $has_list = $this->findExistingColNames($db, $cols);
436
            foreach ($field_select as $column) {
437
                if (!in_array($column, $has_list)) {
438
                    $colNotExist[] = "'" . $column . "'";
439
                }
440
            }
441
        }
442 View Code Duplication
        if (!empty($colNotExist)) {
443
            $colNotExist = implode(",", array_unique($colNotExist));
444
            $message = Message::notice(
445
                sprintf(
446
                    __(
447
                        'Couldn\'t remove Column(s) %1$s '
448
                        . 'as they don\'t exist in central columns list!'
449
                    ), htmlspecialchars($colNotExist)
450
                )
451
            );
452
        }
453
        $this->dbi->selectDb($pmadb, DatabaseInterface::CONNECT_CONTROL);
454
455
        $query = 'DELETE FROM ' . Util::backquote($central_list_table) . ' '
456
            . 'WHERE db_name = \'' . $this->dbi->escapeString($db) . '\' AND col_name IN (' . $cols . ');';
457
458
        if (!$this->dbi->tryQuery($query, DatabaseInterface::CONNECT_CONTROL)) {
459
            $message = Message::error(__('Could not remove columns!'));
460
            $message->addHtml('<br />' . htmlspecialchars($cols) . '<br />');
461
            $message->addMessage(
462
                Message::rawError(
463
                    $this->dbi->getError(DatabaseInterface::CONNECT_CONTROL)
0 ignored issues
show
Bug introduced by
It seems like $this->dbi->getError(\Ph...rface::CONNECT_CONTROL) targeting PhpMyAdmin\DatabaseInterface::getError() can also be of type boolean; however, PhpMyAdmin\Message::rawError() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
464
                )
465
            );
466
        }
467
        return $message;
468
    }
469
470
    /**
471
     * Make the columns of given tables consistent with central list of columns.
472
     * Updates only those columns which are not being referenced.
473
     *
474
     * @param string $db              current database
475
     * @param array  $selected_tables list of selected tables.
476
     *
477
     * @return true|PhpMyAdmin\Message
478
     */
479
    public function makeConsistentWithList(
480
        $db,
481
        array $selected_tables
482
    ) {
483
        $message = true;
484
        foreach ($selected_tables as $table) {
485
            $query = 'ALTER TABLE ' . Util::backquote($table);
486
            $has_list = $this->getFromTable($db, $table, true);
487
            $this->dbi->selectDb($db);
488
            foreach ($has_list as $column) {
489
                $column_status = Relation::checkChildForeignReferences(
490
                    $db, $table, $column['col_name']
491
                );
492
                //column definition can only be changed if
493
                //it is not referenced by another column
494
                if ($column_status['isEditable']) {
495
                    $query .= ' MODIFY ' . Util::backquote($column['col_name']) . ' '
496
                        . $this->dbi->escapeString($column['col_type']);
497
                    if ($column['col_length']) {
498
                        $query .= '(' . $column['col_length'] . ')';
499
                    }
500
501
                    $query .= ' ' . $column['col_attribute'];
502
                    if ($column['col_isNull']) {
503
                        $query .= ' NULL';
504
                    } else {
505
                        $query .= ' NOT NULL';
506
                    }
507
508
                    $query .= ' ' . $column['col_extra'];
509
                    if ($column['col_default']) {
510
                        if ($column['col_default'] != 'CURRENT_TIMESTAMP') {
511
                            $query .= ' DEFAULT \'' . $this->dbi->escapeString(
512
                                $column['col_default']
513
                            ) . '\'';
514
                        } else {
515
                            $query .= ' DEFAULT ' . $this->dbi->escapeString(
516
                                $column['col_default']
517
                            );
518
                        }
519
                    }
520
                    $query .= ',';
521
                }
522
            }
523
            $query = trim($query, " ,") . ";";
524
            if (!$this->dbi->tryQuery($query)) {
525
                if ($message === true) {
526
                    $message = Message::error(
527
                        $this->dbi->getError()
0 ignored issues
show
Bug introduced by
It seems like $this->dbi->getError() targeting PhpMyAdmin\DatabaseInterface::getError() can also be of type boolean; however, PhpMyAdmin\Message::error() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
528
                    );
529
                } else {
530
                    $message->addText(
531
                        $this->dbi->getError(),
0 ignored issues
show
Bug introduced by
It seems like $this->dbi->getError() targeting PhpMyAdmin\DatabaseInterface::getError() can also be of type boolean; however, PhpMyAdmin\Message::addText() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
532
                        '<br />'
533
                    );
534
                }
535
            }
536
        }
537
        return $message;
538
    }
539
540
    /**
541
     * return the columns present in central list of columns for a given
542
     * table of a given database
543
     *
544
     * @param string  $db        given database
545
     * @param string  $table     given table
546
     * @param boolean $allFields set if need all the fields of existing columns,
547
     *                           otherwise only column_name is returned
548
     *
549
     * @return array columns present in central list from given table of given db.
550
     */
551
    public function getFromTable(
552
        $db,
553
        $table,
554
        $allFields = false
555
    ) {
556
        $cfgCentralColumns = $this->getParams();
557
        if (empty($cfgCentralColumns)) {
558
            return array();
559
        }
560
        $this->dbi->selectDb($db);
561
        $fields = (array) $this->dbi->getColumnNames(
562
            $db, $table
563
        );
564
        $cols = '';
565
        foreach ($fields as $col_select) {
566
            $cols .= '\'' . $this->dbi->escapeString($col_select) . '\',';
567
        }
568
        $cols = trim($cols, ',');
569
        $has_list = $this->findExistingColNames($db, $cols, $allFields);
570
        if (! empty($has_list)) {
571
            return (array)$has_list;
572
        }
573
574
        return array();
575
    }
576
577
    /**
578
     * update a column in central columns list if a edit is requested
579
     *
580
     * @param string $db            current database
581
     * @param string $orig_col_name original column name before edit
582
     * @param string $col_name      new column name
583
     * @param string $col_type      new column type
584
     * @param string $col_attribute new column attribute
585
     * @param string $col_length    new column length
586
     * @param int    $col_isNull    value 1 if new column isNull is true, 0 otherwise
587
     * @param string $collation     new column collation
588
     * @param string $col_extra     new column extra property
589
     * @param string $col_default   new column default value
590
     *
591
     * @return true|PhpMyAdmin\Message
592
     */
593
    public function updateOneColumn(
594
        $db,
595
        $orig_col_name,
596
        $col_name,
597
        $col_type,
598
        $col_attribute,
599
        $col_length,
600
        $col_isNull,
601
        $collation,
602
        $col_extra,
603
        $col_default
604
    ) {
605
        $cfgCentralColumns = $this->getParams();
606
        if (empty($cfgCentralColumns)) {
607
            return $this->configErrorMessage();
608
        }
609
        $centralTable = $cfgCentralColumns['table'];
610
        $this->dbi->selectDb($cfgCentralColumns['db'], DatabaseInterface::CONNECT_CONTROL);
611
        if ($orig_col_name == "") {
612
            $def = array();
613
            $def['Type'] = $col_type;
614
            if ($col_length) {
615
                $def['Type'] .= '(' . $col_length . ')';
616
            }
617
            $def['Collation'] = $collation;
618
            $def['Null'] = $col_isNull?__('YES'):__('NO');
619
            $def['Extra'] = $col_extra;
620
            $def['Attribute'] = $col_attribute;
621
            $def['Default'] = $col_default;
622
            $query = $this->getInsertQuery($col_name, $def, $db, $centralTable);
623
        } else {
624
            $query = 'UPDATE ' . Util::backquote($centralTable)
625
                . ' SET col_type = \'' . $this->dbi->escapeString($col_type) . '\''
626
                . ', col_name = \'' . $this->dbi->escapeString($col_name) . '\''
627
                . ', col_length = \'' . $this->dbi->escapeString($col_length) . '\''
628
                . ', col_isNull = ' . $col_isNull
629
                . ', col_collation = \'' . $this->dbi->escapeString($collation) . '\''
630
                . ', col_extra = \''
631
                . implode(',', array($col_extra, $col_attribute)) . '\''
632
                . ', col_default = \'' . $this->dbi->escapeString($col_default) . '\''
633
                . ' WHERE db_name = \'' . $this->dbi->escapeString($db) . '\' '
634
                . 'AND col_name = \'' . $this->dbi->escapeString($orig_col_name)
635
                . '\'';
636
        }
637
        if (!$this->dbi->tryQuery($query, DatabaseInterface::CONNECT_CONTROL)) {
638
            return Message::error(
639
                $this->dbi->getError(DatabaseInterface::CONNECT_CONTROL)
0 ignored issues
show
Bug introduced by
It seems like $this->dbi->getError(\Ph...rface::CONNECT_CONTROL) targeting PhpMyAdmin\DatabaseInterface::getError() can also be of type boolean; however, PhpMyAdmin\Message::error() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
640
            );
641
        }
642
        return true;
643
    }
644
645
    /**
646
     * Update Multiple column in central columns list if a chnage is requested
647
     *
648
     * @return true|PhpMyAdmin\Message
649
     */
650
    public function updateMultipleColumn()
651
    {
652
        $db = $_POST['db'];
653
        $col_name = $_POST['field_name'];
654
        $orig_col_name = $_POST['orig_col_name'];
655
        $col_default = $_POST['field_default_type'];
656
        $col_length = $_POST['field_length'];
657
        $col_attribute = $_POST['field_attribute'];
658
        $col_type = $_POST['field_type'];
659
        $collation = $_POST['field_collation'];
660
        $col_isNull = array();
661
        $col_extra = array();
662
        $num_central_fields = count($orig_col_name);
663
        for ($i = 0; $i < $num_central_fields ; $i++) {
664
            $col_isNull[$i] = isset($_POST['field_null'][$i]) ? 1 : 0;
665
            $col_extra[$i] = isset($_POST['col_extra'][$i])
666
                ? $_POST['col_extra'][$i] : '';
667
668
            if ($col_default[$i] == 'NONE') {
669
                $col_default[$i] = "";
670
            } elseif ($col_default[$i] == 'USER_DEFINED') {
671
                $col_default[$i] = $_POST['field_default_value'][$i];
672
            }
673
674
            $message = $this->updateOneColumn(
675
                $db, $orig_col_name[$i], $col_name[$i], $col_type[$i],
676
                $col_attribute[$i], $col_length[$i], $col_isNull[$i], $collation[$i],
677
                $col_extra[$i], $col_default[$i]
678
            );
679
            if (!is_bool($message)) {
680
                return $message;
681
            }
682
        }
683
        return true;
684
    }
685
686
    /**
687
     * get the html for table navigation in Central columns page
688
     *
689
     * @param int    $total_rows total number of rows in complete result set
690
     * @param int    $pos        offset of first result with complete result set
691
     * @param string $db         current database
692
     *
693
     * @return string html for table navigation in Central columns page
694
     */
695
    public function getHtmlForTableNavigation($total_rows, $pos, $db)
696
    {
697
        $pageNow = ($pos / $this->maxRows) + 1;
698
        $nbTotalPage = ceil($total_rows / $this->maxRows);
699
        $page_selector = ($nbTotalPage > 1)?(Util::pageselector(
700
            'pos', $this->maxRows, $pageNow, $nbTotalPage
701
        )):'';
702
        return  Template::get('database/central_columns/table_navigation')->render(array(
703
            "pos" => $pos,
704
            "max_rows" => $this->maxRows,
705
            "db" => $db,
706
            "total_rows" => $total_rows,
707
            "nb_total_page" => $nbTotalPage,
708
            "page_selector" => $page_selector,
709
        ));
710
    }
711
712
    /**
713
     * function generate and return the table header for central columns page
714
     *
715
     * @param string  $class       styling class of 'th' elements
716
     * @param string  $title       title of the 'th' elements
717
     * @param integer $actionCount number of actions
718
     *
719
     * @return string html for table header in central columns view/edit page
720
     */
721
    public function getTableHeader($class = '', $title = '', $actionCount = 0)
722
    {
723
        $action = '';
724
        if ($actionCount > 0) {
725
            $action .= '<th class="column_action" colspan="' . $actionCount . '">'
726
                . __('Action') . '</th>';
727
        }
728
        $tableheader = '<thead>';
729
        $tableheader .= '<tr>'
730
            . '<th class="' . $class . '"></th>'
731
            . '<th class="hide"></th>'
732
            . $action
733
            . '<th class="' . $class . '" title="' . $title . '" data-column="name">'
734
            . __('Name') . '<div class="sorticon"></div></th>'
735
            . '<th class="' . $class . '" title="' . $title . '" data-column="type">'
736
            . __('Type') . '<div class="sorticon"></div></th>'
737
            . '<th class="' . $class . '" title="' . $title . '" data-column="length">'
738
            . __('Length/Values') . '<div class="sorticon"></div></th>'
739
            . '<th class="' . $class . '" title="' . $title . '" data-column="default">'
740
            . __('Default') . '<div class="sorticon"></div></th>'
741
            . '<th class="' . $class . '" title="' . $title . '" data-column="collation"'
742
            . '>' . __('Collation') . '<div class="sorticon"></div></th>'
743
            . '<th class="' . $class . '" title="' . $title
744
            . '" data-column="attribute">'
745
            . __('Attribute') . '<div class="sorticon"></div></th>'
746
            . '<th class="' . $class . '" title="' . $title . '" data-column="isnull">'
747
            . __('Null') . '<div class="sorticon"></div></th>'
748
            . '<th class="' . $class . '" title="' . $title . '" data-column="extra">'
749
            . __('A_I') . '<div class="sorticon"></div></th>'
750
            . '</tr>';
751
        $tableheader .= '</thead>';
752
        return $tableheader;
753
    }
754
755
    /**
756
     * Function generate and return the table header for
757
     * multiple edit central columns page
758
     *
759
     * @param array $headers headers list
760
     *
761
     * @return string html for table header in central columns multi edit page
762
     */
763
    private function getEditTableHeader(array $headers)
764
    {
765
        return Template::get(
766
            'database/central_columns/edit_table_header'
767
        )->render([
768
            'headers' => $headers,
769
        ]);
770
    }
771
772
    /**
773
     * build the dropdown select html for tables of given database
774
     *
775
     * @param string $db current database
776
     *
777
     * @return string html dropdown for selecting table
778
     */
779
    private function getHtmlForTableDropdown($db)
780
    {
781
        $this->dbi->selectDb($db);
782
        $tables = $this->dbi->getTables($db);
783
        $selectHtml = '<select name="table-select" id="table-select">'
784
            . '<option value="" disabled="disabled" selected="selected">'
785
            . __('Select a table') . '</option>';
786
        foreach ($tables as $table) {
787
            $selectHtml .= '<option value="' . htmlspecialchars($table) . '">'
788
                . htmlspecialchars($table) . '</option>';
789
        }
790
        $selectHtml .= '</select>';
791
        return $selectHtml;
792
    }
793
794
    /**
795
     * build dropdown select html to select column in selected table,
796
     * include only columns which are not already in central list
797
     *
798
     * @param string $db           current database to which selected table belongs
799
     * @param string $selected_tbl selected table
800
     *
801
     * @return string html to select column
802
     */
803
    public function getHtmlForColumnDropdown($db, $selected_tbl)
804
    {
805
        $existing_cols = $this->getFromTable($db, $selected_tbl);
806
        $this->dbi->selectDb($db);
807
        $columns = (array) $this->dbi->getColumnNames(
808
            $db, $selected_tbl
809
        );
810
        $selectColHtml = "";
811 View Code Duplication
        foreach ($columns as $column) {
812
            if (!in_array($column, $existing_cols)) {
813
                $selectColHtml .= '<option value="' . htmlspecialchars($column) . '">'
814
                    . htmlspecialchars($column)
815
                    . '</option>';
816
            }
817
        }
818
        return $selectColHtml;
819
    }
820
821
    /**
822
     * HTML to display the form that let user to add a column on Central columns page
823
     *
824
     * @param int    $total_rows total number of rows in complete result set
825
     * @param int    $pos        offset of first result with complete result set
826
     * @param string $db         current database
827
     *
828
     * @return string html to add a column in the central list
829
     */
830
     public function getHtmlForAddColumn(
831
         $total_rows,
832
         $pos,
833
         $db
834
     ) {
835
         $icon = Util::getIcon(
836
             'centralColumns_add',
837
             __('Add column')
838
         );
839
         $table_drop_down = $this->getHtmlForTableDropdown($db);
840
         return Template::get('database/central_columns/add_column')->render(array(
841
             'icon' => $icon,
842
             'pos' => $pos,
843
             'db' => $db,
844
             'total_rows' => $total_rows,
845
             'table_drop_down' => $table_drop_down,
846
         ));
847
     }
848
849
    /**
850
     * build html for a row in central columns table
851
     *
852
     * @param array  $row     array contains complete information of a particular row of central list table
853
     * @param int    $row_num position the row in the table
854
     * @param string $db      current database
855
     *
856
     * @return string html of a particular row in the central columns table.
857
     */
858
    public function getHtmlForTableRow(array $row, $row_num, $db)
859
    {
860
        $tableHtml = '<tr data-rownum="' . $row_num . '" id="f_' . $row_num . '">'
861
            . Url::getHiddenInputs(
862
                $db
863
            )
864
            . '<input type="hidden" name="edit_save" value="save">'
865
            . '<td class="nowrap">'
866
            . '<input type="checkbox" class="checkall" name="selected_fld[]" '
867
            . 'value="' . htmlspecialchars($row['col_name']) . '" '
868
            . 'id="checkbox_row_' . $row_num . '"/>'
869
            . '</td>'
870
            . '<td id="edit_' . $row_num . '" class="edit center">'
871
            . '<a href="#">' . Util::getIcon('b_edit', __('Edit')) . '</a></td>'
872
            . '<td class="del_row" data-rownum = "' . $row_num . '">'
873
            . '<a hrf="#">' . Util::getIcon('b_drop', __('Delete')) . '</a>'
874
            . '<input type="submit" data-rownum = "' . $row_num . '"'
875
            . ' class="edit_cancel_form" value="Cancel"></td>'
876
            . '<td id="save_' . $row_num . '" class="hide">'
877
            . '<input type="submit" data-rownum = "' . $row_num . '"'
878
            . ' class="edit_save_form" value="Save"></td>';
879
880
        $tableHtml .=
881
            '<td name="col_name" class="nowrap">'
882
            . '<span>' . htmlspecialchars($row['col_name']) . '</span>'
883
            . '<input name="orig_col_name" type="hidden" '
884
            . 'value="' . htmlspecialchars($row['col_name']) . '">'
885
            . Template::get('columns_definitions/column_name')->render(array(
886
                'column_number' => $row_num,
887
                'ci' => 0,
888
                'ci_offset' => 0,
889
                'column_meta' => array(
890
                    'Field'=>$row['col_name']
891
                ),
892
                'cfg_relation' => array(
893
                    'centralcolumnswork' => false
894
                ),
895
                'max_rows' => $this->maxRows,
896
            ))
897
            . '</td>';
898
        $tableHtml .=
899
            '<td name = "col_type" class="nowrap"><span>'
900
            . htmlspecialchars($row['col_type']) . '</span>'
901
            . Template::get('columns_definitions/column_type')
902
                ->render(
903
                    array(
904
                    'column_number' => $row_num,
905
                    'ci' => 1,
906
                    'ci_offset' => 0,
907
                    'type_upper' => mb_strtoupper($row['col_type']),
908
                    'column_meta' => array()
909
                    )
910
                )
911
            . '</td>';
912
        $tableHtml .=
913
            '<td class="nowrap" name="col_length">'
914
            . '<span>' . ($row['col_length']?htmlspecialchars($row['col_length']):"")
915
            . '</span>'
916
            . Template::get('columns_definitions/column_length')->render(
917
                array(
918
                    'column_number' => $row_num,
919
                    'ci' => 2,
920
                    'ci_offset' => 0,
921
                    'length_values_input_size' => 8,
922
                    'length_to_display' => $row['col_length']
923
                )
924
            )
925
            . '</td>';
926
927
        $meta = array();
928 View Code Duplication
        if (!isset($row['col_default']) || $row['col_default'] == '') {
929
            $meta['DefaultType'] = 'NONE';
930
        } else {
931
            if ($row['col_default'] == 'CURRENT_TIMESTAMP'
932
                || $row['col_default'] == 'NULL'
933
            ) {
934
                $meta['DefaultType'] = $row['col_default'];
935
            } else {
936
                $meta['DefaultType'] = 'USER_DEFINED';
937
                $meta['DefaultValue'] = $row['col_default'];
938
            }
939
        }
940
        $tableHtml .=
941
            '<td class="nowrap" name="col_default"><span>' . (isset($row['col_default'])
942
                ? htmlspecialchars($row['col_default']) : 'None')
943
            . '</span>'
944
            . Template::get('columns_definitions/column_default')
945
                ->render(
946
                    array(
947
                    'column_number' => $row_num,
948
                    'ci' => 3,
949
                    'ci_offset' => 0,
950
                    'type_upper' => mb_strtoupper($row['col_type']),
951
                    'column_meta' => $meta,
952
                    'char_editing' => $this->charEditing,
953
                    )
954
                )
955
            . '</td>';
956
957
        $tableHtml .=
958
            '<td name="collation" class="nowrap">'
959
            . '<span>' . htmlspecialchars($row['col_collation']) . '</span>'
960
            . Charsets::getCollationDropdownBox(
961
                $this->dbi,
962
                $this->disableIs,
963
                'field_collation[' . $row_num . ']',
964
                'field_' . $row_num . '_4', $row['col_collation'], false
965
            )
966
            . '</td>';
967
        $tableHtml .=
968
            '<td class="nowrap" name="col_attribute">'
969
            . '<span>' .
970
            ($row['col_attribute']
971
                ? htmlspecialchars($row['col_attribute']) : "" )
972
            . '</span>'
973
            . Template::get('columns_definitions/column_attribute')
974
                ->render(
975
                    array(
976
                    'column_number' => $row_num,
977
                    'ci' => 5,
978
                    'ci_offset' => 0,
979
                    'extracted_columnspec' => array(),
980
                    'column_meta' => $row['col_attribute'],
981
                    'submit_attribute' => false,
982
                    'attribute_types' => $this->dbi->types->getAttributes(),
983
                    )
984
                )
985
            . '</td>';
986
        $tableHtml .=
987
            '<td class="nowrap" name="col_isNull">'
988
            . '<span>' . ($row['col_isNull'] ? __('Yes') : __('No'))
989
            . '</span>'
990
            . Template::get('columns_definitions/column_null')
991
                ->render(
992
                    array(
993
                    'column_number' => $row_num,
994
                    'ci' => 6,
995
                    'ci_offset' => 0,
996
                    'column_meta' => array(
997
                        'Null' => $row['col_isNull']
998
                    )
999
                    )
1000
                )
1001
            . '</td>';
1002
1003
        $tableHtml .=
1004
            '<td class="nowrap" name="col_extra"><span>'
1005
            . htmlspecialchars($row['col_extra']) . '</span>'
1006
            . Template::get('columns_definitions/column_extra')->render(
1007
                array(
1008
                    'column_number' => $row_num,
1009
                    'ci' => 7,
1010
                    'ci_offset' => 0,
1011
                    'column_meta' => array('Extra'=>$row['col_extra'])
1012
                )
1013
            )
1014
            . '</td>';
1015
1016
        $tableHtml .= '</tr>';
1017
1018
        return $tableHtml;
1019
    }
1020
1021
    /**
1022
     * build html for editing a row in central columns table
1023
     *
1024
     * @param array $row     array contains complete information of a
1025
     *                       particular row of central list table
1026
     * @param int   $row_num position the row in the table
1027
     *
1028
     * @return string html of a particular row in the central columns table.
1029
     */
1030
    private function getHtmlForEditTableRow(array $row, $row_num)
1031
    {
1032
        $tableHtml = '<tr>'
1033
            . '<input name="orig_col_name[' . $row_num . ']" type="hidden" '
1034
            . 'value="' . htmlspecialchars($row['col_name']) . '">'
1035
            . '<td name="col_name" class="nowrap">'
1036
            . Template::get('columns_definitions/column_name')->render(array(
1037
                'column_number' => $row_num,
1038
                'ci' => 0,
1039
                'ci_offset' => 0,
1040
                'column_meta' => array(
1041
                    'Field' => $row['col_name']
1042
                ),
1043
                'cfg_relation' => array(
1044
                    'centralcolumnswork' => false
1045
                ),
1046
                'max_rows' => $this->maxRows,
1047
            ))
1048
            . '</td>';
1049
        $tableHtml .=
1050
            '<td name = "col_type" class="nowrap">'
1051
            . Template::get('columns_definitions/column_type')
1052
                ->render(
1053
                    array(
1054
                    'column_number' => $row_num,
1055
                    'ci' => 1,
1056
                    'ci_offset' => 0,
1057
                    'type_upper' => mb_strtoupper($row['col_type']),
1058
                    'column_meta' => array()
1059
                    )
1060
                )
1061
            . '</td>';
1062
        $tableHtml .=
1063
            '<td class="nowrap" name="col_length">'
1064
            . Template::get('columns_definitions/column_length')->render(
1065
                array(
1066
                    'column_number' => $row_num,
1067
                    'ci' => 2,
1068
                    'ci_offset' => 0,
1069
                    'length_values_input_size' => 8,
1070
                    'length_to_display' => $row['col_length']
1071
                )
1072
            )
1073
            . '</td>';
1074
        $meta = array();
1075 View Code Duplication
        if (!isset($row['col_default']) || $row['col_default'] == '') {
1076
            $meta['DefaultType'] = 'NONE';
1077
        } else {
1078
            if ($row['col_default'] == 'CURRENT_TIMESTAMP'
1079
                || $row['col_default'] == 'NULL'
1080
            ) {
1081
                $meta['DefaultType'] = $row['col_default'];
1082
            } else {
1083
                $meta['DefaultType'] = 'USER_DEFINED';
1084
                $meta['DefaultValue'] = $row['col_default'];
1085
            }
1086
        }
1087
        $tableHtml .=
1088
            '<td class="nowrap" name="col_default">'
1089
            . Template::get('columns_definitions/column_default')
1090
                ->render(
1091
                    array(
1092
                    'column_number' => $row_num,
1093
                    'ci' => 3,
1094
                    'ci_offset' => 0,
1095
                    'type_upper' => mb_strtoupper($row['col_default']),
1096
                    'column_meta' => $meta,
1097
                    'char_editing' => $this->charEditing,
1098
                    )
1099
                )
1100
            . '</td>';
1101
        $tableHtml .=
1102
            '<td name="collation" class="nowrap">'
1103
            . Charsets::getCollationDropdownBox(
1104
                $this->dbi,
1105
                $this->disableIs,
1106
                'field_collation[' . $row_num . ']',
1107
                'field_' . $row_num . '_4', $row['col_collation'], false
1108
            )
1109
            . '</td>';
1110
        $tableHtml .=
1111
            '<td class="nowrap" name="col_attribute">'
1112
            . Template::get('columns_definitions/column_attribute')
1113
                ->render(
1114
                    array(
1115
                    'column_number' => $row_num,
1116
                    'ci' => 5,
1117
                    'ci_offset' => 0,
1118
                    'extracted_columnspec' => array(
1119
                        'attribute' => $row['col_attribute']
1120
                    ),
1121
                    'column_meta' => array(),
1122
                    'submit_attribute' => false,
1123
                    'attribute_types' => $this->dbi->types->getAttributes(),
1124
                    )
1125
                )
1126
            . '</td>';
1127
        $tableHtml .=
1128
            '<td class="nowrap" name="col_isNull">'
1129
            . Template::get('columns_definitions/column_null')
1130
                ->render(
1131
                    array(
1132
                    'column_number' => $row_num,
1133
                    'ci' => 6,
1134
                    'ci_offset' => 0,
1135
                    'column_meta' => array(
1136
                        'Null' => $row['col_isNull']
1137
                    )
1138
                    )
1139
                )
1140
            . '</td>';
1141
1142
        $tableHtml .=
1143
            '<td class="nowrap" name="col_extra">'
1144
            . Template::get('columns_definitions/column_extra')->render(
1145
                array(
1146
                    'column_number' => $row_num,
1147
                    'ci' => 7,
1148
                    'ci_offset' => 0,
1149
                    'column_meta' => array('Extra' => $row['col_extra'])
1150
                )
1151
            )
1152
            . '</td>';
1153
        $tableHtml .= '</tr>';
1154
        return $tableHtml;
1155
    }
1156
1157
    /**
1158
     * get the list of columns in given database excluding
1159
     * the columns present in current table
1160
     *
1161
     * @param string $db    selected database
1162
     * @param string $table current table name
1163
     *
1164
     * @return string encoded list of columns present in central list for the given
1165
     *                database
1166
     */
1167
    public function getListRaw($db, $table)
1168
    {
1169
        $cfgCentralColumns = $this->getParams();
1170
        if (empty($cfgCentralColumns)) {
1171
            return json_encode(array());
1172
        }
1173
        $centralTable = $cfgCentralColumns['table'];
1174
        if (empty($table) || $table == '') {
1175
            $query = 'SELECT * FROM ' . Util::backquote($centralTable) . ' '
1176
                . 'WHERE db_name = \'' . $this->dbi->escapeString($db) . '\';';
1177
        } else {
1178
            $this->dbi->selectDb($db);
1179
            $columns = (array) $this->dbi->getColumnNames(
1180
                $db, $table
1181
            );
1182
            $cols = '';
1183
            foreach ($columns as $col_select) {
1184
                $cols .= '\'' . $this->dbi->escapeString($col_select) . '\',';
1185
            }
1186
            $cols = trim($cols, ',');
1187
            $query = 'SELECT * FROM ' . Util::backquote($centralTable) . ' '
1188
                . 'WHERE db_name = \'' . $this->dbi->escapeString($db) . '\'';
1189
            if ($cols) {
1190
                $query .= ' AND col_name NOT IN (' . $cols . ')';
1191
            }
1192
            $query .= ';';
1193
        }
1194
        $this->dbi->selectDb($cfgCentralColumns['db'], DatabaseInterface::CONNECT_CONTROL);
1195
        $columns_list = (array)$this->dbi->fetchResult(
1196
            $query, null, null, DatabaseInterface::CONNECT_CONTROL
1197
        );
1198
        $this->handleColumnExtra($columns_list);
1199
        return json_encode($columns_list);
1200
    }
1201
1202
    /**
1203
     * Get HTML for "check all" check box with "with selected" dropdown
1204
     *
1205
     * @param string $pmaThemeImage pma theme image url
1206
     * @param string $text_dir      url for text directory
1207
     *
1208
     * @return string $html_output
1209
     */
1210
    public function getTableFooter($pmaThemeImage, $text_dir)
1211
    {
1212
        $html_output = Template::get('select_all')
1213
            ->render(
1214
                array(
1215
                    'pma_theme_image' => $pmaThemeImage,
1216
                    'text_dir'        => $text_dir,
1217
                    'form_name'       => 'tableslistcontainer',
1218
                )
1219
            );
1220
        $html_output .= Util::getButtonOrImage(
1221
            'edit_central_columns', 'mult_submit change_central_columns',
1222
            __('Edit'), 'b_edit', 'edit central columns'
1223
        );
1224
        $html_output .= Util::getButtonOrImage(
1225
            'delete_central_columns', 'mult_submit',
1226
            __('Delete'), 'b_drop',
1227
            'remove_from_central_columns'
1228
        );
1229
        return $html_output;
1230
    }
1231
1232
    /**
1233
     * function generate and return the table footer for
1234
     * multiple edit central columns page
1235
     *
1236
     * @return string html for table footer in central columns multi edit page
1237
     */
1238
    private function getEditTableFooter()
1239
    {
1240
        $html_output = '<fieldset class="tblFooters">'
1241
            . '<input type="submit" '
1242
            . 'name="save_multi_central_column_edit" value="' . __('Save') . '" />'
1243
            . '</fieldset>';
1244
        return $html_output;
1245
    }
1246
1247
    /**
1248
     * Column `col_extra` is used to store both extra and attributes for a column.
1249
     * This method separates them.
1250
     *
1251
     * @param array &$columns_list columns list
1252
     *
1253
     * @return void
1254
     */
1255
    private function handleColumnExtra(array &$columns_list)
1256
    {
1257
        foreach ($columns_list as &$row) {
1258
            $vals = explode(',', $row['col_extra']);
1259
1260
            if (in_array('BINARY', $vals)) {
1261
                $row['col_attribute'] = 'BINARY';
1262
            } elseif (in_array('UNSIGNED', $vals)) {
1263
                $row['col_attribute'] = 'UNSIGNED';
1264
            } elseif (in_array('UNSIGNED ZEROFILL', $vals)) {
1265
                $row['col_attribute'] = 'UNSIGNED ZEROFILL';
1266
            } elseif (in_array('on update CURRENT_TIMESTAMP', $vals)) {
1267
                $row['col_attribute'] = 'on update CURRENT_TIMESTAMP';
1268
            } else {
1269
                $row['col_attribute'] = '';
1270
            }
1271
1272
            if (in_array('auto_increment', $vals)) {
1273
                $row['col_extra'] = 'auto_increment';
1274
            } else {
1275
                $row['col_extra'] = '';
1276
            }
1277
        }
1278
    }
1279
1280
    /**
1281
     * build html for adding a new user defined column to central list
1282
     *
1283
     * @param string  $db         current database
1284
     * @param integer $total_rows number of rows in central columns
1285
     *
1286
     * @return string html of the form to let user add a new user defined column to the
1287
     *                list
1288
     */
1289
    public function getHtmlForAddNewColumn($db, $total_rows)
1290
    {
1291
        $addNewColumn = '<div id="add_col_div" class="topmargin"><a href="#">'
1292
            . '<span>+</span> ' . __('Add new column') . '</a>'
1293
            . '<form id="add_new" class="new_central_col '
1294
            . ($total_rows != 0 ? 'hide"' : '"')
1295
            . 'method="post" action="db_central_columns.php">'
1296
            . Url::getHiddenInputs(
1297
                $db
1298
            )
1299
            . '<input type="hidden" name="add_new_column" value="add_new_column">'
1300
            . '<div class="responsivetable">'
1301
            . '<table>';
1302
        $addNewColumn .= $this->getTableHeader();
1303
        $addNewColumn .= '<tr>'
1304
            . '<td></td>'
1305
            . '<td name="col_name" class="nowrap">'
1306
            . Template::get('columns_definitions/column_name')->render(array(
1307
                'column_number' => 0,
1308
                'ci' => 0,
1309
                'ci_offset' => 0,
1310
                'column_meta' => array(),
1311
                'cfg_relation' => array(
1312
                    'centralcolumnswork' => false
1313
                ),
1314
                'max_rows' => $this->maxRows,
1315
            ))
1316
            . '</td>'
1317
            . '<td name = "col_type" class="nowrap">'
1318
            . Template::get('columns_definitions/column_type')
1319
                ->render(
1320
                    array(
1321
                    'column_number' => 0,
1322
                    'ci' => 1,
1323
                    'ci_offset' => 0,
1324
                    'type_upper' => '',
1325
                    'column_meta' => array()
1326
                    )
1327
                )
1328
            . '</td>'
1329
            . '<td class="nowrap" name="col_length">'
1330
            . Template::get('columns_definitions/column_length')->render(
1331
                array(
1332
                    'column_number' => 0,
1333
                    'ci' => 2,
1334
                    'ci_offset' => 0,
1335
                    'length_values_input_size' => 8,
1336
                    'length_to_display' => ''
1337
                )
1338
            )
1339
            . '</td>'
1340
            . '<td class="nowrap" name="col_default">'
1341
            . Template::get('columns_definitions/column_default')
1342
                ->render(
1343
                    array(
1344
                    'column_number' => 0,
1345
                    'ci' => 3,
1346
                    'ci_offset' => 0,
1347
                    'type_upper' => '',
1348
                    'column_meta' => array(),
1349
                    'char_editing' => $this->charEditing,
1350
                    )
1351
                )
1352
            . '</td>'
1353
            . '<td name="collation" class="nowrap">'
1354
            . Charsets::getCollationDropdownBox(
1355
                $this->dbi,
1356
                $this->disableIs,
1357
                'field_collation[0]',
1358
                'field_0_4', null, false
1359
            )
1360
            . '</td>'
1361
            . '<td class="nowrap" name="col_attribute">'
1362
            . Template::get('columns_definitions/column_attribute')
1363
                ->render(
1364
                    array(
1365
                    'column_number' => 0,
1366
                    'ci' => 5,
1367
                    'ci_offset' => 0,
1368
                    'extracted_columnspec' => array(),
1369
                    'column_meta' => array(),
1370
                    'submit_attribute' => false,
1371
                    'attribute_types' => $this->dbi->types->getAttributes(),
1372
                    )
1373
                )
1374
            . '</td>'
1375
            . '<td class="nowrap" name="col_isNull">'
1376
            . Template::get('columns_definitions/column_null')
1377
                ->render(
1378
                    array(
1379
                    'column_number' => 0,
1380
                    'ci' => 6,
1381
                    'ci_offset' => 0,
1382
                    'column_meta' => array()
1383
                    )
1384
                )
1385
            . '</td>'
1386
            . '<td class="nowrap" name="col_extra">'
1387
            . Template::get('columns_definitions/column_extra')->render(
1388
                array(
1389
                    'column_number' => 0,
1390
                    'ci' => 7,
1391
                    'ci_offset' => 0,
1392
                    'column_meta' => array()
1393
                )
1394
            )
1395
            . '</td>'
1396
            . ' <td>'
1397
            . '<input id="add_column_save" type="submit" '
1398
            . ' value="Save"/></td>'
1399
            . '</tr>';
1400
        $addNewColumn .= '</table></div></form></div>';
1401
        return $addNewColumn;
1402
    }
1403
1404
    /**
1405
     * Get HTML for editing page central columns
1406
     *
1407
     * @param array  $selected_fld Array containing the selected fields
1408
     * @param string $selected_db  String containing the name of database
1409
     *
1410
     * @return string HTML for complete editing page for central columns
1411
     */
1412
    public function getHtmlForEditingPage(array $selected_fld, $selected_db)
1413
    {
1414
        $html = '<form id="multi_edit_central_columns">';
1415
        $header_cells = array(
1416
            __('Name'), __('Type'), __('Length/Values'), __('Default'),
1417
            __('Collation'), __('Attributes'), __('Null'), __('A_I')
1418
        );
1419
        $html .= $this->getEditTableHeader($header_cells);
1420
        $selected_fld_safe = array();
1421
        foreach ($selected_fld as $key) {
1422
            $selected_fld_safe[] = $this->dbi->escapeString($key);
1423
        }
1424
        $columns_list = implode("','", $selected_fld_safe);
1425
        $columns_list = "'" . $columns_list . "'";
1426
        $list_detail_cols = $this->findExistingColNames($selected_db, $columns_list, true);
1427
        $row_num = 0;
1428
        foreach ($list_detail_cols as $row) {
1429
            $tableHtmlRow = $this->getHtmlForEditTableRow(
1430
                $row,
1431
                $row_num
1432
            );
1433
            $html .= $tableHtmlRow;
1434
            $row_num++;
1435
        }
1436
        $html .= '</table>';
1437
        $html .= $this->getEditTableFooter();
1438
        $html .= '</form>';
1439
        return $html;
1440
    }
1441
}
1442