Passed
Push — develop ( 926541...c213cd )
by Felipe
05:17
created

DataexportController::_mimicXml()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 34
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 34
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 25
nc 8
nop 4
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
/**
10
 * Base controller class.
11
 *
12
 * @package PHPPgAdmin
13
 */
14
class DataexportController extends BaseController
15
{
16
    public $extensions = [
17
        'sql'  => 'sql',
18
        'copy' => 'sql',
19
        'csv'  => 'csv',
20
        'tab'  => 'txt',
21
        'html' => 'html',
22
        'xml'  => 'xml',
23
    ];
24
    public $controller_title = 'strexport';
25
26
    /**
27
     * Default method to render the controller according to the action parameter.
28
     */
29
    public function render()
30
    {
31
        set_time_limit(0);
32
33
        // if (!isset($_REQUEST['table']) && !isset($_REQUEST['query']))
34
        // What must we do in this case? Maybe redirect to the homepage?
35
36
        $format = 'N/A';
37
38
        // force behavior to assume there is no pg_dump in the system
39
        $forcemimic = false;
40
41
        // If format is set, then perform the export
42
        if (!isset($_REQUEST['what'])) {
43
            return $this->doDefault();
44
        }
45
46
        $this->prtrace("REQUEST['what']", $_REQUEST['what']);
47
48
        // Include application functions
49
        $this->setNoOutput(true);
50
        $clean = false;
51
        $oids  = false;
52
        switch ($_REQUEST['what']) {
53
            case 'dataonly':
54
                // Check to see if they have pg_dump set up and if they do, use that
55
                // instead of custom dump code
56
                if (!$forcemimic && $this->misc->isDumpEnabled() && ('copy' == $_REQUEST['d_format'] || 'sql' == $_REQUEST['d_format'])) {
1 ignored issue
show
introduced by
The condition $forcemimic is always false.
Loading history...
57
                    $this->prtrace('DUMP ENABLED, d_format is', $_REQUEST['d_format']);
58
                    $dbexport_controller = new \PHPPgAdmin\Controller\DbexportController($this->getContainer());
59
60
                    return $dbexport_controller->render();
61
                }
62
                $this->prtrace('d_format is', $_REQUEST['d_format'], 'd_oids is', isset($_REQUEST['d_oids']));
63
                $format = $_REQUEST['d_format'];
64
                $oids   = isset($_REQUEST['d_oids']);
65
66
                break;
67
            case 'structureonly':
68
                // Check to see if they have pg_dump set up and if they do, use that
69
                // instead of custom dump code
70
                if (!$forcemimic && $this->misc->isDumpEnabled()) {
1 ignored issue
show
introduced by
The condition $forcemimic is always false.
Loading history...
71
                    $dbexport_controller = new \PHPPgAdmin\Controller\DbexportController($this->getContainer());
72
73
                    return $dbexport_controller->render();
74
                }
75
                $clean = isset($_REQUEST['s_clean']);
76
77
                break;
78
            case 'structureanddata':
79
                // Check to see if they have pg_dump set up and if they do, use that
80
                // instead of custom dump code
81
                if (!$forcemimic && $this->misc->isDumpEnabled()) {
1 ignored issue
show
introduced by
The condition $forcemimic is always false.
Loading history...
82
                    $dbexport_controller = new \PHPPgAdmin\Controller\DbexportController($this->getContainer());
83
84
                    return $dbexport_controller->render();
85
                }
86
                $format = $_REQUEST['sd_format'];
87
                $clean  = isset($_REQUEST['sd_clean']);
88
                $oids   = isset($_REQUEST['sd_oids']);
89
90
                break;
91
        }
92
93
        return $this->mimicDumpFeature($format, $clean, $oids);
94
    }
95
96
    protected function mimicDumpFeature($format, $clean, $oids)
97
    {
98
        $data = $this->misc->getDatabaseAccessor();
99
100
        set_time_limit(0);
101
102
        // if (!isset($_REQUEST['table']) && !isset($_REQUEST['query']))
103
        // What must we do in this case? Maybe redirect to the homepage?
104
105
        // If format is set, then perform the export
106
        if (!isset($_REQUEST['what'])) {
107
            return $this->doDefault();
108
        }
109
110
        $this->prtrace("REQUEST['what']", $_REQUEST['what']);
111
112
        // Include application functions
113
        $this->setNoOutput(true);
114
        $clean    = false;
115
        $response = $this
116
            ->container
117
            ->responseobj;
118
119
        // Make it do a download, if necessary
120
        if ('download' == $_REQUEST['output']) {
121
            // Set headers.  MSIE is totally broken for SSL downloading, so
122
            // we need to have it download in-place as plain text
123
            if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS'])) {
124
                $response = $response
125
                    ->withHeader('Content-type', 'text/plain');
126
            } else {
127
                $response = $response
128
                    ->withHeader('Content-type', 'application/download');
129
130
                if (isset($this->extensions[$format])) {
131
                    $ext = $this->extensions[$format];
132
                } else {
133
                    $ext = 'txt';
134
                }
135
                $response = $response
136
                    ->withHeader('Content-Disposition', 'attachment; filename=dump.'.$ext);
137
            }
138
        } else {
139
            $response = $response
140
                ->withHeader('Content-type', 'text/plain');
141
        }
142
143
        if (isset($_REQUEST['query'])) {
144
            $_REQUEST['query'] = trim(urldecode($_REQUEST['query']));
145
        }
146
147
        // Set the schema search path
148
        if (isset($_REQUEST['search_path'])) {
149
            $data->setSearchPath(array_map('trim', explode(',', $_REQUEST['search_path'])));
150
        } elseif (isset($_REQUEST['schema'])) {
151
            $data->setSearchPath($_REQUEST['schema']);
152
        }
153
154
        $subject = $this->coalesceArr($_REQUEST, 'subject', 'table')['subject'];
155
156
        $object = $this->coalesceArr($_REQUEST, $subject)[$subject];
157
158
        // Set up the dump transaction
159
        $status = $data->beginDump();
160
        $this->prtrace('subject', $subject);
161
        $this->prtrace('object', $object);
162
        $tabledefprefix = '';
1 ignored issue
show
Unused Code introduced by
The assignment to $tabledefprefix is dead and can be removed.
Loading history...
163
        $tabledefsuffix = '';
1 ignored issue
show
Unused Code introduced by
The assignment to $tabledefsuffix is dead and can be removed.
Loading history...
164
165
        // If the dump is not dataonly then dump the structure prefix
166
        if ('dataonly' != $_REQUEST['what']) {
167
            $tabledefprefix = $data->getTableDefPrefix($object, $clean);
168
            $this->prtrace('tabledefprefix', $tabledefprefix);
169
            echo $tabledefprefix;
170
        }
171
172
        // If the dump is not structureonly then dump the actual data
173
        if ('structureonly' != $_REQUEST['what']) {
174
            // Get database encoding
175
            //$dbEncoding = $data->getDatabaseEncoding();
176
177
            // Set fetch mode to NUM so that duplicate field names are properly returned
178
            $data->conn->setFetchMode(\ADODB_FETCH_NUM);
179
180
            // Execute the query, if set, otherwise grab all rows from the table
181
            if ($object) {
182
                $rs = $data->dumpRelation($object, $oids);
183
            } else {
184
                $rs = $data->conn->Execute($_REQUEST['query']);
185
                $this->prtrace('$_REQUEST[query]', $_REQUEST['query']);
186
            }
187
188
            if ('copy' == $format) {
189
                $this->_mimicCopy($data, $object, $oids, $rs);
190
            } elseif ('html' == $format) {
191
                $response = $response
192
                    ->withHeader('Content-type', 'text/html');
193
                $this->_mimicHtml($data, $object, $oids, $rs);
194
            } elseif ('xml' == $format) {
195
                $response = $response
196
                    ->withHeader('Content-type', 'application/xml');
197
                $this->_mimicXml($data, $object, $oids, $rs);
198
            } elseif ('sql' == $format) {
199
                $this->_mimicSQL($data, $object, $oids, $rs);
200
            } else {
201
                $this->_csvOrTab($data, $object, $oids, $rs, $format);
202
            }
203
        }
204
        if ('dataonly' != $_REQUEST['what']) {
205
            $data->conn->setFetchMode(\ADODB_FETCH_ASSOC);
206
            $tabledefsuffix = $data->getTableDefSuffix($object);
207
            $this->prtrace('tabledefsuffix', $tabledefsuffix);
208
            echo $tabledefsuffix;
209
        }
210
211
        // Finish the dump transaction
212
        $status = $data->endDump();
213
214
        return $response;
215
    }
