Add more commands

This commit is contained in:
Sebastian Meyer 2024-01-06 21:15:11 +01:00
parent 2f2a41f665
commit 08a573852e
6 changed files with 157 additions and 9 deletions

View File

@ -23,8 +23,11 @@ declare(strict_types=1);
namespace OCC\OaiPmh2\Console; namespace OCC\OaiPmh2\Console;
use OCC\OaiPmh2\Database; use OCC\OaiPmh2\Database;
use OCC\OaiPmh2\Database\Format;
use OCC\OaiPmh2\Database\Record;
use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
@ -40,6 +43,36 @@ use Symfony\Component\Console\Output\OutputInterface;
)] )]
class AddRecordCommand extends Command class AddRecordCommand extends Command
{ {
/**
* Configures the current command.
*
* @return void
*/
protected function configure(): void
{
$this->addArgument(
'identifier',
InputArgument::REQUIRED,
'The record identifier.'
);
$this->addArgument(
'format',
InputArgument::REQUIRED,
'The metadata prefix.'
);
$this->addArgument(
'file',
InputArgument::REQUIRED,
'The file containing the record content.'
);
$this->addArgument(
'sets',
InputArgument::IS_ARRAY | InputArgument::OPTIONAL,
'The list of sets to associate the record with.'
);
parent::configure();
}
/** /**
* Executes the current command. * Executes the current command.
* *
@ -50,7 +83,42 @@ class AddRecordCommand extends Command
*/ */
protected function execute(InputInterface $input, OutputInterface $output): int protected function execute(InputInterface $input, OutputInterface $output): int
{ {
/** @var array<string, string> */
$arguments = $input->getArguments();
/** @var Format */
$format = Database::getInstance()->getEntityManager()->getReference(Format::class, $arguments['format']);
$content = file_get_contents($arguments['file']);
if ($content === false) {
$output->writeln([
'',
sprintf(
' [ERROR] File "%s" not found or not readable. ',
$arguments['file']
),
''
]);
return Command::INVALID;
}
$record = new Record($arguments['identifier'], $format);
if (trim($content) !== '') {
$record->setContent($content);
}
// TODO: Add full set support.
Database::getInstance()->addOrUpdateRecord($record);
Database::getInstance()->pruneOrphanSets(); Database::getInstance()->pruneOrphanSets();
$output->writeln([
'',
sprintf(
' [OK] Record "%s" with metadata prefix "%s" added or updated successfully! ',
$arguments['identifier'],
$arguments['format']
),
''
]);
return Command::SUCCESS; return Command::SUCCESS;
} }
} }

View File

@ -24,8 +24,11 @@ namespace OCC\OaiPmh2\Console;
use OCC\OaiPmh2\Configuration; use OCC\OaiPmh2\Configuration;
use OCC\OaiPmh2\Database; use OCC\OaiPmh2\Database;
use OCC\OaiPmh2\Database\Format;
use OCC\OaiPmh2\Database\Record;
use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
@ -41,6 +44,26 @@ use Symfony\Component\Console\Output\OutputInterface;
)] )]
class DeleteRecordCommand extends Command class DeleteRecordCommand extends Command
{ {
/**
* Configures the current command.
*
* @return void
*/
protected function configure(): void
{
$this->addArgument(
'identifier',
InputArgument::REQUIRED,
'The record identifier.'
);
$this->addArgument(
'format',
InputArgument::REQUIRED,
'The metadata prefix.'
);
parent::configure();
}
/** /**
* Executes the current command. * Executes the current command.
* *
@ -51,8 +74,42 @@ class DeleteRecordCommand extends Command
*/ */
protected function execute(InputInterface $input, OutputInterface $output): int protected function execute(InputInterface $input, OutputInterface $output): int
{ {
$policy = Configuration::getInstance()->deletedRecords; /** @var array<string, string> */
Database::getInstance()->pruneOrphanSets(); $arguments = $input->getArguments();
return Command::SUCCESS; $entityManager = Database::getInstance()->getEntityManager();
$format = $entityManager->getReference(Format::class, $arguments['format']);
$record = $entityManager->find(
Record::class,
[
'identifier' => $arguments['identifier'],
'format' => $format
]
);
if (isset($record)) {
Database::getInstance()->deleteRecord($record);
$output->writeln([
'',
sprintf(
' [OK] Record "%s" with metadata prefix "%s" successfully deleted. ',
$arguments['identifier'],
$arguments['format']
),
''
]);
return Command::SUCCESS;
} else {
$output->writeln([
'',
sprintf(
' [ERROR] Record "%s" with metadata prefix "%s" not found. ',
$arguments['identifier'],
$arguments['format']
),
''
]);
return Command::FAILURE;
}
} }
} }

