Passed
Push — master ( 003da0...69fb1d )
by William
07:21
created

libraries/classes/Plugins/Export/ExportOdt.php (1 issue)

1
<?php
2
/* vim: set expandtab sw=4 ts=4 sts=4: */
3
/**
4
 * Set of functions used to build OpenDocument Text dumps of tables
5
 *
6
 * @package    PhpMyAdmin-Export
7
 * @subpackage ODT
8
 */
9
declare(strict_types=1);
10
11
namespace PhpMyAdmin\Plugins\Export;
12
13
use PhpMyAdmin\DatabaseInterface;
14
use PhpMyAdmin\Export;
15
use PhpMyAdmin\OpenDocument;
16
use PhpMyAdmin\Plugins\ExportPlugin;
17
use PhpMyAdmin\Properties\Plugins\ExportPluginProperties;
18
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup;
19
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup;
20
use PhpMyAdmin\Properties\Options\Items\BoolPropertyItem;
21
use PhpMyAdmin\Properties\Options\Items\RadioPropertyItem;
22
use PhpMyAdmin\Properties\Options\Items\TextPropertyItem;
23
use PhpMyAdmin\Transformations;
24
use PhpMyAdmin\Util;
25
26
/**
27
 * Handles the export for the ODT class
28
 *
29
 * @package    PhpMyAdmin-Export
30
 * @subpackage ODT
31
 */