216
217
    public function doDefault($msg = '')
218
    {
219
        if (!isset($_REQUEST['query']) || empty($_REQUEST['query'])) {
220
            $_REQUEST['query'] = $_SESSION['sqlquery'];
221
        }
222
223
        $this->printHeader();
224
        $this->printBody();
225
        $this->printTrail(isset($_REQUEST['subject']) ? $_REQUEST['subject'] : 'database');
226
        $this->printTitle($this->lang['strexport']);
227
        if (isset($msg)) {
228
            $this->printMsg($msg);
229
        }
230
231
        echo '<form action="'.\SUBFOLDER."/src/views/dataexport\" method=\"post\">\n";
232
        echo "<table>\n";
233
        echo "<tr><th class=\"data\">{$this->lang['strformat']}:</th><td><select name=\"d_format\">\n";
234
        // COPY and SQL require a table
235
        if (isset($_REQUEST['table'])) {
236
            echo "<option value=\"copy\">COPY</option>\n";
237
            echo "<option value=\"sql\">SQL</option>\n";
238
        }
239
        echo "<option value=\"csv\">CSV</option>\n";
240
        echo "<option value=\"tab\">{$this->lang['strtabbed']}</option>\n";
241
        echo "<option value=\"html\">XHTML</option>\n";
242
        echo "<option value=\"xml\">XML</option>\n";
243
        echo '</select></td></tr>';
244
        echo "</table>\n";
245
246
        echo "<h3>{$this->lang['stroptions']}</h3>\n";
247
        echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$this->lang['strshow']}</label>\n";
