2
0
mirror of https://github.com/opencultureconsulting/oai-pmh2.git synced 2025-03-30 00:00:30 +01:00

Update Psalm and fix new issues

This commit is contained in:
Sebastian Meyer 2025-03-21 13:15:34 +01:00
parent 373104fff4
commit cd6d2e038f
27 changed files with 66 additions and 43 deletions

View File

@ -13,7 +13,15 @@
>
<issueHandlers>
<!--
Psalm doesn't recognize some variables always being set because of prior validation.
This is a false-positive caused by Doctrine's EntityManagerDecorator.
-->
<MethodSignatureMismatch>
<errorLevel type="suppress">
<file name="src/EntityManager.php"/>
</errorLevel>
</MethodSignatureMismatch>
<!--
This is a false-positive caused by Doctrine's ArrayCollection.
-->
<PossiblyNullReference>
<errorLevel type="suppress">
@ -30,15 +38,6 @@
-->
<PropertyNotSetInConstructor errorLevel="suppress"/>
<RedundantPropertyInitializationCheck errorLevel="suppress"/>
<!--
We deliberately want to evaluate empty strings as FALSE in those files.
-->
<RiskyTruthyFalsyComparison>
<errorLevel type="suppress">
<file name="src/Console/AddRecordCommand.php"/>
<file name="src/Console/AddSetCommand.php"/>
</errorLevel>
</RiskyTruthyFalsyComparison>
<!--
Those classes are dynamically used depending on the given OAI verb.
@see src/Middleware/Dispatcher.php:95

View File