32
class ExportOdt extends ExportPlugin
33
{
34
    /**
35
     * Constructor
36
     */
37
    public function __construct()
38
    {
39
        parent::__construct();
40
        $GLOBALS['odt_buffer'] = '';
41
        $this->setProperties();
42
    }
43
44
    /**
45
     * Sets the export ODT properties
46
     *
47
     * @return void
48
     */
49
    protected function setProperties()
50
    {
51
        global $plugin_param;
52
        $hide_structure = false;
53
        if ($plugin_param['export_type'] == 'table'
54
            && !$plugin_param['single_table']
55
        ) {
56
            $hide_structure = true;
57
        }
58
59
        $exportPluginProperties = new ExportPluginProperties();
60
        $exportPluginProperties->setText('OpenDocument Text');
61
        $exportPluginProperties->setExtension('odt');
62
        $exportPluginProperties->setMimeType(
63
            'application/vnd.oasis.opendocument.text'
64
        );
65
        $exportPluginProperties->setForceFile(true);
66
        $exportPluginProperties->setOptionsText(__('Options'));
67
68
        // create the root group that will be the options field for
69
        // $exportPluginProperties
70
        // this will be shown as "Format specific options"
71
        $exportSpecificOptions = new OptionsPropertyRootGroup(
72
            "Format Specific Options"
73
        );
74
75
        // what to dump (structure/data/both) main group
76
        $dumpWhat = new OptionsPropertyMainGroup(
77
            "general_opts",
78
            __('Dump table')
79
        );
80
        // create primary items and add them to the group
81
        $leaf = new RadioPropertyItem("structure_or_data");
82
        $leaf->setValues(
83
            [
84
                'structure'          => __('structure'),
85
                'data'               => __('data'),
86
                'structure_and_data' => __('structure and data'),
87
            ]
88
        );
89
        $dumpWhat->addProperty($leaf);
90
        // add the main group to the root group
91
        $exportSpecificOptions->addProperty($dumpWhat);
92
93
        // structure options main group
94
        if (!$hide_structure) {
95
            $structureOptions = new OptionsPropertyMainGroup(
96
                "structure",
97
                __('Object creation options')
98
            );
99
            $structureOptions->setForce('data');
100
            // create primary items and add them to the group
101
            if (!empty($GLOBALS['cfgRelation']['relation'])) {
102
                $leaf = new BoolPropertyItem(
103
                    "relation",
104
                    __('Display foreign key relationships')
105
                );
106
                $structureOptions->addProperty($leaf);
107
            }
108
            $leaf = new BoolPropertyItem(
109
                "comments",
110
                __('Display comments')
111
            );
112
            $structureOptions->addProperty($leaf);
113
            if (!empty($GLOBALS['cfgRelation']['mimework'])) {
114
                $leaf = new BoolPropertyItem(
115
                    "mime",
116
                    __('Display MIME types')
117
                );
118
                $structureOptions->addProperty($leaf);
119
            }
120
            // add the main group to the root group
121
            $exportSpecificOptions->addProperty($structureOptions);
122
        }
123
124
        // data options main group
125
        $dataOptions = new OptionsPropertyMainGroup(
126
            "data",
127
            __('Data dump options')
128
        );
129
        $dataOptions->setForce('structure');
130
        // create primary items and add them to the group
131
        $leaf = new BoolPropertyItem(
132
            "columns",
133
            __('Put columns names in the first row')
134
        );
135
        $dataOptions->addProperty($leaf);
136
        $leaf = new TextPropertyItem(
137
            'null',
138
            __('Replace NULL with:')
139
        );
140
        $dataOptions->addProperty($leaf);
141
        // add the main group to the root group
142
        $exportSpecificOptions->addProperty($dataOptions);
143
144
        // set the options for the export plugin property item
145
        $exportPluginProperties->setOptions($exportSpecificOptions);
146
        $this->properties = $exportPluginProperties;
147
    }
148
149
    /**
150
     * Outputs export header
151
     *
152
     * @return bool Whether it succeeded
153
     */
154
    public function exportHeader()
155
    {
156
        $GLOBALS['odt_buffer'] .= '<?xml version="1.0" encoding="utf-8"?' . '>'
157
            . '<office:document-content '
158
            . OpenDocument::NS . ' office:version="1.0">'
159
            . '<office:body>'
160
            . '<office:text>';
161
162
        return true;
163
    }
164
165
    /**
166
     * Outputs export footer
167
     *
168
     * @return bool Whether it succeeded
169
     */
170
    public function exportFooter()
171
    {
172
        $GLOBALS['odt_buffer'] .= '</office:text>'
173
            . '</office:body>'
174
            . '</office:document-content>';
175
        if (!$this->export->outputHandler(
176
            OpenDocument::create(
177
                'application/vnd.oasis.opendocument.text',
178
                $GLOBALS['odt_buffer']
179
            )
180
        )
181
        ) {
182
            return false;
183
        }
184
185
        return true;
186
    }
187
188
    /**
189
     * Outputs database header
190
     *
191
     * @param string $db       Database name
192
     * @param string $db_alias Aliases of db
193
     *
194
     * @return bool Whether it succeeded
195
     */
196
    public function exportDBHeader($db, $db_alias = '')
197
    {
198
        if (empty($db_alias)) {
199
            $db_alias = $db;
200
        }
201
        $GLOBALS['odt_buffer']
202
            .= '<text:h text:outline-level="1" text:style-name="Heading_1"'
203
            . ' text:is-list-header="true">'
204
            . __('Database') . ' ' . htmlspecialchars($db_alias)
205
            . '</text:h>';
206
207
        return true;
208
    }
209
210
    /**
211
     * Outputs database footer
212
     *
213
     * @param string $db Database name
214
     *
215
     * @return bool Whether it succeeded
216
     */
217
    public function exportDBFooter($db)
218
    {
219
        return true;
220
    }
221
222
    /**
223
     * Outputs CREATE DATABASE statement
224
     *
225
     * @param string $db          Database name
226
     * @param string $export_type 'server', 'database', 'table'
227
     * @param string $db_alias    Aliases of db
228
     *
229
     * @return bool Whether it succeeded
230
     */
231
    public function exportDBCreate($db, $export_type, $db_alias = '')
232
    {
233
        return true;
234
    }
235
236
    /**
237
     * Outputs the content of a table in NHibernate format
238
     *
239
     * @param string $db        database name
240
     * @param string $table     table name
241
     * @param string $crlf      the end of line sequence
242
     * @param string $error_url the url to go back in case of error
243
     * @param string $sql_query SQL query for obtaining data
244
     * @param array  $aliases   Aliases of db/table/columns
245
     *
246
     * @return bool Whether it succeeded
247
     */
248
    public function exportData(
249
        $db,
250
        $table,
251
        $crlf,
252
        $error_url,
253
        $sql_query,
254
        array $aliases = []
255
    ) {
256
        global $what;
257
258
        $db_alias = $db;
259
        $table_alias = $table;
260
        $this->initAlias($aliases, $db_alias, $table_alias);
261
        // Gets the data from the database
262
        $result = $GLOBALS['dbi']->query(
263
            $sql_query,
264
            DatabaseInterface::CONNECT_USER,
265
            DatabaseInterface::QUERY_UNBUFFERED
266
        );
267
        $fields_cnt = $GLOBALS['dbi']->numFields($result);
268
        $fields_meta = $GLOBALS['dbi']->getFieldsMeta($result);
269
        $field_flags = [];
270
        for ($j = 0; $j < $fields_cnt; $j++) {
271
            $field_flags[$j] = $GLOBALS['dbi']->fieldFlags($result, $j);
272
        }
273
274
        $GLOBALS['odt_buffer']
275
            .= '<text:h text:outline-level="2" text:style-name="Heading_2"'
276
            . ' text:is-list-header="true">'
277
            . __('Dumping data for table') . ' ' . htmlspecialchars($table_alias)
278
            . '</text:h>'
279
            . '<table:table'
280
            . ' table:name="' . htmlspecialchars($table_alias) . '_structure">'
281
            . '<table:table-column'
282
            . ' table:number-columns-repeated="' . $fields_cnt . '"/>';
283
284
        // If required, get fields name at the first line
285
        if (isset($GLOBALS[$what . '_columns'])) {
286
            $GLOBALS['odt_buffer'] .= '<table:table-row>';
287
            for ($i = 0; $i < $fields_cnt; $i++) {
288
                $col_as = $GLOBALS['dbi']->fieldName($result, $i);
289
                if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
290
                    $col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
291
                }
292
                $GLOBALS['odt_buffer']
293
                    .= '<table:table-cell office:value-type="string">'
294
                    . '<text:p>'
295
                    . htmlspecialchars(
296
                        stripslashes($col_as)
297
                    )
298
                    . '</text:p>'
299
                    . '</table:table-cell>';
300
            } // end for
301
            $GLOBALS['odt_buffer'] .= '</table:table-row>';
302
        } // end if
303
304
        // Format the data
305
        while ($row = $GLOBALS['dbi']->fetchRow($result)) {
306
            $GLOBALS['odt_buffer'] .= '<table:table-row>';
307
            for ($j = 0; $j < $fields_cnt; $j++) {
308
                if (!isset($row[$j]) || is_null($row[$j])) {
309
                    $GLOBALS['odt_buffer']
310
                        .= '<table:table-cell office:value-type="string">'
311
                        . '<text:p>'
312
                        . htmlspecialchars($GLOBALS[$what . '_null'])
313
                        . '</text:p>'
314
                        . '</table:table-cell>';
315
                } elseif (stristr($field_flags[$j], 'BINARY')
316
                    && $fields_meta[$j]->blob
317
                ) {
318
                    // ignore BLOB
319
                    $GLOBALS['odt_buffer']
320
                        .= '<table:table-cell office:value-type="string">'
321
                        . '<text:p></text:p>'
322
                        . '</table:table-cell>';
323
                } elseif ($fields_meta[$j]->numeric
324
                    && $fields_meta[$j]->type != 'timestamp'
325
                    && !$fields_meta[$j]->blob
326
                ) {
327
                    $GLOBALS['odt_buffer']
328
                        .= '<table:table-cell office:value-type="float"'
329
                        . ' office:value="' . $row[$j] . '" >'
330
                        . '<text:p>'
331
                        . htmlspecialchars($row[$j])
332
                        . '</text:p>'
333
                        . '</table:table-cell>';
334
                } else {
335
                    $GLOBALS['odt_buffer']
336
                        .= '<table:table-cell office:value-type="string">'
337
                        . '<text:p>'
338
                        . htmlspecialchars($row[$j])
339
                        . '</text:p>'
340
                        . '</table:table-cell>';
341
                }
342
            } // end for
343
            $GLOBALS['odt_buffer'] .= '</table:table-row>';
344
        } // end while
345
        $GLOBALS['dbi']->freeResult($result);
346
347
        $GLOBALS['odt_buffer'] .= '</table:table>';
348
349
        return true;
350
    }