248
        echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$this->lang['strdownload']}</label></p>\n";
249
250
        echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n";
251
        echo "<input type=\"hidden\" name=\"what\" value=\"dataonly\" />\n";
252
        if (isset($_REQUEST['table'])) {
253
            echo '<input type="hidden" name="subject" value="table" />'."\n";
254
            echo '<input type="hidden" name="table" value="', htmlspecialchars($_REQUEST['table']), "\" />\n";
255
        } else {
256
            echo '<input type="hidden" name="subject" value="table" />'."\n";
257
        }
258
        $this->prtrace('$_REQUEST[query]', $_REQUEST['query'], htmlspecialchars(urlencode($_REQUEST['query'])));
259
        $this->prtrace('$_SESSION[sqlquery]', $_SESSION['sqlquery'], htmlspecialchars(urlencode($_SESSION['sqlquery'])));
260
        echo '<input type="hidden" name="query" value="', htmlspecialchars(urlencode($_REQUEST['query'])), "\" />\n";
261
        if (isset($_REQUEST['search_path'])) {
262
            echo '<input type="hidden" name="search_path" value="', htmlspecialchars($_REQUEST['search_path']), "\" />\n";
263
        }
264
        echo $this->misc->form;
265
        echo "<input type=\"submit\" value=\"{$this->lang['strexport']}\" /></p>\n";
266
        echo "</form>\n";
267
268
        $this->printFooter();
269
    }
270
271
    private function _mimicCopy($data, $object, $oids, $rs)
