Consolidate class naming scheme
This commit is contained in:
parent
c0321ab38d
commit
647e2ac007
|
@ -25,7 +25,9 @@ namespace OCC\OaiPmh2;
|
||||||
use Symfony\Component\Console\Application;
|
use Symfony\Component\Console\Application;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
use Symfony\Component\Console\Input\ArrayInput;
|
use Symfony\Component\Console\Input\ArrayInput;
|
||||||
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\NullOutput;
|
use Symfony\Component\Console\Output\NullOutput;
|
||||||
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all OAI-PMH console commands.
|
* Base class for all OAI-PMH console commands.
|
||||||
|
@ -33,7 +35,7 @@ use Symfony\Component\Console\Output\NullOutput;
|
||||||
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
|
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
|
||||||
* @package opencultureconsulting/oai-pmh2
|
* @package opencultureconsulting/oai-pmh2
|
||||||
*/
|
*/
|
||||||
abstract class ConsoleCommand extends Command
|
abstract class Console extends Command
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Clears the result cache.
|
* Clears the result cache.
|
||||||
|
@ -76,4 +78,43 @@ abstract class ConsoleCommand extends Command
|
||||||
}
|
}
|
||||||
return $limit;
|
return $limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate input arguments.
|
||||||
|
*
|
||||||
|
* @param InputInterface $input The inputs
|
||||||
|
* @param OutputInterface $output The output interface
|
||||||
|
*
|
||||||
|
* @return bool Whether the inputs validate
|
||||||
|
*/
|
||||||
|
protected function validateInput(InputInterface $input, OutputInterface $output): bool
|
||||||
|
{
|
||||||
|
/** @var array<string, string> */
|
||||||
|
$arguments = $input->getArguments();
|
||||||
|
|
||||||
|
$formats = Database::getInstance()->getMetadataFormats()->getQueryResult();
|
||||||
|
if (!in_array($arguments['format'], array_keys($formats), true)) {
|
||||||
|
$output->writeln([
|
||||||
|
'',
|
||||||
|
sprintf(
|
||||||
|
' [ERROR] Metadata format "%s" is not supported. ',
|
||||||
|
$arguments['format']
|
||||||
|
),
|
||||||
|
''
|
||||||
|
]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!is_readable($arguments['file'])) {
|
||||||
|
$output->writeln([
|
||||||
|
'',
|
||||||
|
sprintf(
|
||||||
|
' [ERROR] File "%s" not found or not readable. ',
|
||||||
|
$arguments['file']
|
||||||
|
),
|
||||||
|
''
|
||||||
|
]);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -22,10 +22,11 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCC\OaiPmh2\Console;
|
namespace OCC\OaiPmh2\Console;
|
||||||
|
|
||||||
use OCC\OaiPmh2\ConsoleCommand;
|
use OCC\OaiPmh2\Console;
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use OCC\OaiPmh2\Database\Format;
|
use OCC\OaiPmh2\Entity\Format;
|
||||||
use OCC\OaiPmh2\Database\Record;
|
use OCC\OaiPmh2\Entity\Record;
|
||||||
|
use OCC\OaiPmh2\Entity\Set;
|
||||||
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\InputArgument;
|
||||||
|
@ -42,7 +43,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||||
name: 'oai:records:add',
|
name: 'oai:records:add',
|
||||||
description: 'Add or update a record in the database'
|
description: 'Add or update a record in the database'
|
||||||
)]
|
)]
|
||||||
class AddRecordCommand extends ConsoleCommand
|
class AddRecordCommand extends Console
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Configures the current command.
|
* Configures the current command.
|
||||||
|
@ -84,29 +85,29 @@ class AddRecordCommand extends ConsoleCommand
|
||||||
*/
|
*/
|
||||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||||
{
|
{
|
||||||
/** @var array<string, string> */
|
if (!$this->validateInput($input, $output)) {
|
||||||
$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;
|
return Command::INVALID;
|
||||||
}
|
}
|
||||||
|
/** @var string */
|
||||||
|
$identifier = $input->getArgument('identifier');
|
||||||
|
/** @var Format */
|
||||||
|
$format = Database::getInstance()->getEntityManager()->getReference(Format::class, $input->getArgument('format'));
|
||||||
|
/** @var string */
|
||||||
|
$file = $input->getArgument('file');
|
||||||
|
/** @var string[] */
|
||||||
|
$sets = $input->getArgument('sets');
|
||||||
|
/** @var string */
|
||||||
|
$content = file_get_contents($file);
|
||||||
|
|
||||||
$record = new Record($arguments['identifier'], $format);
|
$record = new Record($identifier, $format);
|
||||||
if (trim($content) !== '') {
|
if (trim($content) !== '') {
|
||||||
$record->setContent($content);
|
$record->setContent($content);
|
||||||
}
|
}
|
||||||
// TODO: Add full set support.
|
foreach ($sets as $set) {
|
||||||
|
/** @var Set */
|
||||||
|
$setSpec = Database::getInstance()->getEntityManager()->getReference(Set::class, $set);
|
||||||
|
$record->addSet($setSpec);
|
||||||
|
}
|
||||||
|
|
||||||
Database::getInstance()->addOrUpdateRecord($record);
|
Database::getInstance()->addOrUpdateRecord($record);
|
||||||
Database::getInstance()->pruneOrphanSets();
|
Database::getInstance()->pruneOrphanSets();
|
||||||
|
@ -117,8 +118,8 @@ class AddRecordCommand extends ConsoleCommand
|
||||||
'',
|
'',
|
||||||
sprintf(
|
sprintf(
|
||||||
' [OK] Record "%s" with metadata prefix "%s" added or updated successfully! ',
|
' [OK] Record "%s" with metadata prefix "%s" added or updated successfully! ',
|
||||||
$arguments['identifier'],
|
$identifier,
|
||||||
$arguments['format']
|
$format->getPrefix()
|
||||||
),
|
),
|
||||||
''
|
''
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -23,10 +23,11 @@ declare(strict_types=1);
|
||||||
namespace OCC\OaiPmh2\Console;
|
namespace OCC\OaiPmh2\Console;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use OCC\OaiPmh2\ConsoleCommand;
|
use OCC\OaiPmh2\Console;
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use OCC\OaiPmh2\Database\Format;
|
use OCC\OaiPmh2\Entity\Format;
|
||||||
use OCC\OaiPmh2\Database\Record;
|
use OCC\OaiPmh2\Entity\Record;
|
||||||
|
use OCC\OaiPmh2\Entity\Set;
|
||||||
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\Helper\ProgressIndicator;
|
use Symfony\Component\Console\Helper\ProgressIndicator;
|
||||||
|
@ -45,7 +46,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||||
name: 'oai:records:import:csv',
|
name: 'oai:records:import:csv',
|
||||||
description: 'Import records from a CSV file'
|
description: 'Import records from a CSV file'
|
||||||
)]
|
)]
|
||||||
class CsvImportCommand extends ConsoleCommand
|
class CsvImportCommand extends Console
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Configures the current command.
|
* Configures the current command.
|
||||||
|
@ -93,7 +94,7 @@ class CsvImportCommand extends ConsoleCommand
|
||||||
'setColumn',
|
'setColumn',
|
||||||
's',
|
's',
|
||||||
InputOption::VALUE_OPTIONAL,
|
InputOption::VALUE_OPTIONAL,
|
||||||
'Name of the CSV column which holds the records\' sets list.',
|
'Name of the CSV column which holds the comma-separated list of the records\' sets.',
|
||||||
'sets'
|
'sets'
|
||||||
);
|
);
|
||||||
$this->addOption(
|
$this->addOption(
|
||||||
|
@ -148,7 +149,12 @@ class CsvImportCommand extends ConsoleCommand
|
||||||
if (strlen(trim($row[$columns['contentColumn']])) > 0) {
|
if (strlen(trim($row[$columns['contentColumn']])) > 0) {
|
||||||
$record->setContent($row[$columns['contentColumn']], !$noValidation);
|
$record->setContent($row[$columns['contentColumn']], !$noValidation);
|
||||||
}
|
}
|
||||||
// TODO: Complete support for sets.
|
$sets = $row[$columns['setColumn']] ?? '';
|
||||||
|
foreach (explode(',', trim($sets)) as $set) {
|
||||||
|
/** @var Set */
|
||||||
|
$setSpec = Database::getInstance()->getEntityManager()->getReference(Set::class, $set);
|
||||||
|
$record->addSet($setSpec);
|
||||||
|
}
|
||||||
Database::getInstance()->addOrUpdateRecord($record, true);
|
Database::getInstance()->addOrUpdateRecord($record, true);
|
||||||
|
|
||||||
++$count;
|
++$count;
|
||||||
|
@ -230,43 +236,4 @@ class CsvImportCommand extends ConsoleCommand
|
||||||
}
|
}
|
||||||
return $columns;
|
return $columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate input arguments.
|
|
||||||
*
|
|
||||||
* @param InputInterface $input The inputs
|
|
||||||
* @param OutputInterface $output The output interface
|
|
||||||
*
|
|
||||||
* @return bool Whether the inputs validate
|
|
||||||
*/
|
|
||||||
protected function validateInput(InputInterface $input, OutputInterface $output): bool
|
|
||||||
{
|
|
||||||
/** @var array<string, string> */
|
|
||||||
$arguments = $input->getArguments();
|
|
||||||
|
|
||||||
$formats = Database::getInstance()->getMetadataFormats()->getQueryResult();
|
|
||||||
if (!in_array($arguments['format'], array_keys($formats), true)) {
|
|
||||||
$output->writeln([
|
|
||||||
'',
|
|
||||||
sprintf(
|
|
||||||
' [ERROR] Metadata format "%s" is not supported. ',
|
|
||||||
$arguments['format']
|
|
||||||
),
|
|
||||||
''
|
|
||||||
]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!is_readable($arguments['file'])) {
|
|
||||||
$output->writeln([
|
|
||||||
'',
|
|
||||||
sprintf(
|
|
||||||
' [ERROR] File "%s" not found or not readable. ',
|
|
||||||
$arguments['file']
|
|
||||||
),
|
|
||||||
''
|
|
||||||
]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,10 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCC\OaiPmh2\Console;
|
namespace OCC\OaiPmh2\Console;
|
||||||
|
|
||||||
use OCC\OaiPmh2\ConsoleCommand;
|
use OCC\OaiPmh2\Console;
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use OCC\OaiPmh2\Database\Format;
|
use OCC\OaiPmh2\Entity\Format;
|
||||||
use OCC\OaiPmh2\Database\Record;
|
use OCC\OaiPmh2\Entity\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\InputArgument;
|
||||||
|
@ -42,7 +42,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||||
name: 'oai:records:delete',
|
name: 'oai:records:delete',
|
||||||
description: 'Delete a record from database'
|
description: 'Delete a record from database'
|
||||||
)]
|
)]
|
||||||
class DeleteRecordCommand extends ConsoleCommand
|
class DeleteRecordCommand extends Console
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Configures the current command.
|
* Configures the current command.
|
||||||
|
|
|
@ -23,7 +23,7 @@ declare(strict_types=1);
|
||||||
namespace OCC\OaiPmh2\Console;
|
namespace OCC\OaiPmh2\Console;
|
||||||
|
|
||||||
use OCC\OaiPmh2\Configuration;
|
use OCC\OaiPmh2\Configuration;
|
||||||
use OCC\OaiPmh2\ConsoleCommand;
|
use OCC\OaiPmh2\Console;
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
@ -41,7 +41,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||||
name: 'oai:records:prune',
|
name: 'oai:records:prune',
|
||||||
description: 'Prune deleted records from database'
|
description: 'Prune deleted records from database'
|
||||||
)]
|
)]
|
||||||
class PruneDeletedRecordsCommand extends ConsoleCommand
|
class PruneDeletedRecordsCommand extends Console
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Configures the current command.
|
* Configures the current command.
|
||||||
|
|
|
@ -22,7 +22,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCC\OaiPmh2\Console;
|
namespace OCC\OaiPmh2\Console;
|
||||||
|
|
||||||
use OCC\OaiPmh2\ConsoleCommand;
|
use OCC\OaiPmh2\Console;
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use Symfony\Component\Console\Attribute\AsCommand;
|
use Symfony\Component\Console\Attribute\AsCommand;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
@ -39,7 +39,7 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||||
name: 'oai:tokens:prune',
|
name: 'oai:tokens:prune',
|
||||||
description: 'Prune expired resumption tokens from database'
|
description: 'Prune expired resumption tokens from database'
|
||||||
)]
|
)]
|
||||||
class PruneResumptionTokensCommand extends ConsoleCommand
|
class PruneResumptionTokensCommand extends Console
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Executes the current command.
|
* Executes the current command.
|
||||||
|
|
|
@ -23,9 +23,9 @@ declare(strict_types=1);
|
||||||
namespace OCC\OaiPmh2\Console;
|
namespace OCC\OaiPmh2\Console;
|
||||||
|
|
||||||
use OCC\OaiPmh2\Configuration;
|
use OCC\OaiPmh2\Configuration;
|
||||||
use OCC\OaiPmh2\ConsoleCommand;
|
use OCC\OaiPmh2\Console;
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use OCC\OaiPmh2\Database\Format;
|
use OCC\OaiPmh2\Entity\Format;
|
||||||
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\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
|
@ -42,7 +42,7 @@ use Symfony\Component\Validator\Exception\ValidationFailedException;
|
||||||
name: 'oai:formats:update',
|
name: 'oai:formats:update',
|
||||||
description: 'Update metadata formats in database from configuration'
|
description: 'Update metadata formats in database from configuration'
|
||||||
)]
|
)]
|
||||||
class UpdateFormatsCommand extends ConsoleCommand
|
class UpdateFormatsCommand extends Console
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Executes the current command.
|
* Executes the current command.
|
||||||
|
|
|
@ -34,11 +34,11 @@ use Doctrine\ORM\Mapping\Driver\AttributeDriver;
|
||||||
use Doctrine\ORM\Proxy\ProxyFactory;
|
use Doctrine\ORM\Proxy\ProxyFactory;
|
||||||
use Doctrine\ORM\Tools\Pagination\Paginator;
|
use Doctrine\ORM\Tools\Pagination\Paginator;
|
||||||
use OCC\Basics\Traits\Singleton;
|
use OCC\Basics\Traits\Singleton;
|
||||||
use OCC\OaiPmh2\Database\Format;
|
use OCC\OaiPmh2\Entity\Format;
|
||||||
use OCC\OaiPmh2\Database\Record;
|
use OCC\OaiPmh2\Entity\Record;
|
||||||
use OCC\OaiPmh2\Database\Result;
|
use OCC\OaiPmh2\Entity\Set;
|
||||||
use OCC\OaiPmh2\Database\Set;
|
use OCC\OaiPmh2\Entity\Token;
|
||||||
use OCC\OaiPmh2\Database\Token;
|
use OCC\OaiPmh2\Result;
|
||||||
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
|
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
|
||||||
use Symfony\Component\Filesystem\Path;
|
use Symfony\Component\Filesystem\Path;
|
||||||
|
|
||||||
|
@ -485,10 +485,10 @@ class Database
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$configuration->setMetadataDriverImpl(
|
$configuration->setMetadataDriverImpl(
|
||||||
new AttributeDriver([__DIR__ . '/Database'])
|
new AttributeDriver([__DIR__ . '/Entity'])
|
||||||
);
|
);
|
||||||
$configuration->setProxyDir(__DIR__ . '/../var/generated');
|
$configuration->setProxyDir(__DIR__ . '/../var/generated');
|
||||||
$configuration->setProxyNamespace('OCC\OaiPmh2\Database\Proxy');
|
$configuration->setProxyNamespace('OCC\OaiPmh2\Entity\Proxy');
|
||||||
$configuration->setQueryCache(
|
$configuration->setQueryCache(
|
||||||
new PhpFilesAdapter(
|
new PhpFilesAdapter(
|
||||||
'Query',
|
'Query',
|
||||||
|
|
|
@ -28,7 +28,6 @@ use DOMException;
|
||||||
use DOMNode;
|
use DOMNode;
|
||||||
use GuzzleHttp\Psr7\Uri;
|
use GuzzleHttp\Psr7\Uri;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Psr\Http\Message\UriInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An OAI-PMH XML response object.
|
* An OAI-PMH XML response object.
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OAI-PMH 2.0 Data Provider
|
||||||
|
* Copyright (C) 2023 Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace OCC\OaiPmh2;
|
||||||
|
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use Symfony\Component\Validator\Exception\ValidationFailedException;
|
||||||
|
use Symfony\Component\Validator\Validation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for all Doctrine/ORM entities.
|
||||||
|
*
|
||||||
|
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
|
||||||
|
* @package opencultureconsulting/oai-pmh2
|
||||||
|
*/
|
||||||
|
abstract class Entity
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check if a string does not contain any whitespaces.
|
||||||
|
*
|
||||||
|
* @param string $string The string
|
||||||
|
*
|
||||||
|
* @return string The validated string
|
||||||
|
*
|
||||||
|
* @throws ValidationFailedException
|
||||||
|
*/
|
||||||
|
protected function validateNoWhitespace(string $string): string
|
||||||
|
{
|
||||||
|
$string = trim($string);
|
||||||
|
$validator = Validation::createValidator();
|
||||||
|
$violations = $validator->validate(
|
||||||
|
$string,
|
||||||
|
[
|
||||||
|
new Assert\Regex([
|
||||||
|
'pattern' => '/\s/',
|
||||||
|
'match' => false,
|
||||||
|
'message' => 'This value contains whitespaces.'
|
||||||
|
]),
|
||||||
|
new Assert\NotBlank()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
if ($violations->count() > 0) {
|
||||||
|
throw new ValidationFailedException(null, $violations);
|
||||||
|
}
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a string is a valid URI.
|
||||||
|
*
|
||||||
|
* @param string $uri The URI
|
||||||
|
*
|
||||||
|
* @return string The validated URI
|
||||||
|
*
|
||||||
|
* @throws ValidationFailedException
|
||||||
|
*/
|
||||||
|
protected function validateUri(string $uri): string
|
||||||
|
{
|
||||||
|
$uri = trim($uri);
|
||||||
|
$validator = Validation::createValidator();
|
||||||
|
$violations = $validator->validate($uri, new Assert\Url());
|
||||||
|
if ($violations->count() > 0) {
|
||||||
|
throw new ValidationFailedException(null, $violations);
|
||||||
|
}
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a string is well-formed XML.
|
||||||
|
*
|
||||||
|
* @param string $xml The XML string
|
||||||
|
*
|
||||||
|
* @return string The validated XML string
|
||||||
|
*
|
||||||
|
* @throws ValidationFailedException
|
||||||
|
*/
|
||||||
|
protected function validateXml(string $xml): string
|
||||||
|
{
|
||||||
|
$validator = Validation::createValidator();
|
||||||
|
$violations = $validator->validate(
|
||||||
|
$xml,
|
||||||
|
[
|
||||||
|
new Assert\Type('string'),
|
||||||
|
new Assert\NotBlank()
|
||||||
|
]
|
||||||
|
);
|
||||||
|
if ($violations->count() > 0
|
||||||
|
or simplexml_load_string($xml) === false) {
|
||||||
|
throw new ValidationFailedException(null, $violations);
|
||||||
|
}
|
||||||
|
return $xml;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,12 +20,11 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCC\OaiPmh2\Database;
|
namespace OCC\OaiPmh2\Entity;
|
||||||
|
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use OCC\OaiPmh2\Entity;
|
||||||
use Symfony\Component\Validator\Exception\ValidationFailedException;
|
use Symfony\Component\Validator\Exception\ValidationFailedException;
|
||||||
use Symfony\Component\Validator\Validation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doctrine/ORM Entity for formats.
|
* Doctrine/ORM Entity for formats.
|
||||||
|
@ -35,7 +34,7 @@ use Symfony\Component\Validator\Validation;
|
||||||
*/
|
*/
|
||||||
#[ORM\Entity]
|
#[ORM\Entity]
|
||||||
#[ORM\Table(name: 'formats')]
|
#[ORM\Table(name: 'formats')]
|
||||||
class Format
|
class Format extends Entity
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The unique metadata prefix.
|
* The unique metadata prefix.
|
||||||
|
@ -98,7 +97,7 @@ class Format
|
||||||
public function setNamespace(string $namespace): void
|
public function setNamespace(string $namespace): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->namespace = $this->validateUrl($namespace);
|
$this->namespace = $this->validateUri($namespace);
|
||||||
} catch (ValidationFailedException $exception) {
|
} catch (ValidationFailedException $exception) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
|
@ -116,62 +115,12 @@ class Format
|
||||||
public function setSchema(string $schema): void
|
public function setSchema(string $schema): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->xmlSchema = $this->validateUrl($schema);
|
$this->xmlSchema = $this->validateUri($schema);
|
||||||
} catch (ValidationFailedException $exception) {
|
} catch (ValidationFailedException $exception) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate metadata prefix.
|
|
||||||
*
|
|
||||||
* @param string $prefix The metadata prefix
|
|
||||||
*
|
|
||||||
* @return string The validated prefix
|
|
||||||
*
|
|
||||||
* @throws ValidationFailedException
|
|
||||||
*/
|
|
||||||
protected function validatePrefix(string $prefix): string
|
|
||||||
{
|
|
||||||
$prefix = trim($prefix);
|
|
||||||
$validator = Validation::createValidator();
|
|
||||||
$violations = $validator->validate(
|
|
||||||
$prefix,
|
|
||||||
[
|
|
||||||
new Assert\Regex([
|
|
||||||
'pattern' => '/\s/',
|
|
||||||
'match' => false,
|
|
||||||
'message' => 'This value contains whitespaces.'
|
|
||||||
]),
|
|
||||||
new Assert\NotBlank()
|
|
||||||
]
|
|
||||||
);
|
|
||||||
if ($violations->count() > 0) {
|
|
||||||
throw new ValidationFailedException(null, $violations);
|
|
||||||
}
|
|
||||||
return $prefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate namespace and schema URLs.
|
|
||||||
*
|
|
||||||
* @param string $url The namespace or schema URL
|
|
||||||
*
|
|
||||||
* @return string The validated URL
|
|
||||||
*
|
|
||||||
* @throws ValidationFailedException
|
|
||||||
*/
|
|
||||||
protected function validateUrl(string $url): string
|
|
||||||
{
|
|
||||||
$url = trim($url);
|
|
||||||
$validator = Validation::createValidator();
|
|
||||||
$violations = $validator->validate($url, new Assert\Url());
|
|
||||||
if ($violations->count() > 0) {
|
|
||||||
throw new ValidationFailedException(null, $violations);
|
|
||||||
}
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get new entity of format.
|
* Get new entity of format.
|
||||||
*
|
*
|
||||||
|
@ -184,7 +133,7 @@ class Format
|
||||||
public function __construct(string $prefix, string $namespace, string $schema)
|
public function __construct(string $prefix, string $namespace, string $schema)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->prefix = $this->validatePrefix($prefix);
|
$this->prefix = $this->validateNoWhitespace($prefix);
|
||||||
$this->setNamespace($namespace);
|
$this->setNamespace($namespace);
|
||||||
$this->setSchema($schema);
|
$this->setSchema($schema);
|
||||||
} catch (ValidationFailedException $exception) {
|
} catch (ValidationFailedException $exception) {
|
|
@ -20,15 +20,14 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCC\OaiPmh2\Database;
|
namespace OCC\OaiPmh2\Entity;
|
||||||
|
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use OCC\OaiPmh2\Entity;
|
||||||
use Symfony\Component\Validator\Exception\ValidationFailedException;
|
use Symfony\Component\Validator\Exception\ValidationFailedException;
|
||||||
use Symfony\Component\Validator\Validation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doctrine/ORM Entity for records.
|
* Doctrine/ORM Entity for records.
|
||||||
|
@ -38,7 +37,7 @@ use Symfony\Component\Validator\Validation;
|
||||||
*/
|
*/
|
||||||
#[ORM\Entity]
|
#[ORM\Entity]
|
||||||
#[ORM\Table(name: 'records')]
|
#[ORM\Table(name: 'records')]
|
||||||
class Record
|
class Record extends Entity
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The record identifier.
|
* The record identifier.
|
||||||
|
@ -197,7 +196,7 @@ class Record
|
||||||
$data = trim($data);
|
$data = trim($data);
|
||||||
if ($validate) {
|
if ($validate) {
|
||||||
try {
|
try {
|
||||||
$data = $this->validate($data);
|
$data = $this->validateXml($data);
|
||||||
} catch (ValidationFailedException $exception) {
|
} catch (ValidationFailedException $exception) {
|
||||||
throw $exception;
|
throw $exception;
|
||||||
}
|
}
|
||||||
|
@ -233,32 +232,6 @@ class Record
|
||||||
$this->lastChanged = $dateTime;
|
$this->lastChanged = $dateTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate XML content.
|
|
||||||
*
|
|
||||||
* @param string $xml The XML string
|
|
||||||
*
|
|
||||||
* @return string The validated XML string
|
|
||||||
*
|
|
||||||
* @throws ValidationFailedException
|
|
||||||
*/
|
|
||||||
protected function validate(string $xml): string
|
|
||||||
{
|
|
||||||
$validator = Validation::createValidator();
|
|
||||||
$violations = $validator->validate(
|
|
||||||
$xml,
|
|
||||||
[
|
|
||||||
new Assert\Type('string'),
|
|
||||||
new Assert\NotBlank()
|
|
||||||
]
|
|
||||||
);
|
|
||||||
if ($violations->count() > 0
|
|
||||||
or simplexml_load_string($xml) === false) {
|
|
||||||
throw new ValidationFailedException(null, $violations);
|
|
||||||
}
|
|
||||||
return $xml;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get new entity of record.
|
* Get new entity of record.
|
||||||
*
|
*
|
||||||
|
@ -272,7 +245,7 @@ class Record
|
||||||
public function __construct(string $identifier, Format $format, ?string $data = null, ?DateTime $lastChanged = null)
|
public function __construct(string $identifier, Format $format, ?string $data = null, ?DateTime $lastChanged = null)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->identifier = $identifier;
|
$this->identifier = $this->validateNoWhitespace($identifier);
|
||||||
$this->setFormat($format);
|
$this->setFormat($format);
|
||||||
$this->setContent($data);
|
$this->setContent($data);
|
||||||
$this->setLastChanged($lastChanged);
|
$this->setLastChanged($lastChanged);
|
|
@ -20,14 +20,13 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCC\OaiPmh2\Database;
|
namespace OCC\OaiPmh2\Entity;
|
||||||
|
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Doctrine\Common\Collections\Collection;
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Symfony\Component\Validator\Constraints as Assert;
|
use OCC\OaiPmh2\Entity;
|
||||||
use Symfony\Component\Validator\Exception\ValidationFailedException;
|
use Symfony\Component\Validator\Exception\ValidationFailedException;
|
||||||
use Symfony\Component\Validator\Validation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doctrine/ORM Entity for sets.
|
* Doctrine/ORM Entity for sets.
|
||||||
|
@ -37,7 +36,7 @@ use Symfony\Component\Validator\Validation;
|
||||||
*/
|
*/
|
||||||
#[ORM\Entity]
|
#[ORM\Entity]
|
||||||
#[ORM\Table(name: 'sets')]
|
#[ORM\Table(name: 'sets')]
|
||||||
class Set
|
class Set extends Entity
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The unique set spec.
|
* The unique set spec.
|
||||||
|
@ -152,40 +151,16 @@ class Set
|
||||||
* @param string $description The description
|
* @param string $description The description
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
|
||||||
public function setDescription(string $description): void
|
|
||||||
{
|
|
||||||
$this->description = trim($description);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate set spec.
|
|
||||||
*
|
|
||||||
* @param string $spec The set spec
|
|
||||||
*
|
|
||||||
* @return string The validated spec
|
|
||||||
*
|
*
|
||||||
* @throws ValidationFailedException
|
* @throws ValidationFailedException
|
||||||
*/
|
*/
|
||||||
protected function validate(string $spec): string
|
public function setDescription(string $description): void
|
||||||
{
|
{
|
||||||
$spec = trim($spec);
|
try {
|
||||||
$validator = Validation::createValidator();
|
$this->description = $this->validateXml($description);
|
||||||
$violations = $validator->validate(
|
} catch (ValidationFailedException $exception) {
|
||||||
$spec,
|
throw $exception;
|
||||||
[
|
|
||||||
new Assert\Regex([
|
|
||||||
'pattern' => '/\s/',
|
|
||||||
'match' => false,
|
|
||||||
'message' => 'This value contains whitespaces.'
|
|
||||||
]),
|
|
||||||
new Assert\NotBlank()
|
|
||||||
]
|
|
||||||
);
|
|
||||||
if ($violations->count() > 0) {
|
|
||||||
throw new ValidationFailedException(null, $violations);
|
|
||||||
}
|
}
|
||||||
return $spec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -200,7 +175,7 @@ class Set
|
||||||
public function __construct(string $spec, string $name, string $description = '')
|
public function __construct(string $spec, string $name, string $description = '')
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$this->spec = $this->validate($spec);
|
$this->spec = $this->validateNoWhitespace($spec);
|
||||||
$this->name = trim($name);
|
$this->name = trim($name);
|
||||||
$this->setDescription($description);
|
$this->setDescription($description);
|
||||||
$this->records = new ArrayCollection();
|
$this->records = new ArrayCollection();
|
|
@ -20,12 +20,13 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCC\OaiPmh2\Database;
|
namespace OCC\OaiPmh2\Entity;
|
||||||
|
|
||||||
use DateInterval;
|
use DateInterval;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use OCC\OaiPmh2\Configuration;
|
use OCC\OaiPmh2\Configuration;
|
||||||
|
use OCC\OaiPmh2\Entity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doctrine/ORM Entity for resumption tokens.
|
* Doctrine/ORM Entity for resumption tokens.
|
||||||
|
@ -35,7 +36,7 @@ use OCC\OaiPmh2\Configuration;
|
||||||
*/
|
*/
|
||||||
#[ORM\Entity]
|
#[ORM\Entity]
|
||||||
#[ORM\Table(name: 'tokens')]
|
#[ORM\Table(name: 'tokens')]
|
||||||
class Token
|
class Token extends Entity
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The resumption token.
|
* The resumption token.
|
|
@ -23,8 +23,8 @@ declare(strict_types=1);
|
||||||
namespace OCC\OaiPmh2\Middleware;
|
namespace OCC\OaiPmh2\Middleware;
|
||||||
|
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use OCC\OaiPmh2\Database\Format;
|
|
||||||
use OCC\OaiPmh2\Document;
|
use OCC\OaiPmh2\Document;
|
||||||
|
use OCC\OaiPmh2\Entity\Format;
|
||||||
use OCC\OaiPmh2\Middleware;
|
use OCC\OaiPmh2\Middleware;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ namespace OCC\OaiPmh2\Middleware;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use OCC\OaiPmh2\Configuration;
|
use OCC\OaiPmh2\Configuration;
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use OCC\OaiPmh2\Database\Record;
|
|
||||||
use OCC\OaiPmh2\Document;
|
use OCC\OaiPmh2\Document;
|
||||||
|
use OCC\OaiPmh2\Entity\Record;
|
||||||
use OCC\OaiPmh2\Middleware;
|
use OCC\OaiPmh2\Middleware;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ declare(strict_types=1);
|
||||||
namespace OCC\OaiPmh2\Middleware;
|
namespace OCC\OaiPmh2\Middleware;
|
||||||
|
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use OCC\OaiPmh2\Database\Format;
|
|
||||||
use OCC\OaiPmh2\Document;
|
use OCC\OaiPmh2\Document;
|
||||||
|
use OCC\OaiPmh2\Entity\Format;
|
||||||
use OCC\OaiPmh2\Middleware;
|
use OCC\OaiPmh2\Middleware;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
|
|
|
@ -24,9 +24,8 @@ namespace OCC\OaiPmh2\Middleware;
|
||||||
|
|
||||||
use OCC\OaiPmh2\Configuration;
|
use OCC\OaiPmh2\Configuration;
|
||||||
use OCC\OaiPmh2\Database;
|
use OCC\OaiPmh2\Database;
|
||||||
use OCC\OaiPmh2\Database\Set;
|
|
||||||
use OCC\OaiPmh2\Database\Token;
|
|
||||||
use OCC\OaiPmh2\Document;
|
use OCC\OaiPmh2\Document;
|
||||||
|
use OCC\OaiPmh2\Entity\Set;
|
||||||
use OCC\OaiPmh2\Middleware;
|
use OCC\OaiPmh2\Middleware;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
|
|
||||||
|
@ -92,8 +91,11 @@ class ListSets extends Middleware
|
||||||
$set->appendChild($setName);
|
$set->appendChild($setName);
|
||||||
|
|
||||||
if ($oaiSet->getDescription() !== '') {
|
if ($oaiSet->getDescription() !== '') {
|
||||||
$setDescription = $document->createElement('setDescription', $oaiSet->getDescription());
|
$setDescription = $document->createElement('setDescription');
|
||||||
$set->appendChild($setDescription);
|
$set->appendChild($setDescription);
|
||||||
|
|
||||||
|
$description = $document->importData($oaiSet->getDescription());
|
||||||
|
$setDescription->appendChild($description);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,12 +20,16 @@
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCC\OaiPmh2\Database;
|
namespace OCC\OaiPmh2;
|
||||||
|
|
||||||
use Countable;
|
use Countable;
|
||||||
use Iterator;
|
use Iterator;
|
||||||
use OCC\Basics\InterfaceTraits\Countable as CountableTrait;
|
use OCC\Basics\InterfaceTraits\Countable as CountableTrait;
|
||||||
use OCC\Basics\InterfaceTraits\Iterator as IteratorTrait;
|
use OCC\Basics\InterfaceTraits\Iterator as IteratorTrait;
|
||||||
|
use OCC\OaiPmh2\Entity\Format;
|
||||||
|
use OCC\OaiPmh2\Entity\Record;
|
||||||
|
use OCC\OaiPmh2\Entity\Set;
|
||||||
|
use OCC\OaiPmh2\Entity\Token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A database result set with optional resumption token.
|
* A database result set with optional resumption token.
|
Loading…
Reference in New Issue