View File

@ -93,7 +93,7 @@ class UpdateFormatsCommand extends Command
} }
foreach (array_keys($inDatabase) as $prefix) { foreach (array_keys($inDatabase) as $prefix) {
if (!in_array($prefix, array_keys($formats), true)) { if (!in_array($prefix, array_keys($formats), true)) {
Database::getInstance()->removeMetadataFormat($inDatabase[$prefix]); Database::getInstance()->deleteMetadataFormat($inDatabase[$prefix]);
++$deleted; ++$deleted;
$output->writeln([ $output->writeln([
sprintf( sprintf(

View File

@ -420,13 +420,13 @@ class Database
} }
/** /**
* Remove metadata format and all associated records. * Delete metadata format and all associated records.
* *
* @param Format $format The metadata format * @param Format $format The metadata format
* *
* @return void * @return void
*/ */
public function removeMetadataFormat(Format $format): void public function deleteMetadataFormat(Format $format): void
{ {
$repository = $this->entityManager->getRepository(Record::class); $repository = $this->entityManager->getRepository(Record::class);
$criteria = Criteria::create()->where(Criteria::expr()->eq('format', $format)); $criteria = Criteria::create()->where(Criteria::expr()->eq('format', $format));
@ -439,6 +439,25 @@ class Database
$this->pruneOrphanSets(); $this->pruneOrphanSets();
} }
/**
* Delete a record.
*
* @param Record $record The record
*
* @return void
*/
public function deleteRecord(Record $record): void
{
if (Configuration::getInstance()->deletedRecords === 'no') {
$this->entityManager->remove($record);
} else {
$record->setContent(null);
$record->setLastChanged(new DateTime());
}
$this->entityManager->flush();
$this->pruneOrphanSets();
}
/** /**
* This is a singleton class, thus the constructor is private. * This is a singleton class, thus the constructor is private.
* *

View File

@ -103,6 +103,7 @@ class Dispatcher extends AbstractMiddleware
{ {
// TODO: Add support for content compression // TODO: Add support for content compression
// https://openarchives.org/OAI/openarchivesprotocol.html#ResponseCompression // https://openarchives.org/OAI/openarchivesprotocol.html#ResponseCompression
// https://github.com/middlewares/encoder
return $response->withHeader('Content-Type', 'text/xml'); return $response->withHeader('Content-Type', 'text/xml');
} }

View File

@ -81,9 +81,12 @@ class Identify extends Middleware
$granularity = $document->createElement('granularity', 'YYYY-MM-DDThh:mm:ssZ'); $granularity = $document->createElement('granularity', 'YYYY-MM-DDThh:mm:ssZ');
$identify->appendChild($granularity); $identify->appendChild($granularity);
// TODO: Add support for content compression // TODO: Implement explicit content compression support.
// $compression = $document->createElement('compression', '...'); // $compressionDeflate = $document->createElement('compression', 'deflate');
// $identify->appendChild($compression); // $identify->appendChild($compressionDeflate);
// $compressionGzip = $document->createElement('compression', 'gzip');
// $identify->appendChild($compressionGzip);
$this->preparedResponse = $document; $this->preparedResponse = $document;
} }