272
    {
273
        $data->fieldClean($object);
274
        echo "COPY \"{$_REQUEST['table']}\"";
275
        if ($oids) {
276
            echo ' WITH OIDS';
277
        }
278
279
        echo " FROM stdin;\n";
280
        while (!$rs->EOF) {
281
            $first = true;
282
            //while (list($k, $v) = each($rs->fields)) {
283
            foreach ($rs->fields as $k => $v) {
284
                // Escape value
285
                $v = $data->escapeBytea($v);
286
287
                // We add an extra escaping slash onto octal encoded characters
288
                $v = preg_replace('/\\\\([0-7]{3})/', '\\\\\1', $v);
289
                if ($first) {
290
                    echo (is_null($v)) ? '\\N' : $v;
291
                    $first = false;
292
                } else {
293
                    echo "\t", (is_null($v)) ? '\\N' : $v;
294
                }
295
            }
296
            echo "\n";
297
            $rs->moveNext();
298
        }
299
        echo "\\.\n";
300
    }
301
302
    private function _mimicHtml($data, $object, $oids, $rs)
1 ignored issue
show
Unused Code introduced by
The parameter $object 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

302
    private function _mimicHtml($data, /** @scrutinizer ignore-unused */ $object, $oids, $rs)

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...
303
    {
304
        echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n";
305
        echo "<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n";
306
        echo "<head>\r\n";
307
        echo "\t<title></title>\r\n";
308
        echo "\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n";
309
        echo "</head>\r\n";
310
        echo "<body>\r\n";
311
        echo "<table class=\"phppgadmin\">\r\n";
312
        echo "\t<tr>\r\n";
313
        if (!$rs->EOF) {
314
            // Output header row
315
            $j = 0;
316
            foreach ($rs->fields as $k => $v) {
317
                $finfo = $rs->fetchField($j++);
318
                if ($finfo->name == $data->id && !$oids) {
319
                    continue;
320
                }
321
322
                echo "\t\t<th>", $this->misc->printVal($finfo->name, 'verbatim'), "</th>\r\n";
323
            }
324
        }
325
        echo "\t</tr>\r\n";
326
        while (!$rs->EOF) {
327
            echo "\t<tr>\r\n";
328
            $j = 0;
329
            foreach ($rs->fields as $k => $v) {
330
                $finfo = $rs->fetchField($j++);
331
                if ($finfo->name == $data->id && !$oids) {
332
                    continue;
333
                }
334
335
                echo "\t\t<td>", $this->misc->printVal($v, 'verbatim', $finfo->type), "</td>\r\n";
336
            }
337
            echo "\t</tr>\r\n";
338
            $rs->moveNext();
339
        }
340
        echo "</table>\r\n";
341
        echo "</body>\r\n";
342
        echo "</html>\r\n";
343
    }
344
345
    private function _mimicXml($data, $object, $oids, $rs)
3 ignored issues
show
Unused Code introduced by
The parameter $data 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

345
    private function _mimicXml(/** @scrutinizer ignore-unused */ $data, $object, $oids, $rs)

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...
Unused Code introduced by
The parameter $object 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

345
    private function _mimicXml($data, /** @scrutinizer ignore-unused */ $object, $oids, $rs)

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...
Unused Code introduced by
The parameter $oids 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

345
    private function _mimicXml($data, $object, /** @scrutinizer ignore-unused */ $oids, $rs)

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...
346
    {
347
        echo "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
348
        echo "<data>\n";
349
        if (!$rs->EOF) {
350
            // Output header row
351
            $j = 0;
352
            echo "\t<header>\n";
353
            foreach ($rs->fields as $k => $v) {
354
                $finfo = $rs->fetchField($j++);
355
                $name  = htmlspecialchars($finfo->name);
356
                $type  = htmlspecialchars($finfo->type);
357
                echo "\t\t<column name=\"{$name}\" type=\"{$type}\" />\n";
358
            }
359
            echo "\t</header>\n";
360
        }
361
        echo "\t<records>\n";
362
        while (!$rs->EOF) {
363
            $j = 0;
364
            echo "\t\t<row>\n";
365
            foreach ($rs->fields as $k => $v) {
366
                $finfo = $rs->fetchField($j++);
367
                $name  = htmlspecialchars($finfo->name);
368
                if (!is_null($v)) {
369
                    $v = htmlspecialchars($v);
370
                }
371
372
                echo "\t\t\t<column name=\"{$name}\"", (is_null($v) ? ' null="null"' : ''), ">{$v}</column>\n";
373
            }
374
            echo "\t\t</row>\n";
375
            $rs->moveNext();
376
        }
377
        echo "\t</records>\n";
378
        echo "</data>\n";
379
    }
