From 32a78a96402cac18d44dbc4c3998afcf5b9c5922 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Mon, 15 Dec 2025 10:20:42 +0100 Subject: [PATCH 01/23] toon export Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 205 ++++++++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 src/Plugins/Export/ExportToon.php diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php new file mode 100644 index 0000000000..731f4f16e8 --- /dev/null +++ b/src/Plugins/Export/ExportToon.php @@ -0,0 +1,205 @@ +setText('Toon'); + $exportPluginProperties->setExtension('toon'); + $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setForceFile(true); + $exportPluginProperties->setOptionsText(__('Options')); + + // create the root group that will be the options field for + // $exportPluginProperties + // this will be shown as "Format specific options" + $exportSpecificOptions = new OptionsPropertyRootGroup('Format Specific Options'); + + // general options main group + $generalOptions = new OptionsPropertyMainGroup('general_opts'); + // create primary items and add them to the group + $leaf = new HiddenPropertyItem('structure_or_data'); + $generalOptions->addProperty($leaf); + // add the main group to the root group + $exportSpecificOptions->addProperty($generalOptions); + + // set the options for the export plugin property item + $exportPluginProperties->setOptions($exportSpecificOptions); + + return $exportPluginProperties; + } + + /** + * Outputs export header + */ + public function exportHeader(): bool + { + return true; + } + + /** + * Outputs export footer + */ + public function exportFooter(): bool + { + return true; + } + + /** + * Outputs database header + * + * @param string $db Database name + * @param string $dbAlias Aliases of db + */ + public function exportDBHeader(string $db, string $dbAlias = ''): bool + { + return true; + } + + /** + * Outputs database footer + * + * @param string $db Database name + */ + public function exportDBFooter(string $db): bool + { + return true; + } + + /** + * Outputs CREATE DATABASE statement + * + * @param string $db Database name + * @param string $dbAlias Aliases of db + */ + public function exportDBCreate(string $db, string $dbAlias = ''): bool + { + return true; + } + + /** + * Outputs the content of a table in JSON format + * + * @param string $db database name + * @param string $table table name + * @param string $sqlQuery SQL query for obtaining data + * @param mixed[] $aliases Aliases of db/table/columns + */ + public function exportData( + string $db, + string $table, + string $sqlQuery, + array $aliases = [], + ): bool { + $dbAlias = $this->getDbAlias($aliases, $db); + $tableAlias = $this->getTableAlias($aliases, $db, $table); + $dbi = DatabaseInterface::getInstance(); + $result = $dbi->query($sqlQuery); + + $columnsCnt = $result->numFields(); + $fieldsMeta = $dbi->getFieldsMeta($result); + + $columns = []; + foreach ($fieldsMeta as $i => $field) { + $colAs = $this->getColumnAlias($aliases, $db, $table, $field->name); + + $columns[$i] = $colAs; + } + + while ($record = $result->fetchRow()) { + $buffer = "$dbAlias.$tableAlias" . '[' . $result->numRows() . ']{'; + foreach ($columns as $index => $column) { + $buffer .= $column; + + if ($index !== count($columns) - 1) { + $buffer .= ', '; + } + } + $buffer .= "}:\n"; + + for ($i = 0; $i < $columnsCnt; $i++) { + if (! array_key_exists($i, $record)) { + continue; + } + + if ($i === 0) { + $buffer .= str_repeat(' ', $this->indent); + } + + if ($record[$i] === null) { + $buffer .= '(NULL)'; + continue; + } + + $buffer .= $record[$i]; + + if ($i !== $columnsCnt - 1) { + $buffer .= ', '; + } + } + $buffer .= "\n\n"; + + if (! $this->export->outputHandler($buffer)) { + return false; + } + } + + return true; + } + + /** + * Outputs result raw query in TOON format + * + * @param string|null $db the database where the query is executed + * @param string $sqlQuery the rawquery to output + */ + public function exportRawQuery(string|null $db, string $sqlQuery): bool + { + if ($db !== null) { + DatabaseInterface::getInstance()->selectDb($db); + } + + return $this->exportData($db ?? '', '', $sqlQuery); + } + + /** @inheritDoc */ + public function setExportOptions(ServerRequest $request, array $exportConfig): void + { + $this->structureOrData = $this->setStructureOrData( + $request->getParsedBodyParam('toon_structure_or_data'), + $exportConfig['toon_structure_or_data'] ?? null, + StructureOrData::Data, + ); + } +} From 3f36d0816801e52cbabd7c098bdb1d8a8fd181f7 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Mon, 15 Dec 2025 10:31:10 +0100 Subject: [PATCH 02/23] update test Signed-off-by: faissaloux --- tests/unit/PluginsTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/PluginsTest.php b/tests/unit/PluginsTest.php index 6076ba453d..a1965296c2 100644 --- a/tests/unit/PluginsTest.php +++ b/tests/unit/PluginsTest.php @@ -34,7 +34,7 @@ class PluginsTest extends AbstractTestCase $isCurl = extension_loaded('curl'); self::assertSame(ExportType::Database, ExportPlugin::$exportType); self::assertFalse(ExportPlugin::$singleTable); - $pluginCount = $isCurl ? 14 : 13; + $pluginCount = $isCurl ? 15 : 14; self::assertCount($pluginCount, $plugins); self::assertContainsOnlyInstancesOf(Plugins\ExportPlugin::class, $plugins); } From 8a87b858a635e204c66cd5c90289b0c40b2637b0 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Mon, 15 Dec 2025 11:27:05 +0100 Subject: [PATCH 03/23] Toon Export tests Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 28 ++-- tests/unit/Plugins/Export/ExportToonTest.php | 164 +++++++++++++++++++ 2 files changed, 182 insertions(+), 10 deletions(-) create mode 100644 tests/unit/Plugins/Export/ExportToonTest.php diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 731f4f16e8..6fb8c2e509 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -128,6 +128,7 @@ class ExportToon extends ExportPlugin $result = $dbi->query($sqlQuery); $columnsCnt = $result->numFields(); + $rowsCnt = $result->numRows(); $fieldsMeta = $dbi->getFieldsMeta($result); $columns = []; @@ -137,17 +138,23 @@ class ExportToon extends ExportPlugin $columns[$i] = $colAs; } - while ($record = $result->fetchRow()) { - $buffer = "$dbAlias.$tableAlias" . '[' . $result->numRows() . ']{'; - foreach ($columns as $index => $column) { - $buffer .= $column; + $buffer = "$dbAlias.$tableAlias" . '[' . $rowsCnt . ']{'; + foreach ($columns as $index => $column) { + $buffer .= $column; - if ($index !== count($columns) - 1) { - $buffer .= ', '; - } + if ($index !== count($columns) - 1) { + $buffer .= ', '; } - $buffer .= "}:\n"; + } + $buffer .= "}:\n"; + + if (! $this->export->outputHandler($buffer)) { + return false; + } + $insertedLines = 0; + while ($record = $result->fetchRow()) { + $buffer = ''; for ($i = 0; $i < $columnsCnt; $i++) { if (! array_key_exists($i, $record)) { continue; @@ -158,7 +165,7 @@ class ExportToon extends ExportPlugin } if ($record[$i] === null) { - $buffer .= '(NULL)'; + $buffer .= 'null'; continue; } @@ -168,8 +175,9 @@ class ExportToon extends ExportPlugin $buffer .= ', '; } } - $buffer .= "\n\n"; + $insertedLines++; + $buffer .= $insertedLines === $rowsCnt ? "\n\n" : "\n"; if (! $this->export->outputHandler($buffer)) { return false; } diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php new file mode 100644 index 0000000000..e72681e028 --- /dev/null +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -0,0 +1,164 @@ +createDatabaseInterface(); + DatabaseInterface::$instance = $dbi; + Current::$database = ''; + Current::$table = ''; + Current::$lang = ''; + Export::$saveFilename = ''; + + $relation = new Relation($dbi); + $this->object = new ExportToon($relation, new Export($dbi), new Transformations($dbi, $relation)); + } + + /** + * tearDown for test cases + */ + protected function tearDown(): void + { + parent::tearDown(); + + unset($this->object); + } + + public function testSetProperties(): void + { + $method = new ReflectionMethod(ExportToon::class, 'setProperties'); + $method->invoke($this->object, null); + + $attrProperties = new ReflectionProperty(ExportToon::class, 'properties'); + $properties = $attrProperties->getValue($this->object); + + self::assertInstanceOf(ExportPluginProperties::class, $properties); + + self::assertSame( + 'Toon', + $properties->getText(), + ); + + self::assertSame( + 'toon', + $properties->getExtension(), + ); + + self::assertSame( + 'text/plain', + $properties->getMimeType(), + ); + + self::assertSame( + 'Options', + $properties->getOptionsText(), + ); + + $options = $properties->getOptions(); + + self::assertInstanceOf(OptionsPropertyRootGroup::class, $options); + + self::assertSame( + 'Format Specific Options', + $options->getName(), + ); + + $generalOptionsArray = $options->getProperties(); + $generalOptions = $generalOptionsArray->current(); + + self::assertInstanceOf(OptionsPropertyMainGroup::class, $generalOptions); + + self::assertSame( + 'general_opts', + $generalOptions->getName(), + ); + + $generalProperties = $generalOptions->getProperties(); + + $property = $generalProperties->current(); + + self::assertInstanceOf(HiddenPropertyItem::class, $property); + + self::assertSame( + 'structure_or_data', + $property->getName(), + ); + } + + public function testExportHeader(): void + { + self::assertTrue($this->object->exportHeader()); + } + + public function testExportFooter(): void + { + self::assertTrue($this->object->exportFooter()); + } + + public function testExportDBHeader(): void + { + self::assertTrue($this->object->exportDBHeader('testDB')); + } + + public function testExportDBFooter(): void + { + self::assertTrue($this->object->exportDBFooter('testDB')); + } + + public function testExportDBCreate(): void + { + self::assertTrue($this->object->exportDBCreate('testDB')); + } + + public function testExportData(): void + { + ob_start(); + self::assertTrue($this->object->exportData( + 'test_db', + 'test_table', + 'SELECT * FROM `test_db`.`test_table`;', + )); + $result = ob_get_clean(); + + self::assertSame( + 'test_db.test_table[3]{id, name, datetimefield}:' . "\n". + ' 1, abcd, 2011-01-20 02:00:02' . "\n" . + ' 2, foo, 2010-01-20 02:00:02' . "\n" . + ' 3, Abcd, 2012-01-20 02:00:02' . "\n\n", + $result, + ); + } +} From f8f85c3bcfddd64487bf06410cfd6b6157e7b5c7 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Mon, 15 Dec 2025 19:51:18 +0100 Subject: [PATCH 04/23] remove extra whitespaces Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 6 +++--- tests/unit/Plugins/Export/ExportToonTest.php | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 6fb8c2e509..ed533c149e 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -37,7 +37,7 @@ class ExportToon extends ExportPlugin $exportPluginProperties = new ExportPluginProperties(); $exportPluginProperties->setText('Toon'); $exportPluginProperties->setExtension('toon'); - $exportPluginProperties->setMimeType('text/plain'); + $exportPluginProperties->setMimeType('text/toon'); $exportPluginProperties->setForceFile(true); $exportPluginProperties->setOptionsText(__('Options')); @@ -143,7 +143,7 @@ class ExportToon extends ExportPlugin $buffer .= $column; if ($index !== count($columns) - 1) { - $buffer .= ', '; + $buffer .= ','; } } $buffer .= "}:\n"; @@ -172,7 +172,7 @@ class ExportToon extends ExportPlugin $buffer .= $record[$i]; if ($i !== $columnsCnt - 1) { - $buffer .= ', '; + $buffer .= ','; } } diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php index e72681e028..47f64e6dce 100644 --- a/tests/unit/Plugins/Export/ExportToonTest.php +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -78,7 +78,7 @@ class ExportToonTest extends AbstractTestCase ); self::assertSame( - 'text/plain', + 'text/toon', $properties->getMimeType(), ); @@ -154,10 +154,10 @@ class ExportToonTest extends AbstractTestCase $result = ob_get_clean(); self::assertSame( - 'test_db.test_table[3]{id, name, datetimefield}:' . "\n". - ' 1, abcd, 2011-01-20 02:00:02' . "\n" . - ' 2, foo, 2010-01-20 02:00:02' . "\n" . - ' 3, Abcd, 2012-01-20 02:00:02' . "\n\n", + 'test_db.test_table[3]{id,name,datetimefield}:' . "\n". + ' 1,abcd,2011-01-20 02:00:02' . "\n" . + ' 2,foo,2010-01-20 02:00:02' . "\n" . + ' 3,Abcd,2012-01-20 02:00:02' . "\n\n", $result, ); } From 44b4a72d4d03d1eefa53fc7b19be2cad21dbfafb Mon Sep 17 00:00:00 2001 From: faissaloux Date: Wed, 17 Dec 2025 22:50:58 +0100 Subject: [PATCH 05/23] rebase Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 52 +------------------- tests/unit/Plugins/Export/ExportToonTest.php | 5 +- 2 files changed, 4 insertions(+), 53 deletions(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index ed533c149e..192512a7fd 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -60,54 +60,6 @@ class ExportToon extends ExportPlugin return $exportPluginProperties; } - /** - * Outputs export header - */ - public function exportHeader(): bool - { - return true; - } - - /** - * Outputs export footer - */ - public function exportFooter(): bool - { - return true; - } - - /** - * Outputs database header - * - * @param string $db Database name - * @param string $dbAlias Aliases of db - */ - public function exportDBHeader(string $db, string $dbAlias = ''): bool - { - return true; - } - - /** - * Outputs database footer - * - * @param string $db Database name - */ - public function exportDBFooter(string $db): bool - { - return true; - } - - /** - * Outputs CREATE DATABASE statement - * - * @param string $db Database name - * @param string $dbAlias Aliases of db - */ - public function exportDBCreate(string $db, string $dbAlias = ''): bool - { - return true; - } - /** * Outputs the content of a table in JSON format * @@ -148,7 +100,7 @@ class ExportToon extends ExportPlugin } $buffer .= "}:\n"; - if (! $this->export->outputHandler($buffer)) { + if (! $this->outputHandler->addLine($buffer)) { return false; } @@ -178,7 +130,7 @@ class ExportToon extends ExportPlugin $insertedLines++; $buffer .= $insertedLines === $rowsCnt ? "\n\n" : "\n"; - if (! $this->export->outputHandler($buffer)) { + if (! $this->outputHandler->addLine($buffer)) { return false; } } diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php index 47f64e6dce..268da27fd2 100644 --- a/tests/unit/Plugins/Export/ExportToonTest.php +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -7,7 +7,7 @@ namespace PhpMyAdmin\Tests\Plugins\Export; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Current; use PhpMyAdmin\Dbal\DatabaseInterface; -use PhpMyAdmin\Export\Export; +use PhpMyAdmin\Export\OutputHandler; use PhpMyAdmin\Plugins\Export\ExportToon; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -41,10 +41,9 @@ class ExportToonTest extends AbstractTestCase Current::$database = ''; Current::$table = ''; Current::$lang = ''; - Export::$saveFilename = ''; $relation = new Relation($dbi); - $this->object = new ExportToon($relation, new Export($dbi), new Transformations($dbi, $relation)); + $this->object = new ExportToon($relation, new OutputHandler(), new Transformations($dbi, $relation)); } /** From 875d2f561c07d184aadb472b10e1a640a6d598af Mon Sep 17 00:00:00 2001 From: faissaloux Date: Thu, 18 Dec 2025 00:03:43 +0100 Subject: [PATCH 06/23] toon configurable indent and separator Signed-off-by: faissaloux --- src/Config/Settings/Export.php | 40 +++++++++++++++ src/Plugins/Export/ExportToon.php | 53 +++++++++++++++++++- tests/unit/Plugins/Export/ExportToonTest.php | 31 ++++++++++++ 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/src/Config/Settings/Export.php b/src/Config/Settings/Export.php index e5ac8c0e7d..6da17eac03 100644 --- a/src/Config/Settings/Export.php +++ b/src/Config/Settings/Export.php @@ -55,6 +55,8 @@ use function in_array; * csv_escaped: string, * csv_terminated: string, * csv_removeCRLF: bool, + * toon_indent: int, + * toon_separator: string, * excel_columns: bool, * excel_null: string, * excel_edition: 'mac_excel2003'|'mac_excel2008'|'win', @@ -442,6 +444,20 @@ final class Export */ public bool $csv_removeCRLF; + /** + * ```php + * $cfg['Export']['toon_indent'] = 2; + * ``` + */ + public int $toon_indent; + + /** + * ```php + * $cfg['Export']['toon_separator'] = ','; + * ``` + */ + public string $toon_separator; + /** * ```php * $cfg['Export']['excel_columns'] = true; @@ -1031,6 +1047,8 @@ final class Export $this->csv_escaped = $this->setCsvEscaped($export); $this->csv_terminated = $this->setCsvTerminated($export); $this->csv_removeCRLF = $this->setCsvRemoveCRLF($export); + $this->toon_indent = $this->setToonIndent($export); + $this->toon_separator = $this->setToonSeparator($export); $this->excel_columns = $this->setExcelColumns($export); $this->excel_null = $this->setExcelNull($export); $this->excel_edition = $this->setExcelEdition($export); @@ -1146,6 +1164,8 @@ final class Export 'csv_escaped' => $this->csv_escaped, 'csv_terminated' => $this->csv_terminated, 'csv_removeCRLF' => $this->csv_removeCRLF, + 'toon_indent' => $this->toon_indent, + 'toon_separator' => $this->toon_separator, 'excel_columns' => $this->excel_columns, 'excel_null' => $this->excel_null, 'excel_edition' => $this->excel_edition, @@ -1680,6 +1700,26 @@ final class Export return (bool) $export['csv_removeCRLF']; } + /** @param array $export */ + private function setToonIndent(array $export): int + { + if (! isset($export['toon_indent'])) { + return 2; + } + + return (int) $export['toon_indent']; + } + + /** @param array $export */ + private function setToonSeparator(array $export): string + { + if (! isset($export['toon_separator'])) { + return ','; + } + + return (string) $export['toon_separator']; + } + /** @param array $export */ private function setExcelColumns(array $export): bool { diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 192512a7fd..d27828506c 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -14,6 +14,7 @@ use PhpMyAdmin\Plugins\ExportPlugin; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem; +use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use function __; @@ -25,6 +26,7 @@ use function array_key_exists; class ExportToon extends ExportPlugin { private int $indent = 2; + private string $separator = ','; /** @psalm-return non-empty-lowercase-string */ public function getName(): string @@ -48,6 +50,17 @@ class ExportToon extends ExportPlugin // general options main group $generalOptions = new OptionsPropertyMainGroup('general_opts'); + // create leaf items and add them to the group + $leaf = new TextPropertyItem( + 'separator', + __('Columns separated with:'), + ); + $generalOptions->addProperty($leaf); + $leaf = new TextPropertyItem( + 'indent', + __('Indentation:'), + ); + $generalOptions->addProperty($leaf); // create primary items and add them to the group $leaf = new HiddenPropertyItem('structure_or_data'); $generalOptions->addProperty($leaf); @@ -95,7 +108,7 @@ class ExportToon extends ExportPlugin $buffer .= $column; if ($index !== count($columns) - 1) { - $buffer .= ','; + $buffer .= $this->separator; } } $buffer .= "}:\n"; @@ -124,7 +137,7 @@ class ExportToon extends ExportPlugin $buffer .= $record[$i]; if ($i !== $columnsCnt - 1) { - $buffer .= ','; + $buffer .= $this->separator; } } @@ -161,5 +174,41 @@ class ExportToon extends ExportPlugin $exportConfig['toon_structure_or_data'] ?? null, StructureOrData::Data, ); + + $this->separator = $this->setStringValue( + $request->getParsedBodyParam('toon_separator'), + $exportConfig['toon_separator'] ?? $this->separator, + ); + + $this->indent = $this->setIntValue( + (int) $request->getParsedBodyParam('toon_indent'), + $exportConfig['toon_indent'] ?? $this->indent, + ); + } + + private function setStringValue(mixed $fromRequest, mixed $fromConfig): string + { + if (is_string($fromRequest) && $fromRequest !== '') { + return $fromRequest; + } + + if (is_string($fromConfig) && $fromConfig !== '') { + return $fromConfig; + } + + return ''; + } + + private function setIntValue(mixed $fromRequest, mixed $fromConfig): int + { + if (is_int($fromRequest)) { + return $fromRequest; + } + + if (is_int($fromConfig)) { + return $fromConfig; + } + + return 0; } } diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php index 268da27fd2..ae346ac23e 100644 --- a/tests/unit/Plugins/Export/ExportToonTest.php +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -12,6 +12,7 @@ use PhpMyAdmin\Plugins\Export\ExportToon; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem; +use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Transformations; @@ -107,6 +108,36 @@ class ExportToonTest extends AbstractTestCase $generalProperties = $generalOptions->getProperties(); + $property = $generalProperties->current(); + $generalProperties->next(); + + self::assertInstanceOf(TextPropertyItem::class, $property); + + self::assertSame( + 'separator', + $property->getName(), + ); + + self::assertSame( + 'Columns separated with:', + $property->getText(), + ); + + $property = $generalProperties->current(); + $generalProperties->next(); + + self::assertInstanceOf(TextPropertyItem::class, $property); + + self::assertSame( + 'indent', + $property->getName(), + ); + + self::assertSame( + 'Indentation:', + $property->getText(), + ); + $property = $generalProperties->current(); self::assertInstanceOf(HiddenPropertyItem::class, $property); From 2d5daa493623ee7982919f96a5b5b50c983dc1df Mon Sep 17 00:00:00 2001 From: faissaloux Date: Thu, 18 Dec 2025 00:26:12 +0100 Subject: [PATCH 07/23] documentation Signed-off-by: faissaloux --- docs/import_export.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/import_export.rst b/docs/import_export.rst index b0144ebf42..365a2fa808 100644 --- a/docs/import_export.rst +++ b/docs/import_export.rst @@ -264,6 +264,12 @@ rendered, for example in following document: \end{document} +Toon +---- + +Data can be exported to Toon format, which is a compact, +human-readable encoding of the JSON data model. + MediaWiki --------- From 3f8f923be6484808890af32ed91541049ae5e016 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sat, 20 Dec 2025 14:30:29 +0100 Subject: [PATCH 08/23] toon custom configuration test Signed-off-by: faissaloux --- tests/unit/Plugins/Export/ExportToonTest.php | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php index ae346ac23e..a6f00e84e9 100644 --- a/tests/unit/Plugins/Export/ExportToonTest.php +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -8,6 +8,7 @@ use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\Current; use PhpMyAdmin\Dbal\DatabaseInterface; use PhpMyAdmin\Export\OutputHandler; +use PhpMyAdmin\Http\Factory\ServerRequestFactory; use PhpMyAdmin\Plugins\Export\ExportToon; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -191,4 +192,29 @@ class ExportToonTest extends AbstractTestCase $result, ); } + + public function testExportDataWithCustomConfig(): void + { + $request = ServerRequestFactory::create()->createServerRequest('POST', 'https://example.com/') + ->withParsedBody(['toon_separator' => '|', 'toon_indent' => 4]); + + $this->object->setExportOptions($request, []); + $this->object->exportHeader(); + + ob_start(); + self::assertTrue($this->object->exportData( + 'test_db', + 'test_table', + 'SELECT * FROM `test_db`.`test_table`;', + )); + $result = ob_get_clean(); + + self::assertSame( + 'test_db.test_table[3]{id|name|datetimefield}:' . "\n". + ' 1|abcd|2011-01-20 02:00:02' . "\n" . + ' 2|foo|2010-01-20 02:00:02' . "\n" . + ' 3|Abcd|2012-01-20 02:00:02' . "\n\n", + $result, + ); + } } From 4cc53cf1df59b633e42f2177983055b93f218fe0 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sat, 20 Dec 2025 14:50:42 +0100 Subject: [PATCH 09/23] refactor Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index d27828506c..480935f9a2 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -118,25 +118,22 @@ class ExportToon extends ExportPlugin } $insertedLines = 0; - while ($record = $result->fetchRow()) { + while ($row = $result->fetchRow()) { $buffer = ''; - for ($i = 0; $i < $columnsCnt; $i++) { - if (! array_key_exists($i, $record)) { - continue; - } - if ($i === 0) { + foreach ($row as $index => $col) { + if ($index === 0) { $buffer .= str_repeat(' ', $this->indent); } - if ($record[$i] === null) { + if ($col === null) { $buffer .= 'null'; continue; } - $buffer .= $record[$i]; + $buffer .= $col; - if ($i !== $columnsCnt - 1) { + if ($index !== $columnsCnt - 1) { $buffer .= $this->separator; } } From 405c08d51a46541bb61adde035090e30a78c5583 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sun, 21 Dec 2025 22:20:18 +0100 Subject: [PATCH 10/23] rename Toon -> TOON Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 2 +- tests/unit/Plugins/Export/ExportToonTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 480935f9a2..c0ba36bad5 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -37,7 +37,7 @@ class ExportToon extends ExportPlugin protected function setProperties(): ExportPluginProperties { $exportPluginProperties = new ExportPluginProperties(); - $exportPluginProperties->setText('Toon'); + $exportPluginProperties->setText('TOON'); $exportPluginProperties->setExtension('toon'); $exportPluginProperties->setMimeType('text/toon'); $exportPluginProperties->setForceFile(true); diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php index a6f00e84e9..fbd1cc0828 100644 --- a/tests/unit/Plugins/Export/ExportToonTest.php +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -69,7 +69,7 @@ class ExportToonTest extends AbstractTestCase self::assertInstanceOf(ExportPluginProperties::class, $properties); self::assertSame( - 'Toon', + 'TOON', $properties->getText(), ); From 2a5c05d27f0e0cd66058d75560f1d319a54fa6ed Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sun, 21 Dec 2025 22:44:02 +0100 Subject: [PATCH 11/23] add separator next counter Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 2 +- tests/unit/Plugins/Export/ExportToonTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index c0ba36bad5..030fa6ec64 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -103,7 +103,7 @@ class ExportToon extends ExportPlugin $columns[$i] = $colAs; } - $buffer = "$dbAlias.$tableAlias" . '[' . $rowsCnt . ']{'; + $buffer = "$dbAlias.$tableAlias" . '[' . $rowsCnt . ($this->separator !== ',' ? $this->separator : '') . ']{'; foreach ($columns as $index => $column) { $buffer .= $column; diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php index fbd1cc0828..249efa50f6 100644 --- a/tests/unit/Plugins/Export/ExportToonTest.php +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -210,7 +210,7 @@ class ExportToonTest extends AbstractTestCase $result = ob_get_clean(); self::assertSame( - 'test_db.test_table[3]{id|name|datetimefield}:' . "\n". + 'test_db.test_table[3|]{id|name|datetimefield}:' . "\n". ' 1|abcd|2011-01-20 02:00:02' . "\n" . ' 2|foo|2010-01-20 02:00:02' . "\n" . ' 3|Abcd|2012-01-20 02:00:02' . "\n\n", From 24b49f04d35b084eb7d556639d5251ec62aa4a5a Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sun, 21 Dec 2025 22:52:36 +0100 Subject: [PATCH 12/23] support tab separator Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 030fa6ec64..134e31d0be 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -163,6 +163,11 @@ class ExportToon extends ExportPlugin return $this->exportData($db ?? '', '', $sqlQuery); } + private function setupExportConfiguration(): void + { + $this->separator = str_replace('\\t', "\011", $this->separator); + } + /** @inheritDoc */ public function setExportOptions(ServerRequest $request, array $exportConfig): void { @@ -181,6 +186,8 @@ class ExportToon extends ExportPlugin (int) $request->getParsedBodyParam('toon_indent'), $exportConfig['toon_indent'] ?? $this->indent, ); + + $this->setupExportConfiguration(); } private function setStringValue(mixed $fromRequest, mixed $fromConfig): string From 05b4d86f5514cf466997d11049bffd86e17fe619 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Thu, 22 Jan 2026 15:01:08 +0100 Subject: [PATCH 13/23] update documentation Signed-off-by: faissaloux --- docs/import_export.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/import_export.rst b/docs/import_export.rst index 365a2fa808..38f0dde3f8 100644 --- a/docs/import_export.rst +++ b/docs/import_export.rst @@ -264,11 +264,12 @@ rendered, for example in following document: \end{document} -Toon +TOON ---- -Data can be exported to Toon format, which is a compact, -human-readable encoding of the JSON data model. +Data can be exported to TOON `(Token-Oriented Object Notation) `_, +which is a text-based data format. It encodes the JSON data model in a compact way. +TOON is designed to reduce token usage in LLM prompts while staying human-readable. MediaWiki --------- From 7e7e1ebcf592ad9ef7d826cfdb60ba1809ff24cb Mon Sep 17 00:00:00 2001 From: faissaloux Date: Thu, 22 Jan 2026 15:17:00 +0100 Subject: [PATCH 14/23] adapt ExportToon methods with ExportPlugin Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 134e31d0be..51e4752233 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -86,7 +86,7 @@ class ExportToon extends ExportPlugin string $table, string $sqlQuery, array $aliases = [], - ): bool { + ): void { $dbAlias = $this->getDbAlias($aliases, $db); $tableAlias = $this->getTableAlias($aliases, $db, $table); $dbi = DatabaseInterface::getInstance(); @@ -112,10 +112,8 @@ class ExportToon extends ExportPlugin } } $buffer .= "}:\n"; - - if (! $this->outputHandler->addLine($buffer)) { - return false; - } + + $this->outputHandler->addLine($buffer); $insertedLines = 0; while ($row = $result->fetchRow()) { @@ -140,12 +138,8 @@ class ExportToon extends ExportPlugin $insertedLines++; $buffer .= $insertedLines === $rowsCnt ? "\n\n" : "\n"; - if (! $this->outputHandler->addLine($buffer)) { - return false; - } + $this->outputHandler->addLine($buffer); } - - return true; } /** @@ -154,13 +148,13 @@ class ExportToon extends ExportPlugin * @param string|null $db the database where the query is executed * @param string $sqlQuery the rawquery to output */ - public function exportRawQuery(string|null $db, string $sqlQuery): bool + public function exportRawQuery(string|null $db, string $sqlQuery): void { if ($db !== null) { DatabaseInterface::getInstance()->selectDb($db); } - return $this->exportData($db ?? '', '', $sqlQuery); + $this->exportData($db ?? '', '', $sqlQuery); } private function setupExportConfiguration(): void @@ -176,7 +170,7 @@ class ExportToon extends ExportPlugin $exportConfig['toon_structure_or_data'] ?? null, StructureOrData::Data, ); - + $this->separator = $this->setStringValue( $request->getParsedBodyParam('toon_separator'), $exportConfig['toon_separator'] ?? $this->separator, From d65c0ba430a8cd3b6d0395e250c7345df6ac345e Mon Sep 17 00:00:00 2001 From: faissaloux Date: Thu, 22 Jan 2026 15:31:02 +0100 Subject: [PATCH 15/23] fix tests Signed-off-by: faissaloux --- tests/unit/Plugins/Export/ExportToonTest.php | 27 +++++++++----------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php index 249efa50f6..cc6175a451 100644 --- a/tests/unit/Plugins/Export/ExportToonTest.php +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -151,37 +151,38 @@ class ExportToonTest extends AbstractTestCase public function testExportHeader(): void { - self::assertTrue($this->object->exportHeader()); + $this->expectNotToPerformAssertions(); + $this->object->exportHeader(); } public function testExportFooter(): void { - self::assertTrue($this->object->exportFooter()); + $this->expectNotToPerformAssertions(); + $this->object->exportFooter(); } public function testExportDBHeader(): void { - self::assertTrue($this->object->exportDBHeader('testDB')); + $this->expectNotToPerformAssertions(); + $this->object->exportDBHeader('testDB'); } public function testExportDBFooter(): void { - self::assertTrue($this->object->exportDBFooter('testDB')); + $this->expectNotToPerformAssertions(); + $this->object->exportDBFooter('testDB'); } public function testExportDBCreate(): void { - self::assertTrue($this->object->exportDBCreate('testDB')); + $this->expectNotToPerformAssertions(); + $this->object->exportDBCreate('testDB'); } public function testExportData(): void { ob_start(); - self::assertTrue($this->object->exportData( - 'test_db', - 'test_table', - 'SELECT * FROM `test_db`.`test_table`;', - )); + $this->object->exportData('test_db', 'test_table', 'SELECT * FROM `test_db`.`test_table`;'); $result = ob_get_clean(); self::assertSame( @@ -202,11 +203,7 @@ class ExportToonTest extends AbstractTestCase $this->object->exportHeader(); ob_start(); - self::assertTrue($this->object->exportData( - 'test_db', - 'test_table', - 'SELECT * FROM `test_db`.`test_table`;', - )); + $this->object->exportData('test_db', 'test_table', 'SELECT * FROM `test_db`.`test_table`;'); $result = ob_get_clean(); self::assertSame( From f469a6aac535c7f4c0d9de032fcd7546abc1a769 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Thu, 22 Jan 2026 15:49:19 +0100 Subject: [PATCH 16/23] use array_key_last Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 51e4752233..1774423ea0 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -19,6 +19,7 @@ use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use function __; use function array_key_exists; +use function array_key_last; /** * Handles the export for the TOON format @@ -107,7 +108,7 @@ class ExportToon extends ExportPlugin foreach ($columns as $index => $column) { $buffer .= $column; - if ($index !== count($columns) - 1) { + if ($index !== array_key_last($columns)) { $buffer .= $this->separator; } } From bcf941514563c02f4dedaeae93a937d43c5eef83 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Thu, 22 Jan 2026 16:05:02 +0100 Subject: [PATCH 17/23] lint Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 1774423ea0..e8992d6bc3 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -18,8 +18,11 @@ use PhpMyAdmin\Properties\Options\Items\TextPropertyItem; use PhpMyAdmin\Properties\Plugins\ExportPluginProperties; use function __; -use function array_key_exists; use function array_key_last; +use function is_int; +use function is_string; +use function str_repeat; +use function str_replace; /** * Handles the export for the TOON format @@ -104,14 +107,16 @@ class ExportToon extends ExportPlugin $columns[$i] = $colAs; } - $buffer = "$dbAlias.$tableAlias" . '[' . $rowsCnt . ($this->separator !== ',' ? $this->separator : '') . ']{'; + $buffer = $dbAlias . '.' . $tableAlias . '[' . $rowsCnt . ($this->separator !== ',' ? $this->separator : '') . ']{'; foreach ($columns as $index => $column) { $buffer .= $column; + // phpcs:ignore SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed if ($index !== array_key_last($columns)) { $buffer .= $this->separator; } } + $buffer .= "}:\n"; $this->outputHandler->addLine($buffer); @@ -132,6 +137,7 @@ class ExportToon extends ExportPlugin $buffer .= $col; + // phpcs:ignore SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed if ($index !== $columnsCnt - 1) { $buffer .= $this->separator; } From 2b1e480aba3d47fb3261a86e474ddb73730c315c Mon Sep 17 00:00:00 2001 From: faissaloux Date: Thu, 22 Jan 2026 16:22:38 +0100 Subject: [PATCH 18/23] lint Signed-off-by: faissaloux --- tests/unit/Plugins/Export/ExportToonTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php index cc6175a451..fe6b62afb6 100644 --- a/tests/unit/Plugins/Export/ExportToonTest.php +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -186,7 +186,7 @@ class ExportToonTest extends AbstractTestCase $result = ob_get_clean(); self::assertSame( - 'test_db.test_table[3]{id,name,datetimefield}:' . "\n". + 'test_db.test_table[3]{id,name,datetimefield}:' . "\n" . ' 1,abcd,2011-01-20 02:00:02' . "\n" . ' 2,foo,2010-01-20 02:00:02' . "\n" . ' 3,Abcd,2012-01-20 02:00:02' . "\n\n", @@ -207,7 +207,7 @@ class ExportToonTest extends AbstractTestCase $result = ob_get_clean(); self::assertSame( - 'test_db.test_table[3|]{id|name|datetimefield}:' . "\n". + 'test_db.test_table[3|]{id|name|datetimefield}:' . "\n" . ' 1|abcd|2011-01-20 02:00:02' . "\n" . ' 2|foo|2010-01-20 02:00:02' . "\n" . ' 3|Abcd|2012-01-20 02:00:02' . "\n\n", From 85841976fe32596d9bfbe93f6bf606d7d86cb674 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sun, 25 Jan 2026 00:55:46 +0100 Subject: [PATCH 19/23] align exportRawQuery param with the rest Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index e8992d6bc3..56b7c65e8c 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -152,16 +152,16 @@ class ExportToon extends ExportPlugin /** * Outputs result raw query in TOON format * - * @param string|null $db the database where the query is executed - * @param string $sqlQuery the rawquery to output + * @param string $db the database where the query is executed + * @param string $sqlQuery the rawquery to output */ - public function exportRawQuery(string|null $db, string $sqlQuery): void + public function exportRawQuery(string $db, string $sqlQuery): void { - if ($db !== null) { + if ($db !== '') { DatabaseInterface::getInstance()->selectDb($db); } - $this->exportData($db ?? '', '', $sqlQuery); + $this->exportData($db, '', $sqlQuery); } private function setupExportConfiguration(): void From 6faaca102e7b8bc5b890ab7157587c65b72c3876 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sun, 25 Jan 2026 01:24:05 +0100 Subject: [PATCH 20/23] make phpstan happy Signed-off-by: faissaloux --- phpstan-baseline.neon | 22 ++++++++++++++++---- tests/unit/Plugins/Export/ExportToonTest.php | 2 +- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 7d4e3e026c..c7ca973cfa 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -789,13 +789,19 @@ parameters: - message: '#^Cannot cast mixed to int\.$#' identifier: cast.int - count: 2 + count: 3 path: src/Config/Settings/Export.php + - + message: '#^Cannot cast mixed to int\.$#' + identifier: cast.int + count: 1 + path: src\Plugins\Export\ExportToon.php + - message: '#^Cannot cast mixed to string\.$#' identifier: cast.string - count: 23 + count: 24 path: src/Config/Settings/Export.php - @@ -5818,7 +5824,7 @@ parameters: path: src/Export/Options.php - - message: '#^Only booleans are allowed in &&, bool\|int\<0, max\>\|string given on the right side\.$#' + message: '#^Only booleans are allowed in &&, bool\|int\|string given on the right side\.$#' identifier: booleanAnd.rightNotBoolean count: 1 path: src/Export/Options.php @@ -8919,6 +8925,15 @@ parameters: count: 15 path: src/Plugins/Export/ExportSql.php + - + message: ''' + #^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Dbal\\DatabaseInterface\: + Use dependency injection instead\.$# + ''' + identifier: staticMethod.deprecated + count: 2 + path: src/Plugins/Export/ExportToon.php + - message: '#^Cannot access property \$database on PhpMyAdmin\\SqlParser\\Components\\Expression\|null\.$#' identifier: property.nonObject @@ -17465,4 +17480,3 @@ parameters: identifier: staticMethod.alreadyNarrowedType count: 1 path: tests/unit/WebAuthn/WebauthnLibServerTest.php - diff --git a/tests/unit/Plugins/Export/ExportToonTest.php b/tests/unit/Plugins/Export/ExportToonTest.php index fe6b62afb6..994301288d 100644 --- a/tests/unit/Plugins/Export/ExportToonTest.php +++ b/tests/unit/Plugins/Export/ExportToonTest.php @@ -197,7 +197,7 @@ class ExportToonTest extends AbstractTestCase public function testExportDataWithCustomConfig(): void { $request = ServerRequestFactory::create()->createServerRequest('POST', 'https://example.com/') - ->withParsedBody(['toon_separator' => '|', 'toon_indent' => 4]); + ->withParsedBody(['toon_separator' => '|', 'toon_indent' => '4']); $this->object->setExportOptions($request, []); $this->object->exportHeader(); From e86b9703b50ec9feba5ecdbea7e27d5f8f2f9909 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sun, 25 Jan 2026 01:35:52 +0100 Subject: [PATCH 21/23] psalm ignore deprecated getInstance method Signed-off-by: faissaloux --- psalm-baseline.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 18c4612c1a..0694d3d107 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -5837,6 +5837,12 @@ + + + + + + From a5998a2c2e9c5bc64556a3e3a70d906e06aa11e3 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sun, 25 Jan 2026 01:54:42 +0100 Subject: [PATCH 22/23] make line shorter for phpcs Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 56b7c65e8c..5f169b525d 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -21,6 +21,7 @@ use function __; use function array_key_last; use function is_int; use function is_string; +use function sprintf; use function str_repeat; use function str_replace; @@ -107,7 +108,13 @@ class ExportToon extends ExportPlugin $columns[$i] = $colAs; } - $buffer = $dbAlias . '.' . $tableAlias . '[' . $rowsCnt . ($this->separator !== ',' ? $this->separator : '') . ']{'; + $buffer = sprintf( + "%s.%s[%s%s]{", + $dbAlias, + $tableAlias, + $rowsCnt, + $this->separator !== ',' ? $this->separator : '' + ); foreach ($columns as $index => $column) { $buffer .= $column; From e5b165caf045ecdfe8901be0a026566992951254 Mon Sep 17 00:00:00 2001 From: faissaloux Date: Sun, 25 Jan 2026 02:02:17 +0100 Subject: [PATCH 23/23] [phpcs] last one Signed-off-by: faissaloux --- src/Plugins/Export/ExportToon.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugins/Export/ExportToon.php b/src/Plugins/Export/ExportToon.php index 5f169b525d..766f2c946b 100644 --- a/src/Plugins/Export/ExportToon.php +++ b/src/Plugins/Export/ExportToon.php @@ -109,11 +109,11 @@ class ExportToon extends ExportPlugin } $buffer = sprintf( - "%s.%s[%s%s]{", + '%s.%s[%s%s]{', $dbAlias, $tableAlias, $rowsCnt, - $this->separator !== ',' ? $this->separator : '' + $this->separator !== ',' ? $this->separator : '', ); foreach ($columns as $index => $column) { $buffer .= $column;