@ -107,12 +107,12 @@ abstract class Console extends Command
protected function getPhpMemoryLimit(): int
{
if (!isset($this->memoryLimit)) {
$ini = trim(ini_get('memory_limit'));
$limit = (int) $ini;
if ($limit < 0) {
$phpValue = (string) ini_get('memory_limit');
$limit = (int) $phpValue;
if ($limit <= 0) {
return -1;
}
$unit = strtolower($ini[strlen($ini) - 1]);
$unit = strtolower($phpValue[strlen($phpValue) - 1]);
switch ($unit) {
case 'g':
$limit *= 1024;

View File

@ -42,13 +42,14 @@ use Symfony\Component\Console\Output\OutputInterface;
name: 'oai:records:add',
description: 'Add or update a record in the database'
)]
class AddRecordCommand extends Console
final class AddRecordCommand extends Console
{
/**
* Configures the current command.
*
* @return void
*/
#[\Override]
protected function configure(): void
{
$this->addArgument(
@ -82,6 +83,7 @@ class AddRecordCommand extends Console
*
* @return int 0 if everything went fine, or an error code
*/
#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int
{
if (!$this->validateInput($input, $output)) {
@ -90,7 +92,7 @@ class AddRecordCommand extends Console
/** @var Format */
$format = $this->em->getMetadataFormat($this->arguments['format']);
$content = file_get_contents($this->arguments['file']) ?: '';
$content = (string) file_get_contents($this->arguments['file']);
$record = new Record($this->arguments['identifier'], $format);
if (trim($content) !== '') {

View File

@ -40,13 +40,14 @@ use Symfony\Component\Console\Output\OutputInterface;
name: 'oai:sets:add',
description: 'Add or update a set in the database'
)]
class AddSetCommand extends Console
final class AddSetCommand extends Console
{
/**
* Configures the current command.
*
* @return void
*/
#[\Override]
protected function configure(): void
{
$this->addArgument(
@ -79,6 +80,7 @@ class AddSetCommand extends Console
*
* @return int 0 if everything went fine, or an error code
*/
#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int
{
if (!$this->validateInput($input, $output)) {
@ -86,6 +88,7 @@ class AddSetCommand extends Console
}
if (array_key_exists('file', $this->arguments)) {
/** @psalm-suppress RiskyTruthyFalsyComparison */
$description = file_get_contents($this->arguments['file']) ?: null;
}

View File

@ -52,13 +52,14 @@ use Symfony\Component\Console\Output\OutputInterface;
name: 'oai:records:import:csv',
description: 'Import records from a CSV file'
)]
class CsvImportCommand extends Console
final class CsvImportCommand extends Console
{
/**
* Configures the current command.
*
* @return void
*/
#[\Override]
protected function configure(): void
{
$this->addArgument(
@ -120,6 +121,7 @@ class CsvImportCommand extends Console
*
* @return int 0 if everything went fine, or an error code
*/
#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int
{
if (!$this->validateInput($input, $output)) {
@ -226,6 +228,7 @@ class CsvImportCommand extends Console
$headers = array_flip($headers);
$callback = function (string $column) use ($headers): ?int {
/** @psalm-suppress InvalidArgument */
return array_key_exists($column, $headers) ? $headers[$column] : null;
};

View File

@ -39,13 +39,14 @@ use Symfony\Component\Console\Output\OutputInterface;
name: 'oai:records:delete',
description: 'Delete a record while obeying deleted record policy'
)]
class DeleteRecordCommand extends Console
final class DeleteRecordCommand extends Console
{
/**
* Configures the current command.
*
* @return void
*/
#[\Override]
protected function configure(): void
{
$this->addArgument(
@ -69,6 +70,7 @@ class DeleteRecordCommand extends Console
*
* @return int 0 if everything went fine, or an error code
*/
#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int
{
if (!$this->validateInput($input, $output)) {

View File

@ -40,13 +40,14 @@ use Symfony\Component\Console\Output\OutputInterface;
name: 'oai:records:prune',
description: 'Prune deleted records from database'
)]
class PruneDeletedRecordsCommand extends Console
final class PruneDeletedRecordsCommand extends Console
{
/**
* Configures the current command.
*
* @return void
*/
#[\Override]
protected function configure(): void
{
$this->addOption(
@ -66,13 +67,14 @@ class PruneDeletedRecordsCommand extends Console
*
* @return int 0 if everything went fine, or an error code
*/
#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int
{
$policy = Configuration::getInstance()->deletedRecords;
$forced = (bool) $input->getOption('force');
$forced = $input->getOption('force');
if (
$policy === 'no'
or ($policy === 'transient' && $forced)
or ($policy === 'transient' && $forced === true)
) {
$deleted = $this->em->pruneDeletedRecords();
$this->clearResultCache();

View File

@ -38,7 +38,7 @@ use Symfony\Component\Console\Output\OutputInterface;
name: 'oai:tokens:prune',
description: 'Prune expired resumption tokens from database'
)]
class PruneResumptionTokensCommand extends Console
final class PruneResumptionTokensCommand extends Console
{
/**
* Executes the current command.
@ -48,6 +48,7 @@ class PruneResumptionTokensCommand extends Console
*
* @return int 0 if everything went fine, or an error code
*/
#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int
{
$expired = $this->em->pruneExpiredTokens();

View File

@ -41,7 +41,7 @@ use Symfony\Component\Validator\Exception\ValidationFailedException;
name: 'oai:formats:update',
description: 'Update metadata formats in database from configuration'
)]
class UpdateFormatsCommand extends Console
final class UpdateFormatsCommand extends Console
{
/**
* Executes the current command.
@ -51,6 +51,7 @@ class UpdateFormatsCommand extends Console
*
* @return int 0 if everything went fine, or an error code
*/
#[\Override]
protected function execute(InputInterface $input, OutputInterface $output): int
{
$formats = Configuration::getInstance()->metadataPrefix;

View File

@ -37,7 +37,7 @@ use Symfony\Component\Validator\Exception\ValidationFailedException;
*/
#[ORM\Entity(repositoryClass: FormatRepository::class)]
#[ORM\Table(name: 'formats')]
class Format extends Entity
final class Format extends Entity
{
/**
* The unique metadata prefix.

View File

@ -42,7 +42,7 @@ use Symfony\Component\Validator\Exception\ValidationFailedException;
#[ORM\Index(name: 'format_idx', columns: ['format'])]
#[ORM\Index(name: 'last_changed_idx', columns: ['last_changed'])]
#[ORM\Index(name: 'format_last_changed_idx', columns: ['format', 'last_changed'])]
class Record extends Entity
final class Record extends Entity
{
/**
* The record identifier.

View File

@ -37,7 +37,7 @@ use Symfony\Component\Validator\Exception\ValidationFailedException;
*/
#[ORM\Entity(repositoryClass: SetRepository::class)]
#[ORM\Table(name: 'sets')]
class Set extends Entity
final class Set extends Entity
{
/**
* The unique set spec.

View File

@ -40,7 +40,7 @@ use OCC\OaiPmh2\Repository\TokenRepository;
#[ORM\Entity(repositoryClass: TokenRepository::class)]
#[ORM\Table(name: 'tokens')]
#[ORM\Index(name: 'valid_until_idx', columns: ['valid_until'])]
class Token extends Entity
final class Token extends Entity
{
/**
* The resumption token.

View File

@ -205,11 +205,11 @@ final class EntityManager extends EntityManagerDecorator
->setMaxResults($maxRecords);
if (isset($from)) {
$dql->andWhere($dql->expr()->gte('records.lastChanged', ':from'));
$dql->setParameter('from', new DateTime($from));
$dql->setParameter('from', new DateTime($from), 'datetime');
}
if (isset($until)) {
$dql->andWhere($dql->expr()->lte('records.lastChanged', ':until'));
$dql->setParameter('until', new DateTime($until));
$dql->setParameter('until', new DateTime($until), 'datetime');
}
if (isset($set)) {
$dql->innerJoin(
@ -338,7 +338,7 @@ final class EntityManager extends EntityManagerDecorator
public function isValidRecordIdentifier(string $identifier): bool
{
$records = $this->getRepository(Record::class)->findBy(['identifier' => $identifier]);
return (bool) count($records) > 0;
return count($records) > 0;
}
/**
@ -369,7 +369,7 @@ final class EntityManager extends EntityManagerDecorator
$dql = $this->createQueryBuilder();
$dql->delete(Token::class, 'tokens')
->where($dql->expr()->lt('tokens.validUntil', ':now'))
->setParameter('now', new DateTime());
->setParameter('now', new DateTime(), 'datetime');
/** @var int */
return $dql->getQuery()->execute();
}

View File

@ -142,6 +142,7 @@ abstract class Middleware extends AbstractMiddleware
*
* @return ServerRequestInterface The processed server request
*/
#[\Override]
protected function processRequest(ServerRequestInterface $request): ServerRequestInterface
{
/** @var OaiRequestMetadata */
@ -158,6 +159,7 @@ abstract class Middleware extends AbstractMiddleware
*
* @return ResponseInterface The processed response
*/
#[\Override]
protected function processResponse(ResponseInterface $response): ResponseInterface
{
if (!ErrorHandler::getInstance()->hasErrors() && isset($this->preparedResponse)) {

View File

@ -34,7 +34,7 @@ use Psr\Http\Message\ServerRequestInterface;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class Dispatcher extends AbstractMiddleware
final class Dispatcher extends AbstractMiddleware
{
/**
* List of defined OAI-PMH parameters.
@ -85,6 +85,7 @@ class Dispatcher extends AbstractMiddleware
*
* @return ServerRequestInterface The processed server request
*/
#[\Override]
protected function processRequest(ServerRequestInterface $request): ServerRequestInterface
{
$request = $this->getRequestWithAttributes($request);
@ -108,6 +109,7 @@ class Dispatcher extends AbstractMiddleware
*
* @return ResponseInterface The final response
*/
#[\Override]
protected function processResponse(ResponseInterface $response): ResponseInterface
{
// TODO: Add support for content compression

View File

@ -36,7 +36,7 @@ use Psr\Http\Message\StreamInterface;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class ErrorHandler extends AbstractMiddleware
final class ErrorHandler extends AbstractMiddleware
{
use Singleton;
@ -99,6 +99,7 @@ class ErrorHandler extends AbstractMiddleware
*
* @return ResponseInterface The error response
*/
#[\Override]
protected function processResponse(ResponseInterface $response): ResponseInterface
{
if ($this->hasErrors()) {

View File

@ -34,7 +34,7 @@ use Psr\Http\Message\ServerRequestInterface;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class GetRecord extends Middleware
final class GetRecord extends Middleware
{
/**
* Prepare the response body for verb "GetRecord".
@ -43,6 +43,7 @@ class GetRecord extends Middleware
*
* @return void
*/
#[\Override]
protected function prepareResponse(ServerRequestInterface $request): void
{
$oaiRecord = $this->em->getRecord(

View File

@ -36,7 +36,7 @@ use Psr\Http\Message\ServerRequestInterface;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class Identify extends Middleware
final class Identify extends Middleware
{
/**
* Prepare the response body for verb "Identify".
@ -45,6 +45,7 @@ class Identify extends Middleware
*
* @return void
*/
#[\Override]
protected function prepareResponse(ServerRequestInterface $request): void
{
$response = new Response($request);

View File

@ -43,6 +43,7 @@ class ListIdentifiers extends Middleware
*
* @return void
*/
#[\Override]
protected function prepareResponse(ServerRequestInterface $request): void
{
$this->checkResumptionToken();

View File

@ -34,7 +34,7 @@ use Psr\Http\Message\ServerRequestInterface;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class ListMetadataFormats extends Middleware
final class ListMetadataFormats extends Middleware
{
/**
* Prepare the response body for verb "ListMetadataFormats".
@ -43,6 +43,7 @@ class ListMetadataFormats extends Middleware
*
* @return void
*/
#[\Override]
protected function prepareResponse(ServerRequestInterface $request): void
{
$formats = $this->em->getMetadataFormats($this->arguments['identifier']);

View File

@ -30,7 +30,7 @@ namespace OCC\OaiPmh2\Middleware;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class ListRecords extends ListIdentifiers
final class ListRecords extends ListIdentifiers
{
/**
* "ListIdentifiers" and "ListRecords" are practically identical except the

View File

@ -34,7 +34,7 @@ use Psr\Http\Message\ServerRequestInterface;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class ListSets extends Middleware
final class ListSets extends Middleware
{
/**
* Prepare the response body for verb "ListSets".
@ -43,6 +43,7 @@ class ListSets extends Middleware
*
* @return void
*/
#[\Override]
protected function prepareResponse(ServerRequestInterface $request): void
{
$this->checkResumptionToken();

View File

@ -33,7 +33,7 @@ use Symfony\Component\Validator\Validation;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class ConfigurationValidator
final class ConfigurationValidator
{
/**
* Get constraints for configuration array.

View File

@ -33,7 +33,7 @@ use Symfony\Component\Validator\Validation;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class RegExValidator
final class RegExValidator
{
/**
* Get constraints for regular expression.

View File

@ -33,7 +33,7 @@ use Symfony\Component\Validator\Validation;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class UrlValidator
final class UrlValidator
{
/**
* Get constraints for URLs.

View File

@ -34,7 +34,7 @@ use Symfony\Component\Validator\Validation;
* @author Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
* @package OAIPMH2
*/
class XmlValidator
final class XmlValidator
{
/**
* Get constraints for XML.