380
381
    private function _mimicSQL($data, $object, $oids, $rs)
1 ignored issue
show
Unused Code introduced by
The parameter $oids 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

381
    private function _mimicSQL($data, $object, /** @scrutinizer ignore-unused */ $oids, $rs)

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...
382
    {
383
        $data->fieldClean($object);
384
        while (!$rs->EOF) {
385
            echo "INSERT INTO \"{$object}\" (";
386
            $first = true;
387
            $j     = 0;
388
            foreach ($rs->fields as $k => $v) {
389
                $finfo = $rs->fetchField($j++);
390
                $k     = $finfo->name;
391
                // SQL (INSERT) format cannot handle oids
392
                //                        if ($k == $data->id) continue;
393
                // Output field
394
                $data->fieldClean($k);
395
                if ($first) {
396
                    echo "\"{$k}\"";
397
                } else {
398
                    echo ", \"{$k}\"";
399
                }
400
401
                if (!is_null($v)) {
402
                    // Output value
403
                    // addCSlashes converts all weird ASCII characters to octal representation,
404
                    // EXCEPT the 'special' ones like \r \n \t, etc.
405
                    $v = addcslashes($v, "\0..\37\177..\377");
406
                    // We add an extra escaping slash onto octal encoded characters
407
                    $v = preg_replace('/\\\\([0-7]{3})/', '\\\1', $v);
408
                    // Finally, escape all apostrophes
409
                    $v = str_replace("'", "''", $v);
410
                }
411
                if ($first) {
412
                    $values = (is_null($v) ? 'NULL' : "'{$v}'");
413
                    $first  = false;
414
                } else {
415
                    $values .= ', '.((is_null($v) ? 'NULL' : "'{$v}'"));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $values does not seem to be defined for all execution paths leading up to this point.
Loading history...
416
                }
417
            }
418
            echo ") VALUES ({$values});\n";
419
            $rs->moveNext();
420
        }
421
    }
422
423
    private function _csvOrTab($data, $object, $oids, $rs, $format)
3 ignored issues
show
Unused Code introduced by
The parameter $object 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

423
    private function _csvOrTab($data, /** @scrutinizer ignore-unused */ $object, $oids, $rs, $format)

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...
Unused Code introduced by
The parameter $oids 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

423
    private function _csvOrTab($data, $object, /** @scrutinizer ignore-unused */ $oids, $rs, $format)

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...
Unused Code introduced by
The parameter $data 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

423
    private function _csvOrTab(/** @scrutinizer ignore-unused */ $data, $object, $oids, $rs, $format)

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...
424
    {
425
        switch ($format) {
426
            case 'tab':
427
                $sep = "\t";
428
429
                break;
430
            case 'csv':
431
            default:
432
                $sep = ',';
433
434
                break;
435
        }
436
        if (!$rs->EOF) {
437
            // Output header row
438
            $first = true;
439
            foreach ($rs->fields as $k => $v) {
440
                $finfo = $rs->fetchField($k);
441
                $v     = $finfo->name;
442
                if (!is_null($v)) {
443
                    $v = str_replace('"', '""', $v);
444
                }
445
446
                if ($first) {
447
                    echo "\"{$v}\"";
448
                    $first = false;
449
                } else {
450
                    echo "{$sep}\"{$v}\"";
451
                }
452
            }
453
            echo "\r\n";
454
        }
455
        while (!$rs->EOF) {
456
            $first = true;
457
            foreach ($rs->fields as $k => $v) {
458
                if (!is_null($v)) {
459
                    $v = str_replace('"', '""', $v);
460
                }
461
462
                if ($first) {
463
                    echo (is_null($v)) ? '"\\N"' : "\"{$v}\"";
464
                    $first = false;
465
                } else {
466
                    echo is_null($v) ? "{$sep}\"\\N\"" : "{$sep}\"{$v}\"";
467
                }
468
            }
469
            echo "\r\n";
470
            $rs->moveNext();
471
        }
472
    }
473
}
474