351
352
    /**
353
     * Returns a stand-in CREATE definition to resolve view dependencies
354
     *
355
     * @param string $db      the database name
356
     * @param string $view    the view name
357
     * @param string $crlf    the end of line sequence
358
     * @param array  $aliases Aliases of db/table/columns
359
     *
360
     * @return string resulting definition
361
     */
362
    public function getTableDefStandIn($db, $view, $crlf, $aliases = [])
363
    {
364
        $db_alias = $db;
365
        $view_alias = $view;
366
        $this->initAlias($aliases, $db_alias, $view_alias);
367
        /**
368
         * Gets fields properties
369
         */
370
        $GLOBALS['dbi']->selectDb($db);
371
372
        /**
373
         * Displays the table structure
374
         */
375
        $GLOBALS['odt_buffer']
376
            .= '<table:table table:name="'
377
            . htmlspecialchars($view_alias) . '_data">';
378
        $columns_cnt = 4;
379
        $GLOBALS['odt_buffer']
380
            .= '<table:table-column'
381
            . ' table:number-columns-repeated="' . $columns_cnt . '"/>';
382
        /* Header */
383
        $GLOBALS['odt_buffer'] .= '<table:table-row>'
384
            . '<table:table-cell office:value-type="string">'
385
            . '<text:p>' . __('Column') . '</text:p>'
386
            . '</table:table-cell>'
387
            . '<table:table-cell office:value-type="string">'
388
            . '<text:p>' . __('Type') . '</text:p>'
389
            . '</table:table-cell>'
390
            . '<table:table-cell office:value-type="string">'
391
            . '<text:p>' . __('Null') . '</text:p>'
392
            . '</table:table-cell>'
393
            . '<table:table-cell office:value-type="string">'
394
            . '<text:p>' . __('Default') . '</text:p>'
395
            . '</table:table-cell>'
396
            . '</table:table-row>';
397
398
        $columns = $GLOBALS['dbi']->getColumns($db, $view);
399
        foreach ($columns as $column) {
400
            $col_as = $column['Field'];
401
            if (!empty($aliases[$db]['tables'][$view]['columns'][$col_as])) {
402
                $col_as = $aliases[$db]['tables'][$view]['columns'][$col_as];
403
            }
404
            $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition(
405
                $column,
406
                $col_as
407
            );
408
            $GLOBALS['odt_buffer'] .= '</table:table-row>';
409
        } // end foreach
410
411
        $GLOBALS['odt_buffer'] .= '</table:table>';
412
413
        return true;
414
    }
