mirror of
https://github.com/Codappix/typo3-php-datasets.git
synced 2024-12-04 19:57:26 +01:00
Add command to convert from CSV to PHP (#10)
This commit is contained in:
parent
3e594a0d15
commit
7589a2bf9a
12 changed files with 346 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
$finder = (new PhpCsFixer\Finder())
|
$finder = (new PhpCsFixer\Finder())
|
||||||
->ignoreVCSIgnored(true)
|
->ignoreVCSIgnored(true)
|
||||||
|
->exclude('Tests/Functional/Converter/Fixtures/Csv/')
|
||||||
->exclude('Tests/Functional/Converter/Fixtures/Xml/')
|
->exclude('Tests/Functional/Converter/Fixtures/Xml/')
|
||||||
->in(realpath(__DIR__))
|
->in(realpath(__DIR__))
|
||||||
;
|
;
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## v1.4.0 - 2023-11-07
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add command `convert-from-csv`.
|
||||||
|
|
||||||
## v1.3.1 - 2023-08-10
|
## v1.3.1 - 2023-08-10
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
62
Classes/Command/ConvertFromCsv.php
Normal file
62
Classes/Command/ConvertFromCsv.php
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Codappix\Typo3PhpDatasets\Command;
|
||||||
|
|
||||||
|
use Codappix\Typo3PhpDatasets\Converter\Csv;
|
||||||
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
class ConvertFromCsv extends Command
|
||||||
|
{
|
||||||
|
protected static $defaultName = 'convert-from-csv';
|
||||||
|
protected static $defaultDescription = 'Converts CSV data-sets to PHP data-sets.';
|
||||||
|
|
||||||
|
protected function configure(): void
|
||||||
|
{
|
||||||
|
$this->addArgument('file', InputArgument::IS_ARRAY, 'The file(s) to convert.');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
|
{
|
||||||
|
$files = $input->getArgument('file');
|
||||||
|
if (is_array($files) === false) {
|
||||||
|
$output->writeln('File needs to be an array.');
|
||||||
|
return Command::INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
$converter = new Csv();
|
||||||
|
foreach ($files as $file) {
|
||||||
|
try {
|
||||||
|
$converter->convert(realpath($file) ?: $file);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$output->writeln($e->getMessage());
|
||||||
|
return Command::INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Command::SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
99
Classes/Converter/Csv.php
Normal file
99
Classes/Converter/Csv.php
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Codappix\Typo3PhpDatasets\Converter;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use SplFileObject;
|
||||||
|
|
||||||
|
class Csv implements Converter
|
||||||
|
{
|
||||||
|
public function convert(string $fileName): string
|
||||||
|
{
|
||||||
|
if (file_exists($fileName) === false) {
|
||||||
|
throw new InvalidArgumentException('Given file "' . $fileName . '" does not exist.', 1681283739);
|
||||||
|
}
|
||||||
|
|
||||||
|
$phpFileName = $this->getNewFileName($fileName);
|
||||||
|
$incomingFile = new SplFileObject($fileName);
|
||||||
|
|
||||||
|
try {
|
||||||
|
file_put_contents($phpFileName, $this->buildContent($incomingFile));
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
throw new \Exception('Could not generate new file.', 1681287881, $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $phpFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getNewFileName(string $fileName): string
|
||||||
|
{
|
||||||
|
$file = new SplFileObject($fileName);
|
||||||
|
return str_replace(
|
||||||
|
$file->getBasename(),
|
||||||
|
$file->getBasename($file->getExtension()) . 'php',
|
||||||
|
$file->getRealPath()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function buildContent(SplFileObject $incomingFile): string
|
||||||
|
{
|
||||||
|
$phpArray = [];
|
||||||
|
$tableName = '';
|
||||||
|
$columns = [];
|
||||||
|
|
||||||
|
$incomingFile->setFlags(SplFileObject::READ_CSV);
|
||||||
|
$incomingFile->setCsvControl(',', '"', '"');
|
||||||
|
|
||||||
|
foreach ($incomingFile as $line) {
|
||||||
|
if (is_array($line) && count($line) === 1 && is_null($line[0])) {
|
||||||
|
// End of file
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($line) && count($line) === 1 && is_string($line[0])) {
|
||||||
|
// Line is a new table, introducing also new columns o next row
|
||||||
|
$tableName = $line[0];
|
||||||
|
$columns = [];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($columns === [] && is_array($line)) {
|
||||||
|
$columns = array_slice($line, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($line)) {
|
||||||
|
$values = array_slice($line, 1);
|
||||||
|
$phpArray[$tableName][] = array_combine($columns, $values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(PHP_EOL, [
|
||||||
|
'<?php',
|
||||||
|
'',
|
||||||
|
'return ' . var_export($phpArray, true) . ';',
|
||||||
|
'',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
104
Tests/Functional/Converter/CsvTest.php
Normal file
104
Tests/Functional/Converter/CsvTest.php
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Codappix\Typo3PhpDatasets\Tests\Functional\Converter;
|
||||||
|
|
||||||
|
use Codappix\Typo3PhpDatasets\Converter\Csv;
|
||||||
|
use GlobIterator;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \Codappix\Typo3PhpDatasets\Converter\Csv
|
||||||
|
* @testdox The CSV converter
|
||||||
|
*/
|
||||||
|
class CsvTest extends TestCase
|
||||||
|
{
|
||||||
|
protected function tearDown(): void
|
||||||
|
{
|
||||||
|
$filesToDelete = new GlobIterator(__DIR__ . '/Fixtures/Csv/*Incoming.php');
|
||||||
|
foreach ($filesToDelete as $file) {
|
||||||
|
unlink((string)$file);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function canBeCreated(): void
|
||||||
|
{
|
||||||
|
$subject = new Csv();
|
||||||
|
|
||||||
|
self::assertInstanceOf(
|
||||||
|
Csv::class,
|
||||||
|
$subject
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
*/
|
||||||
|
public function throwsExceptionForNoneExistingFile(): void
|
||||||
|
{
|
||||||
|
$subject = new Csv();
|
||||||
|
$this->expectException(InvalidArgumentException::class);
|
||||||
|
$this->expectExceptionCode(1681283739);
|
||||||
|
$this->expectExceptionMessage('Given file "NoneExistingFile.csv" does not exist.');
|
||||||
|
$subject->convert('NoneExistingFile.csv');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @dataProvider possibleCsvFiles
|
||||||
|
* @testdox Converts $_dataName CSV to PHP
|
||||||
|
*/
|
||||||
|
public function convertsCsvFileToPhpFile(
|
||||||
|
string $incomingCsvFile,
|
||||||
|
string $expectedResultFile
|
||||||
|
): void {
|
||||||
|
$subject = new Csv();
|
||||||
|
$result = $subject->convert($incomingCsvFile);
|
||||||
|
|
||||||
|
self::assertFileEquals($expectedResultFile, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function possibleCsvFiles(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'Simple' => [
|
||||||
|
'incomingCsvFile' => __DIR__ . '/Fixtures/Csv/SimpleIncoming.csv',
|
||||||
|
'expectedResultFile' => __DIR__ . '/Fixtures/Csv/SimpleAssert.php',
|
||||||
|
],
|
||||||
|
'Multiple records in single table' => [
|
||||||
|
'incomingCsvFile' => __DIR__ . '/Fixtures/Csv/MultipleRecordsInSingleTableIncoming.csv',
|
||||||
|
'expectedResultFile' => __DIR__ . '/Fixtures/Csv/MultipleRecordsInSingleTableAssert.php',
|
||||||
|
],
|
||||||
|
'Records in different tables' => [
|
||||||
|
'incomingCsvFile' => __DIR__ . '/Fixtures/Csv/RecordsInDifferentTablesIncoming.csv',
|
||||||
|
'expectedResultFile' => __DIR__ . '/Fixtures/Csv/RecordsInDifferentTablesAssert.php',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return array (
|
||||||
|
'pages' =>
|
||||||
|
array (
|
||||||
|
0 =>
|
||||||
|
array (
|
||||||
|
'uid' => '1',
|
||||||
|
'pid' => '0',
|
||||||
|
'title' => 'Page with uid 1 below 0',
|
||||||
|
'deleted' => '0',
|
||||||
|
),
|
||||||
|
1 =>
|
||||||
|
array (
|
||||||
|
'uid' => '2',
|
||||||
|
'pid' => '1',
|
||||||
|
'title' => 'Page with uid 2 below 1',
|
||||||
|
'deleted' => '0',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
|
@ -0,0 +1,4 @@
|
||||||
|
pages
|
||||||
|
,uid,pid,title,deleted
|
||||||
|
,1,0,Page with uid 1 below 0,0
|
||||||
|
,2,1,Page with uid 2 below 1,0
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return array (
|
||||||
|
'pages' =>
|
||||||
|
array (
|
||||||
|
0 =>
|
||||||
|
array (
|
||||||
|
'uid' => '1',
|
||||||
|
'pid' => '0',
|
||||||
|
'title' => 'Page with uid 1 below 0',
|
||||||
|
'deleted' => '0',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'tt_content' =>
|
||||||
|
array (
|
||||||
|
0 =>
|
||||||
|
array (
|
||||||
|
'uid' => '1',
|
||||||
|
'pid' => '1',
|
||||||
|
'header' => 'Content with uid 1 on page 1',
|
||||||
|
'deleted' => '0',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
|
@ -0,0 +1,6 @@
|
||||||
|
pages
|
||||||
|
,uid,pid,title,deleted
|
||||||
|
,1,0,Page with uid 1 below 0,0
|
||||||
|
tt_content
|
||||||
|
,uid,pid,header,deleted
|
||||||
|
,1,1,Content with uid 1 on page 1,0
|
|
14
Tests/Functional/Converter/Fixtures/Csv/SimpleAssert.php
Normal file
14
Tests/Functional/Converter/Fixtures/Csv/SimpleAssert.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return array (
|
||||||
|
'pages' =>
|
||||||
|
array (
|
||||||
|
0 =>
|
||||||
|
array (
|
||||||
|
'uid' => '1',
|
||||||
|
'pid' => '0',
|
||||||
|
'title' => 'Page with uid 1 below 0',
|
||||||
|
'deleted' => '0',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
|
@ -0,0 +1,3 @@
|
||||||
|
pages
|
||||||
|
,uid,pid,title,deleted
|
||||||
|
,1,0,Page with uid 1 below 0,0
|
|
|
@ -3,11 +3,13 @@
|
||||||
|
|
||||||
require $_composer_autoload_path ?? __DIR__ . '/../vendor/autoload.php';
|
require $_composer_autoload_path ?? __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
use Codappix\Typo3PhpDatasets\Command\ConvertFromCsv;
|
||||||
use Codappix\Typo3PhpDatasets\Command\ConvertFromXml;
|
use Codappix\Typo3PhpDatasets\Command\ConvertFromXml;
|
||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\Console\Application;
|
||||||
|
|
||||||
$application = new Application();
|
$application = new Application();
|
||||||
|
|
||||||
$application->add(new ConvertFromXml());
|
$application->add(new ConvertFromXml());
|
||||||
|
$application->add(new ConvertFromCsv());
|
||||||
|
|
||||||
$application->run();
|
$application->run();
|
||||||
|
|
Loading…
Reference in a new issue