add setImportOptions()
Signed-off-by: Kamil Tekiela <tekiela246@gmail.com>
This commit is contained in:
parent
015d66caef
commit
80dd9e7c88
@ -11295,11 +11295,6 @@ parameters:
|
||||
count: 1
|
||||
path: src/Plugins/ExportPlugin.php
|
||||
|
||||
-
|
||||
message: "#^Cannot access offset 0 on mixed\\.$#"
|
||||
count: 10
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Cannot call method getMessage\\(\\) on mixed\\.$#"
|
||||
count: 1
|
||||
@ -11307,7 +11302,7 @@ parameters:
|
||||
|
||||
-
|
||||
message: "#^Cannot cast mixed to string\\.$#"
|
||||
count: 3
|
||||
count: 8
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
@ -11335,46 +11330,11 @@ parameters:
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$csvTerminated of method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportCsv\\:\\:buildErrorsForParams\\(\\) expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$serverMessage of static method PhpMyAdmin\\\\Html\\\\Generator\\:\\:mysqlDie\\(\\) expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$str of function strtr expects string, mixed given\\.$#"
|
||||
count: 4
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$string of function mb_strlen expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$csvEnclosed of method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportCsv\\:\\:buildErrorsForParams\\(\\) expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$needle of function str_contains expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$csvColumns of method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportCsv\\:\\:getSqlTemplateAndRequiredFields\\(\\) expects string\\|null, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$csvEscaped of method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportCsv\\:\\:buildErrorsForParams\\(\\) expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportCsv.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$rows of class PhpMyAdmin\\\\Import\\\\ImportTable constructor expects array\\<int, array\\<int, mixed\\>\\>, array\\<int\\<0, max\\>, array\\> given\\.$#"
|
||||
count: 1
|
||||
@ -11395,16 +11355,6 @@ parameters:
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportLdi.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:quoteString\\(\\) expects string, mixed given\\.$#"
|
||||
count: 2
|
||||
path: src/Plugins/Import/ImportLdi.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#2 \\$subject of function preg_split expects string, mixed given\\.$#"
|
||||
count: 1
|
||||
path: src/Plugins/Import/ImportLdi.php
|
||||
|
||||
-
|
||||
message: "#^Method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportMediawiki\\:\\:doImport\\(\\) should return array\\<string\\> but returns mixed\\.$#"
|
||||
count: 1
|
||||
|
||||
@ -8587,11 +8587,9 @@
|
||||
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
|
||||
</DeprecatedMethod>
|
||||
<InvalidArgument>
|
||||
<code><![CDATA[$GLOBALS['csv_columns']]]></code>
|
||||
<code><![CDATA[$colNames]]></code>
|
||||
</InvalidArgument>
|
||||
<InvalidArrayOffset>
|
||||
<code><![CDATA[$GLOBALS['csv_new_line']]]></code>
|
||||
<code><![CDATA[$GLOBALS['errorUrl']]]></code>
|
||||
<code><![CDATA[$values[count($values) - 1]]]></code>
|
||||
<code><![CDATA[$values[count($values) - 1]]]></code>
|
||||
@ -8602,11 +8600,7 @@
|
||||
<InvalidReturnType>
|
||||
<code><![CDATA[string]]></code>
|
||||
</InvalidReturnType>
|
||||
<MixedArgument>
|
||||
<code><![CDATA[$GLOBALS['csv_new_line']]]></code>
|
||||
</MixedArgument>
|
||||
<MixedAssignment>
|
||||
<code><![CDATA[$GLOBALS['csv_new_line']]]></code>
|
||||
<code><![CDATA[$GLOBALS['errorUrl']]]></code>
|
||||
</MixedAssignment>
|
||||
<PossiblyInvalidCast>
|
||||
@ -8617,12 +8611,6 @@
|
||||
<code><![CDATA[$maxLines]]></code>
|
||||
<code><![CDATA[1]]></code>
|
||||
</PossiblyInvalidOperand>
|
||||
<PossiblyNullArgument>
|
||||
<code><![CDATA[$GLOBALS['csv_enclosed']]]></code>
|
||||
<code><![CDATA[$GLOBALS['csv_escaped']]]></code>
|
||||
<code><![CDATA[$GLOBALS['csv_new_line']]]></code>
|
||||
<code><![CDATA[$GLOBALS['csv_terminated']]]></code>
|
||||
</PossiblyNullArgument>
|
||||
<PossiblyNullOperand>
|
||||
<code><![CDATA[$ch]]></code>
|
||||
</PossiblyNullOperand>
|
||||
@ -8645,41 +8633,9 @@
|
||||
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
|
||||
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
|
||||
</DeprecatedMethod>
|
||||
<InvalidArrayOffset>
|
||||
<code><![CDATA[$GLOBALS['ldi_columns']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_enclosed']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_escaped']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_ignore']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_local_option']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_new_line']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_replace']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_terminated']]]></code>
|
||||
</InvalidArrayOffset>
|
||||
<MixedArgument>
|
||||
<code><![CDATA[$GLOBALS['ldi_columns']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_enclosed']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_escaped']]]></code>
|
||||
<code><![CDATA[ImportSettings::$importFile]]></code>
|
||||
</MixedArgument>
|
||||
<MixedAssignment>
|
||||
<code><![CDATA[$GLOBALS['ldi_columns']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_enclosed']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_escaped']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_ignore']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_local_option']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_new_line']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_replace']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_terminated']]]></code>
|
||||
</MixedAssignment>
|
||||
<MixedOperand>
|
||||
<code><![CDATA[$GLOBALS['ldi_new_line']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_terminated']]]></code>
|
||||
</MixedOperand>
|
||||
<PossiblyNullArgument>
|
||||
<code><![CDATA[$GLOBALS['ldi_columns']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_enclosed']]]></code>
|
||||
<code><![CDATA[$GLOBALS['ldi_escaped']]]></code>
|
||||
</PossiblyNullArgument>
|
||||
<PossiblyUnusedReturnValue>
|
||||
<code><![CDATA[string[]]]></code>
|
||||
</PossiblyUnusedReturnValue>
|
||||
|
||||
@ -195,9 +195,6 @@ final class ImportController extends AbstractController
|
||||
return;
|
||||
}
|
||||
|
||||
$postPatterns = ['/^' . $format . '_/'];
|
||||
Core::setPostAsGlobal($postPatterns);
|
||||
|
||||
if (Current::$table !== '' && Current::$database !== '') {
|
||||
$GLOBALS['urlParams'] = ['db' => Current::$database, 'table' => Current::$table];
|
||||
} elseif (Current::$database !== '') {
|
||||
@ -485,6 +482,8 @@ final class ImportController extends AbstractController
|
||||
if (! $GLOBALS['error']) {
|
||||
$importPlugin = new ($importFormat->getClassName());
|
||||
|
||||
$importPlugin->setImportOptions($request);
|
||||
|
||||
// Do the real import
|
||||
$defaultFkCheck = ForeignKey::handleDisableCheckInit();
|
||||
try {
|
||||
|
||||
@ -13,6 +13,7 @@ use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\DatabaseInterface;
|
||||
use PhpMyAdmin\File;
|
||||
use PhpMyAdmin\Html\Generator;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Import\ImportSettings;
|
||||
use PhpMyAdmin\Import\ImportTable;
|
||||
use PhpMyAdmin\Message;
|
||||
@ -53,6 +54,12 @@ class ImportCsv extends AbstractImportCsv
|
||||
*/
|
||||
private bool $analyze = false;
|
||||
|
||||
private string $terminated = '';
|
||||
private string $enclosed = '';
|
||||
private string $escaped = '';
|
||||
private string $newLine = '';
|
||||
private string $columns = '';
|
||||
|
||||
/** @psalm-return non-empty-lowercase-string */
|
||||
public function getName(): string
|
||||
{
|
||||
@ -154,6 +161,15 @@ class ImportCsv extends AbstractImportCsv
|
||||
return $importPluginProperties;
|
||||
}
|
||||
|
||||
public function setImportOptions(ServerRequest $request): void
|
||||
{
|
||||
$this->terminated = (string) $request->getParsedBodyParam('csv_terminated');
|
||||
$this->enclosed = (string) $request->getParsedBodyParam('csv_enclosed');
|
||||
$this->escaped = (string) $request->getParsedBodyParam('csv_escaped');
|
||||
$this->newLine = (string) $request->getParsedBodyParam('csv_new_line');
|
||||
$this->columns = (string) $request->getParsedBodyParam('csv_columns');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*
|
||||
@ -165,34 +181,29 @@ class ImportCsv extends AbstractImportCsv
|
||||
{
|
||||
$GLOBALS['error'] ??= null;
|
||||
$GLOBALS['message'] ??= null;
|
||||
$GLOBALS['csv_terminated'] ??= null;
|
||||
$GLOBALS['csv_enclosed'] ??= null;
|
||||
$GLOBALS['csv_escaped'] ??= null;
|
||||
$GLOBALS['csv_new_line'] ??= null;
|
||||
$GLOBALS['csv_columns'] ??= null;
|
||||
$GLOBALS['errorUrl'] ??= null;
|
||||
|
||||
// $csv_replace and $csv_ignore should have been here,
|
||||
// but we use directly from $_POST
|
||||
|
||||
$replacements = ['\\n' => "\n", '\\t' => "\t", '\\r' => "\r"];
|
||||
$GLOBALS['csv_terminated'] = strtr($GLOBALS['csv_terminated'], $replacements);
|
||||
$GLOBALS['csv_enclosed'] = strtr($GLOBALS['csv_enclosed'], $replacements);
|
||||
$GLOBALS['csv_escaped'] = strtr($GLOBALS['csv_escaped'], $replacements);
|
||||
$GLOBALS['csv_new_line'] = strtr($GLOBALS['csv_new_line'], $replacements);
|
||||
$this->terminated = strtr($this->terminated, $replacements);
|
||||
$this->enclosed = strtr($this->enclosed, $replacements);
|
||||
$this->escaped = strtr($this->escaped, $replacements);
|
||||
$this->newLine = strtr($this->newLine, $replacements);
|
||||
|
||||
[$GLOBALS['error'], $GLOBALS['message']] = $this->buildErrorsForParams(
|
||||
$GLOBALS['csv_terminated'],
|
||||
$GLOBALS['csv_enclosed'],
|
||||
$GLOBALS['csv_escaped'],
|
||||
$GLOBALS['csv_new_line'],
|
||||
$this->terminated,
|
||||
$this->enclosed,
|
||||
$this->escaped,
|
||||
$this->newLine,
|
||||
(string) $GLOBALS['errorUrl'],
|
||||
);
|
||||
|
||||
[$sqlTemplate, $fields] = $this->getSqlTemplateAndRequiredFields(
|
||||
Current::$database,
|
||||
Current::$table,
|
||||
$GLOBALS['csv_columns'],
|
||||
$this->columns,
|
||||
);
|
||||
|
||||
$sqlStatements = [];
|
||||
@ -225,7 +236,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
$rows = [];
|
||||
$buffer = '';
|
||||
$maxCols = 0;
|
||||
$csvTerminatedLen = mb_strlen($GLOBALS['csv_terminated']);
|
||||
$csvTerminatedLen = mb_strlen($this->terminated);
|
||||
$dbi = DatabaseInterface::getInstance();
|
||||
while (! (ImportSettings::$finished && $i >= $len) && ! $GLOBALS['error'] && ! ImportSettings::$timeoutPassed) {
|
||||
$data = $this->import->getNextChunk($importHandle);
|
||||
@ -243,21 +254,21 @@ class ImportCsv extends AbstractImportCsv
|
||||
// Force a trailing new line at EOF to prevent parsing problems
|
||||
if (ImportSettings::$finished && $buffer) {
|
||||
$finalch = mb_substr($buffer, -1);
|
||||
if ($GLOBALS['csv_new_line'] === 'auto' && $finalch !== "\r" && $finalch !== "\n") {
|
||||
if ($this->newLine === 'auto' && $finalch !== "\r" && $finalch !== "\n") {
|
||||
$buffer .= "\n";
|
||||
} elseif ($GLOBALS['csv_new_line'] !== 'auto' && $finalch != $GLOBALS['csv_new_line']) {
|
||||
$buffer .= $GLOBALS['csv_new_line'];
|
||||
} elseif ($this->newLine !== 'auto' && $finalch !== $this->newLine) {
|
||||
$buffer .= $this->newLine;
|
||||
}
|
||||
}
|
||||
|
||||
// Do not parse string when we're not at the end
|
||||
// and don't have new line inside
|
||||
if (
|
||||
($GLOBALS['csv_new_line'] === 'auto'
|
||||
($this->newLine === 'auto'
|
||||
&& ! str_contains($buffer, "\r")
|
||||
&& ! str_contains($buffer, "\n"))
|
||||
|| ($GLOBALS['csv_new_line'] !== 'auto'
|
||||
&& ! str_contains($buffer, $GLOBALS['csv_new_line']))
|
||||
|| ($this->newLine !== 'auto'
|
||||
&& ! str_contains($buffer, $this->newLine))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
@ -268,7 +279,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
// Currently parsed char
|
||||
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) {
|
||||
$ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen);
|
||||
$i += $csvTerminatedLen - 1;
|
||||
}
|
||||
@ -290,7 +301,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
// This can happen with auto EOL and \r at the end of buffer
|
||||
if (! $csvFinish) {
|
||||
// Grab empty field
|
||||
if ($ch == $GLOBALS['csv_terminated']) {
|
||||
if ($ch == $this->terminated) {
|
||||
if ($i === $len - 1) {
|
||||
break;
|
||||
}
|
||||
@ -298,7 +309,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
$values[] = '';
|
||||
$i++;
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) {
|
||||
$ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen);
|
||||
$i += $csvTerminatedLen - 1;
|
||||
}
|
||||
@ -308,7 +319,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
|
||||
// Grab one field
|
||||
$fallbacki = $i;
|
||||
if ($ch == $GLOBALS['csv_enclosed']) {
|
||||
if ($ch == $this->enclosed) {
|
||||
if ($i === $len - 1) {
|
||||
break;
|
||||
}
|
||||
@ -316,7 +327,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
$needEnd = true;
|
||||
$i++;
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) {
|
||||
$ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen);
|
||||
$i += $csvTerminatedLen - 1;
|
||||
}
|
||||
@ -328,15 +339,15 @@ class ImportCsv extends AbstractImportCsv
|
||||
$value = '';
|
||||
while (
|
||||
($needEnd
|
||||
&& ($ch != $GLOBALS['csv_enclosed']
|
||||
|| $GLOBALS['csv_enclosed'] == $GLOBALS['csv_escaped']))
|
||||
&& ($ch != $this->enclosed
|
||||
|| $this->enclosed === $this->escaped))
|
||||
|| (! $needEnd
|
||||
&& ! ($ch == $GLOBALS['csv_terminated']
|
||||
|| $ch == $GLOBALS['csv_new_line']
|
||||
|| ($GLOBALS['csv_new_line'] === 'auto'
|
||||
&& ! ($ch === $this->terminated
|
||||
|| $ch === $this->newLine
|
||||
|| ($this->newLine === 'auto'
|
||||
&& ($ch === "\r" || $ch === "\n"))))
|
||||
) {
|
||||
if ($ch == $GLOBALS['csv_escaped']) {
|
||||
if ($ch == $this->escaped) {
|
||||
if ($i === $len - 1) {
|
||||
$fail = true;
|
||||
break;
|
||||
@ -344,16 +355,16 @@ class ImportCsv extends AbstractImportCsv
|
||||
|
||||
$i++;
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) {
|
||||
$ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen);
|
||||
$i += $csvTerminatedLen - 1;
|
||||
}
|
||||
|
||||
if (
|
||||
$GLOBALS['csv_enclosed'] == $GLOBALS['csv_escaped']
|
||||
&& ($ch == $GLOBALS['csv_terminated']
|
||||
|| $ch == $GLOBALS['csv_new_line']
|
||||
|| ($GLOBALS['csv_new_line'] === 'auto'
|
||||
$this->enclosed === $this->escaped
|
||||
&& ($ch == $this->terminated
|
||||
|| $ch == $this->newLine
|
||||
|| ($this->newLine === 'auto'
|
||||
&& ($ch === "\r" || $ch === "\n")))
|
||||
) {
|
||||
break;
|
||||
@ -371,7 +382,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
|
||||
$i++;
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen <= 1 || $ch != $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen <= 1 || $ch != $this->terminated[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -387,7 +398,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
if ($fail) {
|
||||
$i = $fallbacki;
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) {
|
||||
$i += $csvTerminatedLen - 1;
|
||||
}
|
||||
|
||||
@ -395,13 +406,13 @@ class ImportCsv extends AbstractImportCsv
|
||||
}
|
||||
|
||||
// Need to strip trailing enclosing char?
|
||||
if ($needEnd && $ch == $GLOBALS['csv_enclosed']) {
|
||||
if ($needEnd && $ch == $this->enclosed) {
|
||||
if (ImportSettings::$finished && $i === $len - 1) {
|
||||
$ch = null;
|
||||
} elseif ($i === $len - 1) {
|
||||
$i = $fallbacki;
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) {
|
||||
$i += $csvTerminatedLen - 1;
|
||||
}
|
||||
|
||||
@ -409,7 +420,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
} else {
|
||||
$i++;
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) {
|
||||
$ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen);
|
||||
$i += $csvTerminatedLen - 1;
|
||||
}
|
||||
@ -418,19 +429,19 @@ class ImportCsv extends AbstractImportCsv
|
||||
|
||||
// Are we at the end?
|
||||
if (
|
||||
$ch == $GLOBALS['csv_new_line']
|
||||
|| ($GLOBALS['csv_new_line'] === 'auto' && ($ch === "\r" || $ch === "\n"))
|
||||
$ch == $this->newLine
|
||||
|| ($this->newLine === 'auto' && ($ch === "\r" || $ch === "\n"))
|
||||
|| (ImportSettings::$finished && $i === $len - 1)
|
||||
) {
|
||||
$csvFinish = true;
|
||||
}
|
||||
|
||||
// Go to next char
|
||||
if ($ch == $GLOBALS['csv_terminated']) {
|
||||
if ($ch == $this->terminated) {
|
||||
if ($i === $len - 1) {
|
||||
$i = $fallbacki;
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) {
|
||||
$i += $csvTerminatedLen - 1;
|
||||
}
|
||||
|
||||
@ -439,7 +450,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
|
||||
$i++;
|
||||
$ch = mb_substr($buffer, $i, 1);
|
||||
if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) {
|
||||
if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) {
|
||||
$ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen);
|
||||
$i += $csvTerminatedLen - 1;
|
||||
}
|
||||
@ -452,13 +463,13 @@ class ImportCsv extends AbstractImportCsv
|
||||
// End of line
|
||||
if (
|
||||
! $csvFinish
|
||||
&& $ch != $GLOBALS['csv_new_line']
|
||||
&& ($GLOBALS['csv_new_line'] !== 'auto' || ($ch !== "\r" && $ch !== "\n"))
|
||||
&& $ch != $this->newLine
|
||||
&& ($this->newLine !== 'auto' || ($ch !== "\r" && $ch !== "\n"))
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($GLOBALS['csv_new_line'] === 'auto' && $ch === "\r") { // Handle "\r\n"
|
||||
if ($this->newLine === 'auto' && $ch === "\r") { // Handle "\r\n"
|
||||
if ($i >= ($len - 2) && ! ImportSettings::$finished) {
|
||||
break; // We need more data to decide new line
|
||||
}
|
||||
@ -718,7 +729,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
private function getSqlTemplateAndRequiredFields(
|
||||
string|null $db,
|
||||
string|null $table,
|
||||
string|null $csvColumns,
|
||||
string $csvColumns,
|
||||
): array {
|
||||
$GLOBALS['error'] ??= null;
|
||||
$GLOBALS['message'] ??= null;
|
||||
@ -735,7 +746,7 @@ class ImportCsv extends AbstractImportCsv
|
||||
|
||||
$tmpFields = DatabaseInterface::getInstance()->getColumnNames($db, $table);
|
||||
|
||||
if ($csvColumns === null || $csvColumns === '') {
|
||||
if ($csvColumns === '') {
|
||||
$fields = $tmpFields;
|
||||
} else {
|
||||
$sqlTemplate .= ' (';
|
||||
|
||||
@ -8,6 +8,7 @@ use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\DatabaseInterface;
|
||||
use PhpMyAdmin\File;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Import\ImportSettings;
|
||||
use PhpMyAdmin\Message;
|
||||
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup;
|
||||
@ -28,6 +29,15 @@ use const PHP_EOL;
|
||||
*/
|
||||
class ImportLdi extends AbstractImportCsv
|
||||
{
|
||||
private bool $localOption = false;
|
||||
private bool $replace = false;
|
||||
private bool $ignore = false;
|
||||
private string $terminated = '';
|
||||
private string $enclosed = '';
|
||||
private string $escaped = '';
|
||||
private string $newLine = '';
|
||||
private string $columns = '';
|
||||
|
||||
/** @psalm-return non-empty-lowercase-string */
|
||||
public function getName(): string
|
||||
{
|
||||
@ -84,6 +94,18 @@ class ImportLdi extends AbstractImportCsv
|
||||
return $importPluginProperties;
|
||||
}
|
||||
|
||||
public function setImportOptions(ServerRequest $request): void
|
||||
{
|
||||
$this->localOption = $request->getParsedBodyParam('ldi_local_option') !== null;
|
||||
$this->replace = $request->getParsedBodyParam('ldi_replace') !== null;
|
||||
$this->ignore = $request->getParsedBodyParam('ldi_ignore') !== null;
|
||||
$this->terminated = (string) $request->getParsedBodyParam('ldi_terminated');
|
||||
$this->enclosed = (string) $request->getParsedBodyParam('ldi_enclosed');
|
||||
$this->escaped = (string) $request->getParsedBodyParam('ldi_escaped');
|
||||
$this->newLine = (string) $request->getParsedBodyParam('ldi_new_line');
|
||||
$this->columns = (string) $request->getParsedBodyParam('ldi_columns');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*
|
||||
@ -91,15 +113,6 @@ class ImportLdi extends AbstractImportCsv
|
||||
*/
|
||||
public function doImport(File|null $importHandle = null): array
|
||||
{
|
||||
$GLOBALS['ldi_local_option'] ??= null;
|
||||
$GLOBALS['ldi_replace'] ??= null;
|
||||
$GLOBALS['ldi_ignore'] ??= null;
|
||||
$GLOBALS['ldi_terminated'] ??= null;
|
||||
$GLOBALS['ldi_enclosed'] ??= null;
|
||||
$GLOBALS['ldi_escaped'] ??= null;
|
||||
$GLOBALS['ldi_new_line'] ??= null;
|
||||
$GLOBALS['ldi_columns'] ??= null;
|
||||
|
||||
$sqlStatements = [];
|
||||
$compression = '';
|
||||
if ($importHandle !== null) {
|
||||
@ -117,38 +130,38 @@ class ImportLdi extends AbstractImportCsv
|
||||
}
|
||||
|
||||
$sql = 'LOAD DATA';
|
||||
if (isset($GLOBALS['ldi_local_option'])) {
|
||||
if ($this->localOption) {
|
||||
$sql .= ' LOCAL';
|
||||
}
|
||||
|
||||
$dbi = DatabaseInterface::getInstance();
|
||||
$sql .= ' INFILE ' . $dbi->quoteString(ImportSettings::$importFile);
|
||||
if (isset($GLOBALS['ldi_replace'])) {
|
||||
if ($this->replace) {
|
||||
$sql .= ' REPLACE';
|
||||
} elseif (isset($GLOBALS['ldi_ignore'])) {
|
||||
} elseif ($this->ignore) {
|
||||
$sql .= ' IGNORE';
|
||||
}
|
||||
|
||||
$sql .= ' INTO TABLE ' . Util::backquote(Current::$table);
|
||||
|
||||
if ((string) $GLOBALS['ldi_terminated'] !== '') {
|
||||
$sql .= ' FIELDS TERMINATED BY \'' . $GLOBALS['ldi_terminated'] . '\'';
|
||||
if ($this->terminated !== '') {
|
||||
$sql .= ' FIELDS TERMINATED BY \'' . $this->terminated . '\'';
|
||||
}
|
||||
|
||||
if ((string) $GLOBALS['ldi_enclosed'] !== '') {
|
||||
$sql .= ' ENCLOSED BY ' . $dbi->quoteString($GLOBALS['ldi_enclosed']);
|
||||
if ($this->enclosed !== '') {
|
||||
$sql .= ' ENCLOSED BY ' . $dbi->quoteString($this->enclosed);
|
||||
}
|
||||
|
||||
if ((string) $GLOBALS['ldi_escaped'] !== '') {
|
||||
$sql .= ' ESCAPED BY ' . $dbi->quoteString($GLOBALS['ldi_escaped']);
|
||||
if ($this->escaped !== '') {
|
||||
$sql .= ' ESCAPED BY ' . $dbi->quoteString($this->escaped);
|
||||
}
|
||||
|
||||
if ((string) $GLOBALS['ldi_new_line'] !== '') {
|
||||
if ($GLOBALS['ldi_new_line'] === 'auto') {
|
||||
$GLOBALS['ldi_new_line'] = PHP_EOL;
|
||||
if ($this->newLine !== '') {
|
||||
if ($this->newLine === 'auto') {
|
||||
$this->newLine = PHP_EOL;
|
||||
}
|
||||
|
||||
$sql .= ' LINES TERMINATED BY \'' . $GLOBALS['ldi_new_line'] . '\'';
|
||||
$sql .= ' LINES TERMINATED BY \'' . $this->newLine . '\'';
|
||||
}
|
||||
|
||||
if (ImportSettings::$skipQueries > 0) {
|
||||
@ -156,9 +169,9 @@ class ImportLdi extends AbstractImportCsv
|
||||
ImportSettings::$skipQueries = 0;
|
||||
}
|
||||
|
||||
if ((string) $GLOBALS['ldi_columns'] !== '') {
|
||||
if ($this->columns !== '') {
|
||||
$sql .= ' (';
|
||||
$tmp = preg_split('/,( ?)/', $GLOBALS['ldi_columns']);
|
||||
$tmp = preg_split('/,( ?)/', $this->columns);
|
||||
|
||||
if (! is_array($tmp)) {
|
||||
$tmp = [];
|
||||
|
||||
@ -9,6 +9,7 @@ namespace PhpMyAdmin\Plugins\Import;
|
||||
|
||||
use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\File;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Import\ImportSettings;
|
||||
use PhpMyAdmin\Import\ImportTable;
|
||||
use PhpMyAdmin\Message;
|
||||
@ -62,6 +63,10 @@ class ImportMediawiki extends ImportPlugin
|
||||
return $importPluginProperties;
|
||||
}
|
||||
|
||||
public function setImportOptions(ServerRequest $request): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*
|
||||
|
||||
@ -12,6 +12,7 @@ namespace PhpMyAdmin\Plugins\Import;
|
||||
|
||||
use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\File;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Import\ImportSettings;
|
||||
use PhpMyAdmin\Import\ImportTable;
|
||||
use PhpMyAdmin\Message;
|
||||
@ -96,6 +97,10 @@ class ImportOds extends ImportPlugin
|
||||
return $importPluginProperties;
|
||||
}
|
||||
|
||||
public function setImportOptions(ServerRequest $request): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*
|
||||
|
||||
@ -15,6 +15,7 @@ use PhpMyAdmin\Gis\GisMultiLineString;
|
||||
use PhpMyAdmin\Gis\GisMultiPoint;
|
||||
use PhpMyAdmin\Gis\GisPoint;
|
||||
use PhpMyAdmin\Gis\GisPolygon;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Import\ColumnType;
|
||||
use PhpMyAdmin\Import\Import;
|
||||
use PhpMyAdmin\Import\ImportSettings;
|
||||
@ -74,6 +75,10 @@ class ImportShp extends ImportPlugin
|
||||
return $importPluginProperties;
|
||||
}
|
||||
|
||||
public function setImportOptions(ServerRequest $request): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*
|
||||
|
||||
@ -9,6 +9,7 @@ namespace PhpMyAdmin\Plugins\Import;
|
||||
|
||||
use PhpMyAdmin\DatabaseInterface;
|
||||
use PhpMyAdmin\File;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Import\ImportSettings;
|
||||
use PhpMyAdmin\Plugins\ImportPlugin;
|
||||
use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup;
|
||||
@ -83,6 +84,10 @@ class ImportSql extends ImportPlugin
|
||||
return $importPluginProperties;
|
||||
}
|
||||
|
||||
public function setImportOptions(ServerRequest $request): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*
|
||||
|
||||
@ -11,6 +11,7 @@ namespace PhpMyAdmin\Plugins\Import;
|
||||
|
||||
use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\File;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Import\ImportSettings;
|
||||
use PhpMyAdmin\Import\ImportTable;
|
||||
use PhpMyAdmin\Message;
|
||||
@ -51,6 +52,10 @@ class ImportXml extends ImportPlugin
|
||||
return $importPluginProperties;
|
||||
}
|
||||
|
||||
public function setImportOptions(ServerRequest $request): void
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the whole import logic
|
||||
*
|
||||
|
||||
@ -8,6 +8,7 @@ declare(strict_types=1);
|
||||
namespace PhpMyAdmin\Plugins;
|
||||
|
||||
use PhpMyAdmin\File;
|
||||
use PhpMyAdmin\Http\ServerRequest;
|
||||
use PhpMyAdmin\Import\Import;
|
||||
use PhpMyAdmin\Properties\Plugins\ImportPluginProperties;
|
||||
use PhpMyAdmin\Properties\Plugins\PluginPropertyItem;
|
||||
@ -65,4 +66,6 @@ abstract class ImportPlugin implements Plugin
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract public function setImportOptions(ServerRequest $request): void;
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\DatabaseInterface;
|
||||
use PhpMyAdmin\File;
|
||||
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
|
||||
use PhpMyAdmin\Import\ImportSettings;
|
||||
use PhpMyAdmin\Plugins\Import\ImportCsv;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
@ -57,6 +58,16 @@ class ImportCsvTest extends AbstractTestCase
|
||||
|
||||
$this->object = new ImportCsv();
|
||||
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withParsedBody([
|
||||
'csv_terminated' => "\015",
|
||||
'csv_enclosed' => '"',
|
||||
'csv_escaped' => '"',
|
||||
'csv_new_line' => 'auto',
|
||||
'csv_columns' => null,
|
||||
]);
|
||||
$this->object->setImportOptions($request);
|
||||
|
||||
//setting
|
||||
ImportSettings::$finished = false;
|
||||
ImportSettings::$readLimit = 100000000;
|
||||
@ -68,11 +79,6 @@ class ImportCsvTest extends AbstractTestCase
|
||||
$GLOBALS['compression'] = 'none';
|
||||
ImportSettings::$readMultiply = 10;
|
||||
|
||||
//separator for csv
|
||||
$GLOBALS['csv_terminated'] = "\015";
|
||||
$GLOBALS['csv_enclosed'] = '"';
|
||||
$GLOBALS['csv_escaped'] = '"';
|
||||
$GLOBALS['csv_new_line'] = 'auto';
|
||||
ImportSettings::$importFileName = basename(ImportSettings::$importFile, '.csv');
|
||||
|
||||
//$_SESSION
|
||||
@ -239,6 +245,16 @@ class ImportCsvTest extends AbstractTestCase
|
||||
$GLOBALS['csv_terminated'] = ',';
|
||||
$GLOBALS['import_text'] = '"Row 1","Row 2"' . "\n" . '"123","456"';
|
||||
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withParsedBody([
|
||||
'csv_terminated' => ',',
|
||||
'csv_enclosed' => '"',
|
||||
'csv_escaped' => '"',
|
||||
'csv_new_line' => 'auto',
|
||||
'csv_columns' => null,
|
||||
]);
|
||||
$this->object->setImportOptions($request);
|
||||
|
||||
$this->dummyDbi = $this->createDbiDummy();
|
||||
$this->dbi = $this->createDatabaseInterface($this->dummyDbi);
|
||||
DatabaseInterface::$instance = $this->dbi;
|
||||
@ -281,6 +297,16 @@ class ImportCsvTest extends AbstractTestCase
|
||||
$GLOBALS['csv_terminated'] = ',';
|
||||
$GLOBALS['import_text'] = '"Row 1","Row 2"' . "\n" . '"123","456"';
|
||||
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withParsedBody([
|
||||
'csv_terminated' => ',',
|
||||
'csv_enclosed' => '"',
|
||||
'csv_escaped' => '"',
|
||||
'csv_new_line' => 'auto',
|
||||
'csv_columns' => null,
|
||||
]);
|
||||
$this->object->setImportOptions($request);
|
||||
|
||||
$_REQUEST['csv_col_names'] = 'something';
|
||||
|
||||
$this->dummyDbi = $this->createDbiDummy();
|
||||
|
||||
@ -8,6 +8,7 @@ use PhpMyAdmin\Config;
|
||||
use PhpMyAdmin\Current;
|
||||
use PhpMyAdmin\DatabaseInterface;
|
||||
use PhpMyAdmin\File;
|
||||
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
|
||||
use PhpMyAdmin\Import\ImportSettings;
|
||||
use PhpMyAdmin\Plugins\Import\ImportLdi;
|
||||
use PhpMyAdmin\Tests\AbstractTestCase;
|
||||
@ -30,11 +31,6 @@ class ImportLdiTest extends AbstractTestCase
|
||||
|
||||
DatabaseInterface::$instance = $this->createDatabaseInterface();
|
||||
ImportSettings::$charsetConversion = false;
|
||||
$GLOBALS['ldi_terminated'] = null;
|
||||
$GLOBALS['ldi_escaped'] = null;
|
||||
$GLOBALS['ldi_columns'] = null;
|
||||
$GLOBALS['ldi_enclosed'] = null;
|
||||
$GLOBALS['ldi_new_line'] = null;
|
||||
ImportSettings::$maxSqlLength = 0;
|
||||
$GLOBALS['sql_query'] = '';
|
||||
ImportSettings::$executedQueries = 0;
|
||||
@ -179,19 +175,26 @@ class ImportLdiTest extends AbstractTestCase
|
||||
->willReturnCallback(static fn (string $string): string => "'" . $string . "'");
|
||||
DatabaseInterface::$instance = $dbi;
|
||||
|
||||
$GLOBALS['ldi_local_option'] = true;
|
||||
$GLOBALS['ldi_replace'] = true;
|
||||
$GLOBALS['ldi_ignore'] = true;
|
||||
$GLOBALS['ldi_terminated'] = ',';
|
||||
$GLOBALS['ldi_enclosed'] = ')';
|
||||
$GLOBALS['ldi_new_line'] = 'newline_mark';
|
||||
$request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/')
|
||||
->withParsedBody([
|
||||
'ldi_local_option' => '1',
|
||||
'ldi_replace' => '1',
|
||||
'ldi_ignore' => '1',
|
||||
'ldi_terminated' => ',',
|
||||
'ldi_enclosed' => ')',
|
||||
'ldi_escaped' => null,
|
||||
'ldi_new_line' => 'newline_mark',
|
||||
'ldi_columns' => null,
|
||||
]);
|
||||
ImportSettings::$skipQueries = 1;
|
||||
|
||||
$importHandle = new File(ImportSettings::$importFile);
|
||||
$importHandle->open();
|
||||
|
||||
//Test function called
|
||||
(new ImportLdi())->doImport($importHandle);
|
||||
$object = new ImportLdi();
|
||||
$object->setImportOptions($request);
|
||||
$object->doImport($importHandle);
|
||||
|
||||
//asset that all sql are executed
|
||||
//replace
|
||||
|
||||
Loading…
Reference in New Issue
Block a user