415
416
    /**
417
     * Returns $table's CREATE definition
418
     *
419
     * @param string $db            the database name
420
     * @param string $table         the table name
421
     * @param string $crlf          the end of line sequence
422
     * @param string $error_url     the url to go back in case of error
423
     * @param bool   $do_relation   whether to include relation comments
424
     * @param bool   $do_comments   whether to include the pmadb-style column
425
     *                              comments as comments in the structure;
426
     *                              this is deprecated but the parameter is
427
     *                              left here because export.php calls
428
     *                              PMA_exportStructure() also for other
429
     * @param bool   $do_mime       whether to include mime comments
430
     * @param bool   $show_dates    whether to include creation/update/check dates
431
     * @param bool   $add_semicolon whether to add semicolon and end-of-line at
432
     *                              the end
433
     * @param bool   $view          whether we're handling a view
434
     * @param array  $aliases       Aliases of db/table/columns
435
     *
436
     * @return bool true
437
     */
438
    public function getTableDef(
439
        $db,
440
        $table,
441
        $crlf,
442
        $error_url,
443
        $do_relation,
444
        $do_comments,
445
        $do_mime,
446
        $show_dates = false,
447
        $add_semicolon = true,
448
        $view = false,
0 ignored issues
show
The parameter $view is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

448
        /** @scrutinizer ignore-unused */ $view = false,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
449
        array $aliases = []
450
    ) {
451
        global $cfgRelation;
452
453
        $db_alias = $db;
454
        $table_alias = $table;
455
        $this->initAlias($aliases, $db_alias, $table_alias);
456
        /**
457
         * Gets fields properties
458
         */
459
        $GLOBALS['dbi']->selectDb($db);
460
461
        // Check if we can use Relations
462
        list($res_rel, $have_rel) = $this->relation->getRelationsAndStatus(
463
            $do_relation && !empty($cfgRelation['relation']),
464
            $db,
465
            $table
466
        );
467
        /**
468
         * Displays the table structure
469
         */
470
        $GLOBALS['odt_buffer'] .= '<table:table table:name="'
471
            . htmlspecialchars($table_alias) . '_structure">';
472
        $columns_cnt = 4;
473
        if ($do_relation && $have_rel) {
474
            $columns_cnt++;
475
        }
476
        if ($do_comments) {
477
            $columns_cnt++;
478
        }
479
        if ($do_mime && $cfgRelation['mimework']) {
480
            $columns_cnt++;
481
        }
482
        $GLOBALS['odt_buffer'] .= '<table:table-column'
483
            . ' table:number-columns-repeated="' . $columns_cnt . '"/>';
484
        /* Header */
485
        $GLOBALS['odt_buffer'] .= '<table:table-row>'
486
            . '<table:table-cell office:value-type="string">'
487
            . '<text:p>' . __('Column') . '</text:p>'
488
            . '</table:table-cell>'
489
            . '<table:table-cell office:value-type="string">'
490
            . '<text:p>' . __('Type') . '</text:p>'
491
            . '</table:table-cell>'
492
            . '<table:table-cell office:value-type="string">'
493
            . '<text:p>' . __('Null') . '</text:p>'
494
            . '</table:table-cell>'
495
            . '<table:table-cell office:value-type="string">'
496
            . '<text:p>' . __('Default') . '</text:p>'
497
            . '</table:table-cell>';
498
        if ($do_relation && $have_rel) {
499
            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
500
                . '<text:p>' . __('Links to') . '</text:p>'
501
                . '</table:table-cell>';
502
        }
503
        if ($do_comments) {
504
            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
505
                . '<text:p>' . __('Comments') . '</text:p>'
506
                . '</table:table-cell>';
507
            $comments = $this->relation->getComments($db, $table);
508
        }
509
        if ($do_mime && $cfgRelation['mimework']) {
510
            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
511
                . '<text:p>' . __('MIME type') . '</text:p>'
512
                . '</table:table-cell>';
513
            $mime_map = $this->transformations->getMime($db, $table, true);
514
        }
515
        $GLOBALS['odt_buffer'] .= '</table:table-row>';
516
517
        $columns = $GLOBALS['dbi']->getColumns($db, $table);
518
        foreach ($columns as $column) {
519
            $col_as = $field_name = $column['Field'];
520
            if (!empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
521
                $col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
522
            }
523
            $GLOBALS['odt_buffer'] .= $this->formatOneColumnDefinition(
524
                $column,
525
                $col_as
526
            );
527
            if ($do_relation && $have_rel) {
528
                $foreigner = $this->relation->searchColumnInForeigners($res_rel, $field_name);
529
                if ($foreigner) {
530
                    $rtable = $foreigner['foreign_table'];
531
                    $rfield = $foreigner['foreign_field'];
532
                    if (!empty($aliases[$db]['tables'][$rtable]['columns'][$rfield])
533
                    ) {
534
                        $rfield
535
                            = $aliases[$db]['tables'][$rtable]['columns'][$rfield];
536
                    }
537
                    if (!empty($aliases[$db]['tables'][$rtable]['alias'])) {
538
                        $rtable = $aliases[$db]['tables'][$rtable]['alias'];
539
                    }
540
                    $relation = htmlspecialchars($rtable . ' (' . $rfield . ')');
541
                    $GLOBALS['odt_buffer']
542
                        .= '<table:table-cell office:value-type="string">'
543
                        . '<text:p>'
544
                        . htmlspecialchars($relation)
545
                        . '</text:p>'
546
                        . '</table:table-cell>';
547
                }
548
            }
549
            if ($do_comments) {
550
                if (isset($comments[$field_name])) {
551
                    $GLOBALS['odt_buffer']
552
                        .= '<table:table-cell office:value-type="string">'
553
                        . '<text:p>'
554
                        . htmlspecialchars($comments[$field_name])
555
                        . '</text:p>'
556
                        . '</table:table-cell>';
557
                } else {
558
                    $GLOBALS['odt_buffer']
559
                        .= '<table:table-cell office:value-type="string">'
560
                        . '<text:p></text:p>'
561
                        . '</table:table-cell>';
562
                }
563
            }
564
            if ($do_mime && $cfgRelation['mimework']) {
565
                if (isset($mime_map[$field_name])) {
566
                    $GLOBALS['odt_buffer']
567
                        .= '<table:table-cell office:value-type="string">'
568
                        . '<text:p>'
569
                        . htmlspecialchars(
570
                            str_replace('_', '/', $mime_map[$field_name]['mimetype'])
571
                        )
572
                        . '</text:p>'
573
                        . '</table:table-cell>';
574
                } else {
575
                    $GLOBALS['odt_buffer']
576
                        .= '<table:table-cell office:value-type="string">'
577
                        . '<text:p></text:p>'
578
                        . '</table:table-cell>';
579
                }
580
            }
581
            $GLOBALS['odt_buffer'] .= '</table:table-row>';
582
        } // end foreach
583
584
        $GLOBALS['odt_buffer'] .= '</table:table>';
585
586
        return true;
587
    } // end of the '$this->getTableDef()' function
