*
* 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 3 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, see .
*/
declare(strict_types=1);
namespace OCC\OaiPmh2\Console;
use DateTime;
use OCC\OaiPmh2\Database;
use OCC\OaiPmh2\Database\Record;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Import records into database from a CSV file.
*
* @author Sebastian Meyer
* @package opencultureconsulting/oai-pmh2
*/
#[AsCommand(
name: 'oai:records:import:csv',
description: 'Import records from a CSV file'
)]
class CsvImportCommand extends Command
{
protected function configure(): void
{
$this->addArgument(
'format',
InputArgument::REQUIRED,
'The format (metadata prefix) of the records.',
null,
function (): array {
return array_keys(Database::getInstance()->getMetadataFormats()->getQueryResult());
}
);
$this->addArgument(
'file',
InputArgument::REQUIRED,
'The CSV file containing the records.'
);
$this->addOption(
'idColumn',
null,
InputOption::VALUE_OPTIONAL,
'Name of the CSV column which holds the records\' identifier.',
'identifier'
);
$this->addOption(
'contentColumn',
null,
InputOption::VALUE_OPTIONAL,
'Name of the CSV column which holds the records\' content.',
'content'
);
$this->addOption(
'dateColumn',
null,
InputOption::VALUE_OPTIONAL,
'Name of the CSV column which holds the records\' datetime of last change.',
'lastChanged'
);
$this->addOption(
'setColumn',
null,
InputOption::VALUE_OPTIONAL,
'Name of the CSV column which holds the records\' sets list.',
'sets'
);
parent::configure();
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var array */
$arguments = $input->getArguments();
/** @var array */
$options = $input->getOptions();
$formats = Database::getInstance()->getMetadataFormats()->getQueryResult();
if (!in_array($arguments['format'], array_keys($formats), true)) {
// Error: Invalid metadata prefix
echo 1;
return Command::INVALID;
}
$file = fopen($arguments['file'], 'r');
if ($file === false) {
// Error: File not found or not readable
echo 2;
return Command::INVALID;
}
$headers = fgetcsv($file);
if (!is_array($headers)) {
// Error: No CSV
echo 3;
return Command::INVALID;
} else {
$headers = array_flip($headers);
}
$column = [];
foreach ($options as $option => $value) {
if (isset($headers[$value])) {
$column[$option] = $headers[$value];
}
}
if (!isset($column['idColumn']) || !isset($column['contentColumn'])) {
// Error: Required columns missing
echo 4;
return Command::INVALID;
}
$lastChanged = new DateTime();
$count = 0;
while ($record = fgetcsv($file)) {
$identifier = $record[$column['idColumn']];
$content = $record[$column['contentColumn']];
if ($content === '') {
$content = null;
}
if (isset($column['dateColumn'])) {
$lastChanged = new DateTime($record[$column['dateColumn']]);
}
// TODO: Complete support for sets.
$sets = null;
Database::getInstance()->addOrUpdateRecord(
$identifier,
$arguments['format'],
$content,
$lastChanged,
$sets,
true
);
++$count;
if ($count % 500 === 0) {
Database::getInstance()->flush(true);
}
}
Database::getInstance()->flush(true);
$output->writeln([
'',
sprintf(
' [OK] %d records with metadata prefix "%s" were imported successfully! ',
$count,
$arguments['format']
),
''
]);
return Command::SUCCESS;
}
}