Visitar URL original
Export plugins refactoring (#18071) · phpmyadmin/phpmyadmin@9187dc8 · GitHub
Skip to content

Commit 9187dc8

Browse files
Export plugins refactoring (#18071)
This is a simplification of the code to remove confusing ($row[$j] == '0' || $row[$j] != ''). To make the code simpler, I added a @var annotation and replace for with foreach. I realize this adds Psalm warnings, and they are valid warnings. But they are because of dead code related to $GLOBALS['what']. This just looks like another nonsense of its own that needs a little more work to be removed so I kept it out of this PR. For the time being, let's keep them in Psalm baseline. * Simplify ExportCsv * Simplify ExportHtmlword * Simplify ExportTexytext * Fix broken tests #18071 --------- Signed-off-by: Kamil Tekiela <tekiela246@gmail.com>
1 parent 2b35303 commit 9187dc8

6 files changed

Lines changed: 67 additions & 53 deletions

File tree

‎libraries/classes/Plugins/Export/ExportCsv.php‎

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use PhpMyAdmin\DatabaseInterface;
1111
use PhpMyAdmin\Dbal\Connection;
12+
use PhpMyAdmin\Dbal\ResultInterface;
1213
use PhpMyAdmin\Plugins\ExportPlugin;
1314
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup;
1415
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup;
@@ -18,11 +19,10 @@
1819
use PhpMyAdmin\Properties\Plugins\ExportPluginProperties;
1920

2021
use function __;
22+
use function implode;
2123
use function mb_strtolower;
22-
use function mb_substr;
2324
use function preg_replace;
2425
use function str_replace;
25-
use function trim;
2626

2727
use const PHP_EOL;
2828

@@ -214,115 +214,112 @@ public function exportData(
214214
): bool {
215215
$GLOBALS['what'] = $GLOBALS['what'] ?? null;
216216
$GLOBALS['csv_terminated'] = $GLOBALS['csv_terminated'] ?? null;
217-
$GLOBALS['csv_separator'] = $GLOBALS['csv_separator'] ?? null;
217+
$GLOBALS['csv_separator'] = $GLOBALS['csv_separator'] ?? '';
218218
$GLOBALS['csv_enclosed'] = $GLOBALS['csv_enclosed'] ?? null;
219219
$GLOBALS['csv_escaped'] = $GLOBALS['csv_escaped'] ?? null;
220220

221221
$db_alias = $db;
222222
$table_alias = $table;
223223
$this->initAlias($aliases, $db_alias, $table_alias);
224224

225-
// Gets the data from the database
225+
/**
226+
* Gets the data from the database
227+
*
228+
* @var ResultInterface $result
229+
* @psalm-ignore-var
230+
*/
226231
$result = $GLOBALS['dbi']->query(
227232
$sqlQuery,
228233
Connection::TYPE_USER,
229234
DatabaseInterface::QUERY_UNBUFFERED
230235
);
231-
$fields_cnt = $result->numFields();
232236

233237
// If required, get fields name at the first line
234238
if (isset($GLOBALS['csv_columns']) && $GLOBALS['csv_columns']) {
235-
$schema_insert = '';
239+
$insertFields = [];
236240
foreach ($result->getFieldNames() as $col_as) {
237241
if (! empty($aliases[$db]['tables'][$table]['columns'][$col_as])) {
238242
$col_as = $aliases[$db]['tables'][$table]['columns'][$col_as];
239243
}
240244

241245
if ($GLOBALS['csv_enclosed'] == '') {
242-
$schema_insert .= $col_as;
246+
$insertFields[] = $col_as;
243247
} else {
244-
$schema_insert .= $GLOBALS['csv_enclosed']
248+
$insertFields[] = $GLOBALS['csv_enclosed']
245249
. str_replace(
246250
$GLOBALS['csv_enclosed'],
247251
$GLOBALS['csv_escaped'] . $GLOBALS['csv_enclosed'],
248252
$col_as
249253
)
250254
. $GLOBALS['csv_enclosed'];
251255
}
252-
253-
$schema_insert .= $GLOBALS['csv_separator'];
254256
}
255257

256-
$schema_insert = trim(mb_substr($schema_insert, 0, -1));
258+
$schema_insert = implode($GLOBALS['csv_separator'], $insertFields);
257259
if (! $this->export->outputHandler($schema_insert . $GLOBALS['csv_terminated'])) {
258260
return false;
259261
}
260262
}
261263

262264
// Format the data
263265
while ($row = $result->fetchRow()) {
264-
$schema_insert = '';
265-
for ($j = 0; $j < $fields_cnt; $j++) {
266-
if (! isset($row[$j])) {
267-
$schema_insert .= $GLOBALS[$GLOBALS['what'] . '_null'];
268-
} elseif ($row[$j] == '0' || $row[$j] != '') {
266+
$insertValues = [];
267+
foreach ($row as $field) {
268+
if ($field === null) {
269+
$insertValues[] = $GLOBALS[$GLOBALS['what'] . '_null'];
270+
} elseif ($field !== '') {
269271
// always enclose fields
270272
if ($GLOBALS['what'] === 'excel') {
271-
$row[$j] = preg_replace("/\015(\012)?/", "\012", $row[$j]);
273+
$field = preg_replace("/\015(\012)?/", "\012", $field);
272274
}
273275

274276
// remove CRLF characters within field
275277
if (
276278
isset($GLOBALS[$GLOBALS['what'] . '_removeCRLF']) && $GLOBALS[$GLOBALS['what'] . '_removeCRLF']
277279
) {
278-
$row[$j] = str_replace(
280+
$field = str_replace(
279281
[
280282
"\r",
281283
"\n",
282284
],
283285
'',
284-
$row[$j]
286+
$field
285287
);
286288
}
287289

288290
if ($GLOBALS['csv_enclosed'] == '') {
289-
$schema_insert .= $row[$j];
291+
$insertValues[] = $field;
290292
} else {
291293
// also double the escape string if found in the data
292294
if ($GLOBALS['csv_escaped'] != $GLOBALS['csv_enclosed']) {
293-
$schema_insert .= $GLOBALS['csv_enclosed']
295+
$insertValues[] = $GLOBALS['csv_enclosed']
294296
. str_replace(
295297
$GLOBALS['csv_enclosed'],
296298
$GLOBALS['csv_escaped'] . $GLOBALS['csv_enclosed'],
297299
str_replace(
298300
$GLOBALS['csv_escaped'],
299301
$GLOBALS['csv_escaped'] . $GLOBALS['csv_escaped'],
300-
$row[$j]
302+
$field
301303
)
302304
)
303305
. $GLOBALS['csv_enclosed'];
304306
} else {
305307
// avoid a problem when escape string equals enclose
306-
$schema_insert .= $GLOBALS['csv_enclosed']
308+
$insertValues[] = $GLOBALS['csv_enclosed']
307309
. str_replace(
308310
$GLOBALS['csv_enclosed'],
309311
$GLOBALS['csv_escaped'] . $GLOBALS['csv_enclosed'],
310-
$row[$j]
312+
$field
311313
)
312314
. $GLOBALS['csv_enclosed'];
313315
}
314316
}
315317
} else {
316-
$schema_insert .= '';
318+
$insertValues[] = '';
317319
}
318-
319-
if ($j >= $fields_cnt - 1) {
320-
continue;
321-
}
322-
323-
$schema_insert .= $GLOBALS['csv_separator'];
324320
}
325321

322+
$schema_insert = implode($GLOBALS['csv_separator'], $insertValues);
326323
if (! $this->export->outputHandler($schema_insert . $GLOBALS['csv_terminated'])) {
327324
return false;
328325
}

‎libraries/classes/Plugins/Export/ExportHtmlword.php‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PhpMyAdmin\Database\Triggers;
1111
use PhpMyAdmin\DatabaseInterface;
1212
use PhpMyAdmin\Dbal\Connection;
13+
use PhpMyAdmin\Dbal\ResultInterface;
1314
use PhpMyAdmin\Plugins\ExportPlugin;
1415
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup;
1516
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup;
@@ -201,13 +202,17 @@ public function exportData(
201202
return false;
202203
}
203204

204-
// Gets the data from the database
205+
/**
206+
* Gets the data from the database
207+
*
208+
* @var ResultInterface $result
209+
* @psalm-ignore-var
210+
*/
205211
$result = $GLOBALS['dbi']->query(
206212
$sqlQuery,
207213
Connection::TYPE_USER,
208214
DatabaseInterface::QUERY_UNBUFFERED
209215
);
210-
$fields_cnt = $result->numFields();
211216

212217
// If required, get fields name at the first line
213218
if (isset($GLOBALS['htmlword_columns'])) {
@@ -231,13 +236,11 @@ public function exportData(
231236
// Format the data
232237
while ($row = $result->fetchRow()) {
233238
$schema_insert = '<tr class="print-category">';
234-
for ($j = 0; $j < $fields_cnt; $j++) {
235-
if (! isset($row[$j])) {
239+
foreach ($row as $field) {
240+
if ($field === null) {
236241
$value = $GLOBALS[$GLOBALS['what'] . '_null'];
237-
} elseif ($row[$j] == '0' || $row[$j] != '') {
238-
$value = $row[$j];
239242
} else {
240-
$value = '';
243+
$value = $field;
241244
}
242245

243246
$schema_insert .= '<td class="print">'

‎libraries/classes/Plugins/Export/ExportTexytext.php‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PhpMyAdmin\Database\Triggers;
1111
use PhpMyAdmin\DatabaseInterface;
1212
use PhpMyAdmin\Dbal\Connection;
13+
use PhpMyAdmin\Dbal\ResultInterface;
1314
use PhpMyAdmin\Plugins\ExportPlugin;
1415
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup;
1516
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup;
@@ -181,13 +182,17 @@ public function exportData(
181182
return false;
182183
}
183184

184-
// Gets the data from the database
185+
/**
186+
* Gets the data from the database
187+
*
188+
* @var ResultInterface $result
189+
* @psalm-ignore-var
190+
*/
185191
$result = $GLOBALS['dbi']->query(
186192
$sqlQuery,
187193
Connection::TYPE_USER,
188194
DatabaseInterface::QUERY_UNBUFFERED
189195
);
190-
$fields_cnt = $result->numFields();
191196

192197
// If required, get fields name at the first line
193198
if (isset($GLOBALS[$GLOBALS['what'] . '_columns'])) {
@@ -209,11 +214,11 @@ public function exportData(
209214
// Format the data
210215
while ($row = $result->fetchRow()) {
211216
$text_output = '';
212-
for ($j = 0; $j < $fields_cnt; $j++) {
213-
if (! isset($row[$j])) {
217+
foreach ($row as $field) {
218+
if ($field === null) {
214219
$value = $GLOBALS[$GLOBALS['what'] . '_null'];
215-
} elseif ($row[$j] == '0' || $row[$j] != '') {
216-
$value = $row[$j];
220+
} elseif ($field !== '') {
221+
$value = $field;
217222
} else {
218223
$value = ' ';
219224
}

‎phpstan-baseline.neon‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6260,6 +6260,11 @@ parameters:
62606260
count: 1
62616261
path: libraries/classes/Plugins/Export/ExportCsv.php
62626262

6263+
-
6264+
message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|null given\\.$#"
6265+
count: 3
6266+
path: libraries/classes/Plugins/Export/ExportCsv.php
6267+
62636268
-
62646269
message: "#^Method PhpMyAdmin\\\\Plugins\\\\Export\\\\ExportHtmlword\\:\\:exportData\\(\\) has parameter \\$aliases with no value type specified in iterable type array\\.$#"
62656270
count: 1

‎psalm-baseline.xml‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10899,6 +10899,9 @@
1089910899
</RedundantCondition>
1090010900
</file>
1090110901
<file src="libraries/classes/Plugins/Export/ExportCsv.php">
10902+
<InvalidArgument>
10903+
<code>$insertValues</code>
10904+
</InvalidArgument>
1090210905
<InvalidArrayOffset>
1090310906
<code>$GLOBALS['excel_columns']</code>
1090410907
<code>$GLOBALS['what']</code>
@@ -10907,17 +10910,20 @@
1090710910
<MixedArgument>
1090810911
<code>$col_as</code>
1090910912
</MixedArgument>
10913+
<MixedArgumentTypeCoercion>
10914+
<code>$insertFields</code>
10915+
</MixedArgumentTypeCoercion>
1091010916
<MixedAssignment>
1091110917
<code>$GLOBALS['what']</code>
1091210918
<code>$GLOBALS['what']</code>
1091310919
<code>$col_as</code>
10920+
<code>$insertFields[]</code>
10921+
<code>$insertValues[]</code>
1091410922
</MixedAssignment>
1091510923
<MixedOperand>
10916-
<code>$GLOBALS[$GLOBALS['what'] . '_null']</code>
1091710924
<code>$GLOBALS['what']</code>
1091810925
<code>$GLOBALS['what']</code>
1091910926
<code>$GLOBALS['what']</code>
10920-
<code>$col_as</code>
1092110927
</MixedOperand>
1092210928
<PossiblyNullArgument>
1092310929
<code>$GLOBALS['csv_enclosed']</code>
@@ -10941,8 +10947,6 @@
1094110947
<code>$GLOBALS['csv_escaped']</code>
1094210948
<code>$GLOBALS['csv_escaped']</code>
1094310949
<code>$GLOBALS['csv_escaped']</code>
10944-
<code>$GLOBALS['csv_separator']</code>
10945-
<code>$GLOBALS['csv_separator']</code>
1094610950
<code>$GLOBALS['csv_terminated']</code>
1094710951
<code>$GLOBALS['csv_terminated']</code>
1094810952
</PossiblyNullOperand>

‎test/classes/Plugins/Export/ExportCsvTest.php‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ public function testExportData(): void
404404
$result = ob_get_clean();
405405

406406
$this->assertEquals(
407-
'idnamedatetimefiel;1abcd2011-01-20 02:00:02;2foo2010-01-20 02:00:02;3Abcd2012-01-20 02:00:02;',
407+
'idnamedatetimefield;1abcd2011-01-20 02:00:02;2foo2010-01-20 02:00:02;3Abcd2012-01-20 02:00:02;',
408408
$result
409409
);
410410

@@ -422,7 +422,7 @@ public function testExportData(): void
422422
$result = ob_get_clean();
423423

424424
$this->assertEquals(
425-
'"id""name""datetimefield;"1""abcd""2011-01-20 02:00:02";'
425+
'"id""name""datetimefield";"1""abcd""2011-01-20 02:00:02";'
426426
. '"2""foo""2010-01-20 02:00:02";"3""Abcd""2012-01-20 02:00:02";',
427427
$result
428428
);
@@ -443,7 +443,7 @@ public function testExportData(): void
443443
$result = ob_get_clean();
444444

445445
$this->assertEquals(
446-
'"id""name""datetimefield;"1""abcd""2011-01-20 02:00:02";'
446+
'"id""name""datetimefield";"1""abcd""2011-01-20 02:00:02";'
447447
. '"2""foo""2010-01-20 02:00:02";"3""Abcd""2012-01-20 02:00:02";',
448448
$result
449449
);
@@ -463,7 +463,7 @@ public function testExportData(): void
463463
$result = ob_get_clean();
464464

465465
$this->assertEquals(
466-
'"id""name""datetimefield;"1""abcd""2011-01-20 02:00:02";'
466+
'"id""name""datetimefield";"1""abcd""2011-01-20 02:00:02";'
467467
. '"2""foo""2010-01-20 02:00:02";"3""Abcd""2012-01-20 02:00:02";',
468468
$result
469469
);
@@ -483,7 +483,7 @@ public function testExportData(): void
483483
$result = ob_get_clean();
484484

485485
$this->assertEquals(
486-
'"id""name""datetimefield;"1""abcd""2011-01-20 02:00:02";'
486+
'"id""name""datetimefield";"1""abcd""2011-01-20 02:00:02";'
487487
. '"2""foo""2010-01-20 02:00:02";"3""Abcd""2012-01-20 02:00:02";',
488488
$result
489489
);

0 commit comments

Comments
 (0)