588
589
    /**
590
     * Outputs triggers
591
     *
592
     * @param string $db      database name
593
     * @param string $table   table name
594
     * @param array  $aliases Aliases of db/table/columns
595
     *
596
     * @return bool true
597
     */
598
    protected function getTriggers($db, $table, array $aliases = [])
599
    {
600
        $db_alias = $db;
601
        $table_alias = $table;
602
        $this->initAlias($aliases, $db_alias, $table_alias);
603
        $GLOBALS['odt_buffer'] .= '<table:table'
604
            . ' table:name="' . htmlspecialchars($table_alias) . '_triggers">'
605
            . '<table:table-column'
606
            . ' table:number-columns-repeated="4"/>'
607
            . '<table:table-row>'
608
            . '<table:table-cell office:value-type="string">'
609
            . '<text:p>' . __('Name') . '</text:p>'
610
            . '</table:table-cell>'
611
            . '<table:table-cell office:value-type="string">'
612
            . '<text:p>' . __('Time') . '</text:p>'
613
            . '</table:table-cell>'
614
            . '<table:table-cell office:value-type="string">'
615
            . '<text:p>' . __('Event') . '</text:p>'
616
            . '</table:table-cell>'
617
            . '<table:table-cell office:value-type="string">'
618
            . '<text:p>' . __('Definition') . '</text:p>'
619
            . '</table:table-cell>'
620
            . '</table:table-row>';
621
622
        $triggers = $GLOBALS['dbi']->getTriggers($db, $table);
623
624
        foreach ($triggers as $trigger) {
625
            $GLOBALS['odt_buffer'] .= '<table:table-row>';
626
            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
627
                . '<text:p>'
628
                . htmlspecialchars($trigger['name'])
629
                . '</text:p>'
630
                . '</table:table-cell>';
631
            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
632
                . '<text:p>'
633
                . htmlspecialchars($trigger['action_timing'])
634
                . '</text:p>'
635
                . '</table:table-cell>';
636
            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
637
                . '<text:p>'
638
                . htmlspecialchars($trigger['event_manipulation'])
639
                . '</text:p>'
640
                . '</table:table-cell>';
641
            $GLOBALS['odt_buffer'] .= '<table:table-cell office:value-type="string">'
642
                . '<text:p>'
643
                . htmlspecialchars($trigger['definition'])
644
                . '</text:p>'
645
                . '</table:table-cell>';
646
            $GLOBALS['odt_buffer'] .= '</table:table-row>';
647
        }
648
649
        $GLOBALS['odt_buffer'] .= '</table:table>';
650
651
        return true;
652
    }
653
654
    /**
655
     * Outputs table's structure
656
     *
657
     * @param string $db          database name
658
     * @param string $table       table name
659
     * @param string $crlf        the end of line sequence
660
     * @param string $error_url   the url to go back in case of error
661
     * @param string $export_mode 'create_table', 'triggers', 'create_view',
662
     *                            'stand_in'
663
     * @param string $export_type 'server', 'database', 'table'
664
     * @param bool   $do_relation whether to include relation comments
665
     * @param bool   $do_comments whether to include the pmadb-style column
666
     *                            comments as comments in the structure;
667
     *                            this is deprecated but the parameter is
668
     *                            left here because export.php calls
669
     *                            PMA_exportStructure() also for other
670
     * @param bool   $do_mime     whether to include mime comments
671
     * @param bool   $dates       whether to include creation/update/check dates
672
     * @param array  $aliases     Aliases of db/table/columns
673
     *
674
     * @return bool Whether it succeeded
675
     */
676
    public function exportStructure(
677
        $db,
678
        $table,
679
        $crlf,
680
        $error_url,
681
        $export_mode,
682
        $export_type,
683
        $do_relation = false,
684
        $do_comments = false,
685
        $do_mime = false,
686
        $dates = false,
687
        array $aliases = []
688
    ) {
689
        $db_alias = $db;
690
        $table_alias = $table;
691
        $this->initAlias($aliases, $db_alias, $table_alias);
692
        switch ($export_mode) {
693
            case 'create_table':
694
                $GLOBALS['odt_buffer']
695
                .= '<text:h text:outline-level="2" text:style-name="Heading_2"'
696
                . ' text:is-list-header="true">'
697
                . __('Table structure for table') . ' ' .
698
                htmlspecialchars($table_alias)
699
                . '</text:h>';
700
                $this->getTableDef(
701
                    $db,
702
                    $table,
703
                    $crlf,
704
                    $error_url,
705
                    $do_relation,
706
                    $do_comments,
707
                    $do_mime,
708
                    $dates,
709
                    true,
710
                    false,
711
                    $aliases
712
                );
713
                break;
714
            case 'triggers':
715
                $triggers = $GLOBALS['dbi']->getTriggers($db, $table, $aliases);
716
                if ($triggers) {
717
                    $GLOBALS['odt_buffer']
718
                    .= '<text:h text:outline-level="2" text:style-name="Heading_2"'
719
                    . ' text:is-list-header="true">'
720
                    . __('Triggers') . ' '
721
                    . htmlspecialchars($table_alias)
722
                    . '</text:h>';
723
                    $this->getTriggers($db, $table);
724
                }
725
                break;
726
            case 'create_view':
727
                $GLOBALS['odt_buffer']
728
                .= '<text:h text:outline-level="2" text:style-name="Heading_2"'
729
                . ' text:is-list-header="true">'
730
                . __('Structure for view') . ' '
731
                . htmlspecialchars($table_alias)
732
                . '</text:h>';
733
                $this->getTableDef(
734
                    $db,
735
                    $table,
736
                    $crlf,
737
                    $error_url,
738
                    $do_relation,
739
                    $do_comments,
740
                    $do_mime,
741
                    $dates,
742
                    true,
743
                    true,
744
                    $aliases
745
                );
746
                break;
747
            case 'stand_in':
748
                $GLOBALS['odt_buffer']
749
                .= '<text:h text:outline-level="2" text:style-name="Heading_2"'
750
                . ' text:is-list-header="true">'
751
                . __('Stand-in structure for view') . ' '
752
                . htmlspecialchars($table_alias)
753
                . '</text:h>';
754
                // export a stand-in definition to resolve view dependencies
755
                $this->getTableDefStandIn($db, $table, $crlf, $aliases);
756
        } // end switch
757
758
        return true;
759
    } // end of the '$this->exportStructure' function
760
761
    /**
762
     * Formats the definition for one column
763
     *
764
     * @param array  $column info about this column
765
     * @param string $col_as column alias
766
     *
767
     * @return string Formatted column definition
768
     */
769
    protected function formatOneColumnDefinition($column, $col_as = '')
770
    {
771
        if (empty($col_as)) {
772
            $col_as = $column['Field'];
773
        }
774
        $definition = '<table:table-row>';
775
        $definition .= '<table:table-cell office:value-type="string">'
776
            . '<text:p>' . htmlspecialchars($col_as) . '</text:p>'
777
            . '</table:table-cell>';
778
779
        $extracted_columnspec
780
            = Util::extractColumnSpec($column['Type']);
781
        $type = htmlspecialchars($extracted_columnspec['print_type']);
782
        if (empty($type)) {
783
            $type = '&nbsp;';
784
        }
785
786
        $definition .= '<table:table-cell office:value-type="string">'
787
            . '<text:p>' . htmlspecialchars($type) . '</text:p>'
788
            . '</table:table-cell>';
789
        if (!isset($column['Default'])) {
790
            if ($column['Null'] != 'NO') {
791
                $column['Default'] = 'NULL';
792
            } else {
793
                $column['Default'] = '';
794
            }
795
        }
796
        $definition .= '<table:table-cell office:value-type="string">'
797
            . '<text:p>'
798
            . (($column['Null'] == '' || $column['Null'] == 'NO')
799
                ? __('No')
800
                : __('Yes'))
801
            . '</text:p>'
802
            . '</table:table-cell>';
803
        $definition .= '<table:table-cell office:value-type="string">'
804
            . '<text:p>' . htmlspecialchars($column['Default']) . '</text:p>'
805
            . '</table:table-cell>';
806
807
        return $definition;
808
    }
809
}
810