diff --git a/CHANGELOG.md b/CHANGELOG.md index 380c6526..58c396ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this * *Nothing* ### Changed -* *Nothing* +* Update to Shlink PHP coding standard 2.4 ### Deprecated * *Nothing* diff --git a/composer.json b/composer.json index 9a3e067a..3dc9e10b 100644 --- a/composer.json +++ b/composer.json @@ -72,7 +72,7 @@ "phpunit/phpcov": "^10.0", "phpunit/phpunit": "^11.4", "roave/security-advisories": "dev-master", - "shlinkio/php-coding-standard": "~2.3.0", + "shlinkio/php-coding-standard": "~2.4.0", "shlinkio/shlink-test-utils": "^4.1.1", "symfony/var-dumper": "^7.1", "veewee/composer-run-parallel": "^1.4" diff --git a/module/CLI/src/Command/Config/ReadEnvVarCommand.php b/module/CLI/src/Command/Config/ReadEnvVarCommand.php index 1f436eeb..76ec36ae 100644 --- a/module/CLI/src/Command/Config/ReadEnvVarCommand.php +++ b/module/CLI/src/Command/Config/ReadEnvVarCommand.php @@ -26,7 +26,7 @@ class ReadEnvVarCommand extends Command /** @var Closure(string $envVar): mixed */ private readonly Closure $loadEnvVar; - public function __construct(?Closure $loadEnvVar = null) + public function __construct(Closure|null $loadEnvVar = null) { $this->loadEnvVar = $loadEnvVar ?? static fn (string $envVar) => EnvVars::from($envVar)->loadFromEnv(); parent::__construct(); diff --git a/module/CLI/src/Command/Domain/DomainRedirectsCommand.php b/module/CLI/src/Command/Domain/DomainRedirectsCommand.php index c2e5e60d..61e4a93b 100644 --- a/module/CLI/src/Command/Domain/DomainRedirectsCommand.php +++ b/module/CLI/src/Command/Domain/DomainRedirectsCommand.php @@ -74,7 +74,7 @@ class DomainRedirectsCommand extends Command $domainAuthority = $input->getArgument('domain'); $domain = $this->domainService->findByAuthority($domainAuthority); - $ask = static function (string $message, ?string $current) use ($io): ?string { + $ask = static function (string $message, string|null $current) use ($io): string|null { if ($current === null) { return $io->ask(sprintf('%s (Leave empty for no redirect)', $message)); } diff --git a/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php b/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php index fdff2ddc..b6fa5034 100644 --- a/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php +++ b/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php @@ -22,7 +22,7 @@ class CreateShortUrlCommand extends Command { public const NAME = 'short-url:create'; - private ?SymfonyStyle $io; + private SymfonyStyle|null $io; private readonly ShortUrlDataInput $shortUrlDataInput; public function __construct( diff --git a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php index 34ccd57f..d7243dfb 100644 --- a/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php +++ b/module/CLI/src/Command/ShortUrl/ListShortUrlsCommand.php @@ -210,7 +210,7 @@ class ListShortUrlsCommand extends Command return $shortUrls; } - private function processOrderBy(InputInterface $input): ?string + private function processOrderBy(InputInterface $input): string|null { $orderBy = $input->getOption('order-by'); if (empty($orderBy)) { @@ -247,7 +247,7 @@ class ListShortUrlsCommand extends Command $shortUrl->authorApiKey?->__toString() ?? ''; } if ($input->getOption('show-api-key-name')) { - $columnsMap['API Key Name'] = static fn (array $_, ShortUrl $shortUrl): ?string => + $columnsMap['API Key Name'] = static fn (array $_, ShortUrl $shortUrl): string|null => $shortUrl->authorApiKey?->name; } diff --git a/module/CLI/src/Command/Visit/DownloadGeoLiteDbCommand.php b/module/CLI/src/Command/Visit/DownloadGeoLiteDbCommand.php index ac8ee102..41674a79 100644 --- a/module/CLI/src/Command/Visit/DownloadGeoLiteDbCommand.php +++ b/module/CLI/src/Command/Visit/DownloadGeoLiteDbCommand.php @@ -20,7 +20,7 @@ class DownloadGeoLiteDbCommand extends Command { public const NAME = 'visit:download-db'; - private ?ProgressBar $progressBar = null; + private ProgressBar|null $progressBar = null; public function __construct(private GeolocationDbUpdaterInterface $dbUpdater) { diff --git a/module/CLI/src/Exception/GeolocationDbUpdateFailedException.php b/module/CLI/src/Exception/GeolocationDbUpdateFailedException.php index ceb5cbfd..ee31ac82 100644 --- a/module/CLI/src/Exception/GeolocationDbUpdateFailedException.php +++ b/module/CLI/src/Exception/GeolocationDbUpdateFailedException.php @@ -13,12 +13,12 @@ class GeolocationDbUpdateFailedException extends RuntimeException implements Exc { private bool $olderDbExists; - private function __construct(string $message, ?Throwable $previous = null) + private function __construct(string $message, Throwable|null $previous = null) { parent::__construct($message, previous: $previous); } - public static function withOlderDb(?Throwable $prev = null): self + public static function withOlderDb(Throwable|null $prev = null): self { $e = new self( 'An error occurred while updating geolocation database, but an older DB is already present.', @@ -29,7 +29,7 @@ class GeolocationDbUpdateFailedException extends RuntimeException implements Exc return $e; } - public static function withoutOlderDb(?Throwable $prev = null): self + public static function withoutOlderDb(Throwable|null $prev = null): self { $e = new self( 'An error occurred while updating geolocation database, and an older version could not be found.', diff --git a/module/CLI/src/GeoLite/GeolocationDbUpdater.php b/module/CLI/src/GeoLite/GeolocationDbUpdater.php index 85ae1d3a..2abae05b 100644 --- a/module/CLI/src/GeoLite/GeolocationDbUpdater.php +++ b/module/CLI/src/GeoLite/GeolocationDbUpdater.php @@ -40,8 +40,10 @@ class GeolocationDbUpdater implements GeolocationDbUpdaterInterface /** * @throws GeolocationDbUpdateFailedException */ - public function checkDbUpdate(?callable $beforeDownload = null, ?callable $handleProgress = null): GeolocationResult - { + public function checkDbUpdate( + callable|null $beforeDownload = null, + callable|null $handleProgress = null, + ): GeolocationResult { if ($this->trackingOptions->disableTracking || $this->trackingOptions->disableIpTracking) { return GeolocationResult::CHECK_SKIPPED; } @@ -59,7 +61,7 @@ class GeolocationDbUpdater implements GeolocationDbUpdaterInterface /** * @throws GeolocationDbUpdateFailedException */ - private function downloadIfNeeded(?callable $beforeDownload, ?callable $handleProgress): GeolocationResult + private function downloadIfNeeded(callable|null $beforeDownload, callable|null $handleProgress): GeolocationResult { if (! $this->dbUpdater->databaseFileExists()) { return $this->downloadNewDb(false, $beforeDownload, $handleProgress); @@ -105,8 +107,8 @@ class GeolocationDbUpdater implements GeolocationDbUpdaterInterface */ private function downloadNewDb( bool $olderDbExists, - ?callable $beforeDownload, - ?callable $handleProgress, + callable|null $beforeDownload, + callable|null $handleProgress, ): GeolocationResult { if ($beforeDownload !== null) { $beforeDownload($olderDbExists); @@ -124,7 +126,7 @@ class GeolocationDbUpdater implements GeolocationDbUpdaterInterface } } - private function wrapHandleProgressCallback(?callable $handleProgress, bool $olderDbExists): ?callable + private function wrapHandleProgressCallback(callable|null $handleProgress, bool $olderDbExists): callable|null { if ($handleProgress === null) { return null; diff --git a/module/CLI/src/GeoLite/GeolocationDbUpdaterInterface.php b/module/CLI/src/GeoLite/GeolocationDbUpdaterInterface.php index a143abb8..ba0f0e70 100644 --- a/module/CLI/src/GeoLite/GeolocationDbUpdaterInterface.php +++ b/module/CLI/src/GeoLite/GeolocationDbUpdaterInterface.php @@ -12,7 +12,7 @@ interface GeolocationDbUpdaterInterface * @throws GeolocationDbUpdateFailedException */ public function checkDbUpdate( - ?callable $beforeDownload = null, - ?callable $handleProgress = null, + callable|null $beforeDownload = null, + callable|null $handleProgress = null, ): GeolocationResult; } diff --git a/module/CLI/src/Input/DateOption.php b/module/CLI/src/Input/DateOption.php index 6183a6c5..74acc162 100644 --- a/module/CLI/src/Input/DateOption.php +++ b/module/CLI/src/Input/DateOption.php @@ -21,7 +21,7 @@ readonly class DateOption $command->addOption($name, $shortcut, InputOption::VALUE_REQUIRED, $description); } - public function get(InputInterface $input, OutputInterface $output): ?Chronos + public function get(InputInterface $input, OutputInterface $output): Chronos|null { $value = $input->getOption($this->name); if (empty($value) || ! is_string($value)) { diff --git a/module/CLI/src/Input/EndDateOption.php b/module/CLI/src/Input/EndDateOption.php index 8e6df28a..f2073397 100644 --- a/module/CLI/src/Input/EndDateOption.php +++ b/module/CLI/src/Input/EndDateOption.php @@ -23,7 +23,7 @@ readonly final class EndDateOption )); } - public function get(InputInterface $input, OutputInterface $output): ?Chronos + public function get(InputInterface $input, OutputInterface $output): Chronos|null { return $this->dateOption->get($input, $output); } diff --git a/module/CLI/src/Input/ShortUrlDataOption.php b/module/CLI/src/Input/ShortUrlDataOption.php index 9774d8cb..29c41407 100644 --- a/module/CLI/src/Input/ShortUrlDataOption.php +++ b/module/CLI/src/Input/ShortUrlDataOption.php @@ -18,7 +18,7 @@ enum ShortUrlDataOption: string case CRAWLABLE = 'crawlable'; case NO_FORWARD_QUERY = 'no-forward-query'; - public function shortcut(): ?string + public function shortcut(): string|null { return match ($this) { self::TAGS => 't', diff --git a/module/CLI/src/Input/ShortUrlIdentifierInput.php b/module/CLI/src/Input/ShortUrlIdentifierInput.php index c07de779..def03f74 100644 --- a/module/CLI/src/Input/ShortUrlIdentifierInput.php +++ b/module/CLI/src/Input/ShortUrlIdentifierInput.php @@ -19,7 +19,7 @@ readonly final class ShortUrlIdentifierInput ->addOption('domain', 'd', InputOption::VALUE_REQUIRED, $domainDesc); } - public function shortCode(InputInterface $input): ?string + public function shortCode(InputInterface $input): string|null { return $input->getArgument('shortCode'); } diff --git a/module/CLI/src/Input/StartDateOption.php b/module/CLI/src/Input/StartDateOption.php index 6a7857d7..eaef301f 100644 --- a/module/CLI/src/Input/StartDateOption.php +++ b/module/CLI/src/Input/StartDateOption.php @@ -23,7 +23,7 @@ readonly final class StartDateOption )); } - public function get(InputInterface $input, OutputInterface $output): ?Chronos + public function get(InputInterface $input, OutputInterface $output): Chronos|null { return $this->dateOption->get($input, $output); } diff --git a/module/CLI/src/RedirectRule/RedirectRuleHandler.php b/module/CLI/src/RedirectRule/RedirectRuleHandler.php index cb1d3faf..924876fc 100644 --- a/module/CLI/src/RedirectRule/RedirectRuleHandler.php +++ b/module/CLI/src/RedirectRule/RedirectRuleHandler.php @@ -33,7 +33,7 @@ use const STR_PAD_LEFT; class RedirectRuleHandler implements RedirectRuleHandlerInterface { - public function manageRules(StyleInterface $io, ShortUrl $shortUrl, array $rules): ?array + public function manageRules(StyleInterface $io, ShortUrl $shortUrl, array $rules): array|null { $amountOfRules = count($rules); @@ -213,7 +213,7 @@ class RedirectRuleHandler implements RedirectRuleHandlerInterface private function askMandatory(string $message, StyleInterface $io): string { - return $io->ask($message, validator: function (?string $answer): string { + return $io->ask($message, validator: function (string|null $answer): string { if ($answer === null) { throw new InvalidArgumentException('The value is mandatory'); } @@ -223,6 +223,6 @@ class RedirectRuleHandler implements RedirectRuleHandlerInterface private function askOptional(string $message, StyleInterface $io): string { - return $io->ask($message, validator: fn (?string $answer) => $answer === null ? '' : trim($answer)); + return $io->ask($message, validator: fn (string|null $answer) => $answer === null ? '' : trim($answer)); } } diff --git a/module/CLI/src/RedirectRule/RedirectRuleHandlerInterface.php b/module/CLI/src/RedirectRule/RedirectRuleHandlerInterface.php index 16022768..e871bc81 100644 --- a/module/CLI/src/RedirectRule/RedirectRuleHandlerInterface.php +++ b/module/CLI/src/RedirectRule/RedirectRuleHandlerInterface.php @@ -16,5 +16,5 @@ interface RedirectRuleHandlerInterface * @param ShortUrlRedirectRule[] $rules * @return ShortUrlRedirectRule[]|null - A new list of rules to save, or null if no changes should be saved */ - public function manageRules(StyleInterface $io, ShortUrl $shortUrl, array $rules): ?array; + public function manageRules(StyleInterface $io, ShortUrl $shortUrl, array $rules): array|null; } diff --git a/module/CLI/src/Util/ProcessRunner.php b/module/CLI/src/Util/ProcessRunner.php index 5a568dbe..af9577ea 100644 --- a/module/CLI/src/Util/ProcessRunner.php +++ b/module/CLI/src/Util/ProcessRunner.php @@ -20,7 +20,7 @@ class ProcessRunner implements ProcessRunnerInterface { private Closure $createProcess; - public function __construct(private ProcessHelper $helper, ?callable $createProcess = null) + public function __construct(private ProcessHelper $helper, callable|null $createProcess = null) { $this->createProcess = $createProcess !== null ? $createProcess(...) diff --git a/module/CLI/src/Util/ShlinkTable.php b/module/CLI/src/Util/ShlinkTable.php index c421c613..10823734 100644 --- a/module/CLI/src/Util/ShlinkTable.php +++ b/module/CLI/src/Util/ShlinkTable.php @@ -34,8 +34,12 @@ final class ShlinkTable return new self($baseTable); } - public function render(array $headers, array $rows, ?string $footerTitle = null, ?string $headerTitle = null): void - { + public function render( + array $headers, + array $rows, + string|null $footerTitle = null, + string|null $headerTitle = null, + ): void { $style = Table::getStyleDefinition(self::DEFAULT_STYLE_NAME); $style->setFooterTitleFormat(self::TABLE_TITLE_STYLE) ->setHeaderTitleFormat(self::TABLE_TITLE_STYLE); diff --git a/module/CLI/test/Command/Api/InitialApiKeyCommandTest.php b/module/CLI/test/Command/Api/InitialApiKeyCommandTest.php index 482bd36f..e86cf0e5 100644 --- a/module/CLI/test/Command/Api/InitialApiKeyCommandTest.php +++ b/module/CLI/test/Command/Api/InitialApiKeyCommandTest.php @@ -27,8 +27,11 @@ class InitialApiKeyCommandTest extends TestCase } #[Test, DataProvider('provideParams')] - public function initialKeyIsCreatedWithProvidedValue(?ApiKey $result, bool $verbose, string $expectedOutput): void - { + public function initialKeyIsCreatedWithProvidedValue( + ApiKey|null $result, + bool $verbose, + string $expectedOutput, + ): void { $this->apiKeyService->expects($this->once())->method('createInitial')->with('the_key')->willReturn($result); $this->commandTester->execute( diff --git a/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php b/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php index 32240fc5..5215c2bc 100644 --- a/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php +++ b/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php @@ -31,7 +31,7 @@ class DomainRedirectsCommandTest extends TestCase } #[Test, DataProvider('provideDomains')] - public function onlyPlainQuestionsAreAskedForNewDomainsAndDomainsWithNoRedirects(?Domain $domain): void + public function onlyPlainQuestionsAreAskedForNewDomainsAndDomainsWithNoRedirects(Domain|null $domain): void { $domainAuthority = 'my-domain.com'; $this->domainService->expects($this->once())->method('findByAuthority')->with($domainAuthority)->willReturn( diff --git a/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php b/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php index 19c57481..bd694e7c 100644 --- a/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php +++ b/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php @@ -104,7 +104,7 @@ class CreateShortUrlCommandTest extends TestCase } #[Test, DataProvider('provideDomains')] - public function properlyProcessesProvidedDomain(array $input, ?string $expectedDomain): void + public function properlyProcessesProvidedDomain(array $input, string|null $expectedDomain): void { $this->urlShortener->expects($this->once())->method('shorten')->with( $this->callback(function (ShortUrlCreation $meta) use ($expectedDomain) { @@ -128,8 +128,10 @@ class CreateShortUrlCommandTest extends TestCase } #[Test, DataProvider('provideFlags')] - public function urlValidationHasExpectedValueBasedOnProvidedFlags(array $options, ?bool $expectedCrawlable): void - { + public function urlValidationHasExpectedValueBasedOnProvidedFlags( + array $options, + bool|null $expectedCrawlable, + ): void { $shortUrl = ShortUrl::createFake(); $this->urlShortener->expects($this->once())->method('shorten')->with( $this->callback(function (ShortUrlCreation $meta) use ($expectedCrawlable) { diff --git a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php index c1a3ab23..ccdab885 100644 --- a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php +++ b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php @@ -198,12 +198,12 @@ class ListShortUrlsCommandTest extends TestCase #[Test, DataProvider('provideArgs')] public function serviceIsInvokedWithProvidedArgs( array $commandArgs, - ?int $page, - ?string $searchTerm, + int|null $page, + string|null $searchTerm, array $tags, string $tagsMode, - ?string $startDate = null, - ?string $endDate = null, + string|null $startDate = null, + string|null $endDate = null, ): void { $this->shortUrlService->expects($this->once())->method('listShortUrls')->with(ShortUrlsParams::fromRawData([ 'page' => $page, @@ -260,7 +260,7 @@ class ListShortUrlsCommandTest extends TestCase } #[Test, DataProvider('provideOrderBy')] - public function orderByIsProperlyComputed(array $commandArgs, ?string $expectedOrderBy): void + public function orderByIsProperlyComputed(array $commandArgs, string|null $expectedOrderBy): void { $this->shortUrlService->expects($this->once())->method('listShortUrls')->with(ShortUrlsParams::fromRawData([ 'orderBy' => $expectedOrderBy, diff --git a/module/CLI/test/Exception/GeolocationDbUpdateFailedExceptionTest.php b/module/CLI/test/Exception/GeolocationDbUpdateFailedExceptionTest.php index 3196dd04..519ddf02 100644 --- a/module/CLI/test/Exception/GeolocationDbUpdateFailedExceptionTest.php +++ b/module/CLI/test/Exception/GeolocationDbUpdateFailedExceptionTest.php @@ -15,7 +15,7 @@ use Throwable; class GeolocationDbUpdateFailedExceptionTest extends TestCase { #[Test, DataProvider('providePrev')] - public function withOlderDbBuildsException(?Throwable $prev): void + public function withOlderDbBuildsException(Throwable|null $prev): void { $e = GeolocationDbUpdateFailedException::withOlderDb($prev); @@ -29,7 +29,7 @@ class GeolocationDbUpdateFailedExceptionTest extends TestCase } #[Test, DataProvider('providePrev')] - public function withoutOlderDbBuildsException(?Throwable $prev): void + public function withoutOlderDbBuildsException(Throwable|null $prev): void { $e = GeolocationDbUpdateFailedException::withoutOlderDb($prev); diff --git a/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php b/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php index 3b0f452e..c1cd48f5 100644 --- a/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php +++ b/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php @@ -180,7 +180,7 @@ class GeolocationDbUpdaterTest extends TestCase yield 'both' => [new TrackingOptions(disableTracking: true, disableIpTracking: true)]; } - private function geolocationDbUpdater(?TrackingOptions $options = null): GeolocationDbUpdater + private function geolocationDbUpdater(TrackingOptions|null $options = null): GeolocationDbUpdater { $locker = $this->createMock(Lock\LockFactory::class); $locker->method('createLock')->with($this->isType('string'))->willReturn($this->lock); diff --git a/module/CLI/test/RedirectRule/RedirectRuleHandlerTest.php b/module/CLI/test/RedirectRule/RedirectRuleHandlerTest.php index edd1eae3..18713e00 100644 --- a/module/CLI/test/RedirectRule/RedirectRuleHandlerTest.php +++ b/module/CLI/test/RedirectRule/RedirectRuleHandlerTest.php @@ -56,7 +56,7 @@ class RedirectRuleHandlerTest extends TestCase #[Test, DataProvider('provideExitActions')] public function commentIsDisplayedWhenRulesListIsEmpty( RedirectRuleHandlerAction $action, - ?array $expectedResult, + array|null $expectedResult, ): void { $this->io->expects($this->once())->method('choice')->willReturn($action->value); $this->io->expects($this->once())->method('newLine'); diff --git a/module/Core/functions/functions.php b/module/Core/functions/functions.php index f7bd0cdf..00b220e9 100644 --- a/module/Core/functions/functions.php +++ b/module/Core/functions/functions.php @@ -50,7 +50,7 @@ function generateRandomShortCode(int $length, ShortUrlMode $mode = ShortUrlMode: return $nanoIdClient->formattedId($alphabet, $length); } -function parseDateFromQuery(array $query, string $dateName): ?Chronos +function parseDateFromQuery(array $query, string $dateName): Chronos|null { return normalizeOptionalDate(empty($query[$dateName] ?? null) ? null : Chronos::parse($query[$dateName])); } @@ -63,7 +63,7 @@ function parseDateRangeFromQuery(array $query, string $startDateName, string $en return buildDateRange($startDate, $endDate); } -function dateRangeToHumanFriendly(?DateRange $dateRange): string +function dateRangeToHumanFriendly(DateRange|null $dateRange): string { $startDate = $dateRange?->startDate; $endDate = $dateRange?->endDate; @@ -83,7 +83,7 @@ function dateRangeToHumanFriendly(?DateRange $dateRange): string /** * @return ($date is null ? null : Chronos) */ -function normalizeOptionalDate(string|DateTimeInterface|Chronos|null $date): ?Chronos +function normalizeOptionalDate(string|DateTimeInterface|Chronos|null $date): Chronos|null { $parsedDate = match (true) { $date === null || $date instanceof Chronos => $date, @@ -148,7 +148,7 @@ function splitLocale(string $locale): array /** * @param InputFilter $inputFilter */ -function getOptionalIntFromInputFilter(InputFilter $inputFilter, string $fieldName): ?int +function getOptionalIntFromInputFilter(InputFilter $inputFilter, string $fieldName): int|null { $value = $inputFilter->getValue($fieldName); return $value !== null ? (int) $value : null; @@ -157,7 +157,7 @@ function getOptionalIntFromInputFilter(InputFilter $inputFilter, string $fieldNa /** * @param InputFilter $inputFilter */ -function getOptionalBoolFromInputFilter(InputFilter $inputFilter, string $fieldName): ?bool +function getOptionalBoolFromInputFilter(InputFilter $inputFilter, string $fieldName): bool|null { $value = $inputFilter->getValue($fieldName); return $value !== null ? (bool) $value : null; @@ -276,7 +276,7 @@ function enumToString(string $enum): string * Split provided string by comma and return a list of the results. * An empty array is returned if provided value is empty */ -function splitByComma(?string $value): array +function splitByComma(string|null $value): array { if ($value === null || trim($value) === '') { return []; @@ -285,7 +285,7 @@ function splitByComma(?string $value): array return array_map(trim(...), explode(',', $value)); } -function ipAddressFromRequest(ServerRequestInterface $request): ?string +function ipAddressFromRequest(ServerRequestInterface $request): string|null { return $request->getAttribute(IpAddressMiddlewareFactory::REQUEST_ATTR); } diff --git a/module/Core/src/Action/Model/QrCodeParams.php b/module/Core/src/Action/Model/QrCodeParams.php index 46d90056..3be9097e 100644 --- a/module/Core/src/Action/Model/QrCodeParams.php +++ b/module/Core/src/Action/Model/QrCodeParams.php @@ -123,7 +123,7 @@ final class QrCodeParams return self::parseHexColor($bgColor, DEFAULT_QR_CODE_BG_COLOR); } - private static function parseHexColor(string $hexColor, ?string $fallback): Color + private static function parseHexColor(string $hexColor, string|null $fallback): Color { $hexColor = ltrim($hexColor, '#'); if (! ctype_xdigit($hexColor) && $fallback !== null) { diff --git a/module/Core/src/Config/EmptyNotFoundRedirectConfig.php b/module/Core/src/Config/EmptyNotFoundRedirectConfig.php index 6ccb3848..5ec23bc1 100644 --- a/module/Core/src/Config/EmptyNotFoundRedirectConfig.php +++ b/module/Core/src/Config/EmptyNotFoundRedirectConfig.php @@ -6,7 +6,7 @@ namespace Shlinkio\Shlink\Core\Config; final class EmptyNotFoundRedirectConfig implements NotFoundRedirectConfigInterface { - public function invalidShortUrlRedirect(): ?string + public function invalidShortUrlRedirect(): string|null { return null; } @@ -16,7 +16,7 @@ final class EmptyNotFoundRedirectConfig implements NotFoundRedirectConfigInterfa return false; } - public function regular404Redirect(): ?string + public function regular404Redirect(): string|null { return null; } @@ -26,7 +26,7 @@ final class EmptyNotFoundRedirectConfig implements NotFoundRedirectConfigInterfa return false; } - public function baseUrlRedirect(): ?string + public function baseUrlRedirect(): string|null { return null; } diff --git a/module/Core/src/Config/NotFoundRedirectConfigInterface.php b/module/Core/src/Config/NotFoundRedirectConfigInterface.php index bbdfa9c5..46c2c734 100644 --- a/module/Core/src/Config/NotFoundRedirectConfigInterface.php +++ b/module/Core/src/Config/NotFoundRedirectConfigInterface.php @@ -6,15 +6,15 @@ namespace Shlinkio\Shlink\Core\Config; interface NotFoundRedirectConfigInterface { - public function invalidShortUrlRedirect(): ?string; + public function invalidShortUrlRedirect(): string|null; public function hasInvalidShortUrlRedirect(): bool; - public function regular404Redirect(): ?string; + public function regular404Redirect(): string|null; public function hasRegular404Redirect(): bool; - public function baseUrlRedirect(): ?string; + public function baseUrlRedirect(): string|null; public function hasBaseUrlRedirect(): bool; } diff --git a/module/Core/src/Config/NotFoundRedirectResolver.php b/module/Core/src/Config/NotFoundRedirectResolver.php index cfb09c8e..657336c1 100644 --- a/module/Core/src/Config/NotFoundRedirectResolver.php +++ b/module/Core/src/Config/NotFoundRedirectResolver.php @@ -30,7 +30,7 @@ class NotFoundRedirectResolver implements NotFoundRedirectResolverInterface NotFoundType $notFoundType, NotFoundRedirectConfigInterface $config, UriInterface $currentUri, - ): ?ResponseInterface { + ): ResponseInterface|null { $urlToRedirectTo = match (true) { $notFoundType->isBaseUrl() && $config->hasBaseUrlRedirect() => $config->baseUrlRedirect(), $notFoundType->isRegularNotFound() && $config->hasRegular404Redirect() => $config->regular404Redirect(), diff --git a/module/Core/src/Config/NotFoundRedirectResolverInterface.php b/module/Core/src/Config/NotFoundRedirectResolverInterface.php index 6cbdf702..5f214ca9 100644 --- a/module/Core/src/Config/NotFoundRedirectResolverInterface.php +++ b/module/Core/src/Config/NotFoundRedirectResolverInterface.php @@ -14,5 +14,5 @@ interface NotFoundRedirectResolverInterface NotFoundType $notFoundType, NotFoundRedirectConfigInterface $config, UriInterface $currentUri, - ): ?ResponseInterface; + ): ResponseInterface|null; } diff --git a/module/Core/src/Config/NotFoundRedirects.php b/module/Core/src/Config/NotFoundRedirects.php index 48437924..2753d44f 100644 --- a/module/Core/src/Config/NotFoundRedirects.php +++ b/module/Core/src/Config/NotFoundRedirects.php @@ -9,16 +9,16 @@ use JsonSerializable; final class NotFoundRedirects implements JsonSerializable { private function __construct( - public readonly ?string $baseUrlRedirect, - public readonly ?string $regular404Redirect, - public readonly ?string $invalidShortUrlRedirect, + public readonly string|null $baseUrlRedirect, + public readonly string|null $regular404Redirect, + public readonly string|null $invalidShortUrlRedirect, ) { } public static function withRedirects( - ?string $baseUrlRedirect, - ?string $regular404Redirect = null, - ?string $invalidShortUrlRedirect = null, + string|null $baseUrlRedirect, + string|null $regular404Redirect = null, + string|null $invalidShortUrlRedirect = null, ): self { return new self($baseUrlRedirect, $regular404Redirect, $invalidShortUrlRedirect); } diff --git a/module/Core/src/Config/Options/NotFoundRedirectOptions.php b/module/Core/src/Config/Options/NotFoundRedirectOptions.php index e6ef6a24..7c04d077 100644 --- a/module/Core/src/Config/Options/NotFoundRedirectOptions.php +++ b/module/Core/src/Config/Options/NotFoundRedirectOptions.php @@ -10,9 +10,9 @@ use Shlinkio\Shlink\Core\Config\NotFoundRedirectConfigInterface; final readonly class NotFoundRedirectOptions implements NotFoundRedirectConfigInterface { public function __construct( - public ?string $invalidShortUrl = null, - public ?string $regular404 = null, - public ?string $baseUrl = null, + public string|null $invalidShortUrl = null, + public string|null $regular404 = null, + public string|null $baseUrl = null, ) { } @@ -25,7 +25,7 @@ final readonly class NotFoundRedirectOptions implements NotFoundRedirectConfigIn ); } - public function invalidShortUrlRedirect(): ?string + public function invalidShortUrlRedirect(): string|null { return $this->invalidShortUrl; } @@ -35,7 +35,7 @@ final readonly class NotFoundRedirectOptions implements NotFoundRedirectConfigIn return $this->invalidShortUrl !== null; } - public function regular404Redirect(): ?string + public function regular404Redirect(): string|null { return $this->regular404; } @@ -45,7 +45,7 @@ final readonly class NotFoundRedirectOptions implements NotFoundRedirectConfigIn return $this->regular404 !== null; } - public function baseUrlRedirect(): ?string + public function baseUrlRedirect(): string|null { return $this->baseUrl; } diff --git a/module/Core/src/Config/Options/QrCodeOptions.php b/module/Core/src/Config/Options/QrCodeOptions.php index 4d85e6cc..ac864851 100644 --- a/module/Core/src/Config/Options/QrCodeOptions.php +++ b/module/Core/src/Config/Options/QrCodeOptions.php @@ -26,7 +26,7 @@ final readonly class QrCodeOptions public bool $enabledForDisabledShortUrls = DEFAULT_QR_CODE_ENABLED_FOR_DISABLED_SHORT_URLS, public string $color = DEFAULT_QR_CODE_COLOR, public string $bgColor = DEFAULT_QR_CODE_BG_COLOR, - public ?string $logoUrl = null, + public string|null $logoUrl = null, ) { } diff --git a/module/Core/src/Config/Options/TrackingOptions.php b/module/Core/src/Config/Options/TrackingOptions.php index eddfba34..d238bb42 100644 --- a/module/Core/src/Config/Options/TrackingOptions.php +++ b/module/Core/src/Config/Options/TrackingOptions.php @@ -22,7 +22,7 @@ final readonly class TrackingOptions public bool $trackOrphanVisits = true, // A query param that, if provided, will disable tracking of one particular visit. Always takes precedence over // other options - public ?string $disableTrackParam = null, + public string|null $disableTrackParam = null, // If true, visits will not be tracked at all public bool $disableTracking = false, // If true, visits will be tracked, but neither the IP address, nor the location will be resolved diff --git a/module/Core/src/Domain/DomainService.php b/module/Core/src/Domain/DomainService.php index e514af55..18d66328 100644 --- a/module/Core/src/Domain/DomainService.php +++ b/module/Core/src/Domain/DomainService.php @@ -26,7 +26,7 @@ readonly class DomainService implements DomainServiceInterface /** * @return DomainItem[] */ - public function listDomains(?ApiKey $apiKey = null): array + public function listDomains(ApiKey|null $apiKey = null): array { [$default, $domains] = $this->defaultDomainAndRest($apiKey); $mappedDomains = array_map(fn (Domain $domain) => DomainItem::forNonDefaultDomain($domain), $domains); @@ -47,7 +47,7 @@ readonly class DomainService implements DomainServiceInterface /** * @return array{Domain|null, Domain[]} */ - private function defaultDomainAndRest(?ApiKey $apiKey): array + private function defaultDomainAndRest(ApiKey|null $apiKey): array { /** @var DomainRepositoryInterface $repo */ $repo = $this->em->getRepository(Domain::class); @@ -80,7 +80,7 @@ readonly class DomainService implements DomainServiceInterface return $domain; } - public function findByAuthority(string $authority, ?ApiKey $apiKey = null): ?Domain + public function findByAuthority(string $authority, ApiKey|null $apiKey = null): Domain|null { return $this->em->getRepository(Domain::class)->findOneByAuthority($authority, $apiKey); } @@ -88,7 +88,7 @@ readonly class DomainService implements DomainServiceInterface /** * @throws DomainNotFoundException */ - public function getOrCreate(string $authority, ?ApiKey $apiKey = null): Domain + public function getOrCreate(string $authority, ApiKey|null $apiKey = null): Domain { $domain = $this->getPersistedDomain($authority, $apiKey); $this->em->flush(); @@ -102,7 +102,7 @@ readonly class DomainService implements DomainServiceInterface public function configureNotFoundRedirects( string $authority, NotFoundRedirects $notFoundRedirects, - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, ): Domain { $domain = $this->getPersistedDomain($authority, $apiKey); $domain->configureNotFoundRedirects($notFoundRedirects); @@ -115,7 +115,7 @@ readonly class DomainService implements DomainServiceInterface /** * @throws DomainNotFoundException */ - private function getPersistedDomain(string $authority, ?ApiKey $apiKey): Domain + private function getPersistedDomain(string $authority, ApiKey|null $apiKey): Domain { $domain = $this->findByAuthority($authority, $apiKey); if ($domain === null && $apiKey?->hasRole(Role::DOMAIN_SPECIFIC)) { diff --git a/module/Core/src/Domain/DomainServiceInterface.php b/module/Core/src/Domain/DomainServiceInterface.php index 103abbb2..b7f8b3ee 100644 --- a/module/Core/src/Domain/DomainServiceInterface.php +++ b/module/Core/src/Domain/DomainServiceInterface.php @@ -15,7 +15,7 @@ interface DomainServiceInterface /** * @return DomainItem[] */ - public function listDomains(?ApiKey $apiKey = null): array; + public function listDomains(ApiKey|null $apiKey = null): array; /** * @throws DomainNotFoundException @@ -25,9 +25,9 @@ interface DomainServiceInterface /** * @throws DomainNotFoundException If the API key is restricted to one domain and a different one is provided */ - public function getOrCreate(string $authority, ?ApiKey $apiKey = null): Domain; + public function getOrCreate(string $authority, ApiKey|null $apiKey = null): Domain; - public function findByAuthority(string $authority, ?ApiKey $apiKey = null): ?Domain; + public function findByAuthority(string $authority, ApiKey|null $apiKey = null): Domain|null; /** * @throws DomainNotFoundException If the API key is restricted to one domain and a different one is provided @@ -35,6 +35,6 @@ interface DomainServiceInterface public function configureNotFoundRedirects( string $authority, NotFoundRedirects $notFoundRedirects, - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, ): Domain; } diff --git a/module/Core/src/Domain/Entity/Domain.php b/module/Core/src/Domain/Entity/Domain.php index ba3446a7..628335cd 100644 --- a/module/Core/src/Domain/Entity/Domain.php +++ b/module/Core/src/Domain/Entity/Domain.php @@ -15,9 +15,9 @@ class Domain extends AbstractEntity implements JsonSerializable, NotFoundRedirec private function __construct( public readonly string $authority, - private ?string $baseUrlRedirect = null, - private ?string $regular404Redirect = null, - private ?string $invalidShortUrlRedirect = null, + private string|null $baseUrlRedirect = null, + private string|null $regular404Redirect = null, + private string|null $invalidShortUrlRedirect = null, ) { } @@ -31,7 +31,7 @@ class Domain extends AbstractEntity implements JsonSerializable, NotFoundRedirec return $this->authority; } - public function invalidShortUrlRedirect(): ?string + public function invalidShortUrlRedirect(): string|null { return $this->invalidShortUrlRedirect; } @@ -41,7 +41,7 @@ class Domain extends AbstractEntity implements JsonSerializable, NotFoundRedirec return $this->invalidShortUrlRedirect !== null; } - public function regular404Redirect(): ?string + public function regular404Redirect(): string|null { return $this->regular404Redirect; } @@ -51,7 +51,7 @@ class Domain extends AbstractEntity implements JsonSerializable, NotFoundRedirec return $this->regular404Redirect !== null; } - public function baseUrlRedirect(): ?string + public function baseUrlRedirect(): string|null { return $this->baseUrlRedirect; } diff --git a/module/Core/src/Domain/Repository/DomainRepository.php b/module/Core/src/Domain/Repository/DomainRepository.php index fedf4f54..0a1fe40a 100644 --- a/module/Core/src/Domain/Repository/DomainRepository.php +++ b/module/Core/src/Domain/Repository/DomainRepository.php @@ -20,7 +20,7 @@ class DomainRepository extends EntitySpecificationRepository implements DomainRe /** * @return Domain[] */ - public function findDomains(?ApiKey $apiKey = null): array + public function findDomains(ApiKey|null $apiKey = null): array { $qb = $this->createQueryBuilder('d'); $qb->leftJoin(ShortUrl::class, 's', Join::WITH, 's.domain = d') @@ -39,7 +39,7 @@ class DomainRepository extends EntitySpecificationRepository implements DomainRe return $qb->getQuery()->getResult(); } - public function findOneByAuthority(string $authority, ?ApiKey $apiKey = null): ?Domain + public function findOneByAuthority(string $authority, ApiKey|null $apiKey = null): Domain|null { $qb = $this->createDomainQueryBuilder($authority, $apiKey); $qb->select('d'); @@ -47,7 +47,7 @@ class DomainRepository extends EntitySpecificationRepository implements DomainRe return $qb->getQuery()->getOneOrNullResult(); } - public function domainExists(string $authority, ?ApiKey $apiKey = null): bool + public function domainExists(string $authority, ApiKey|null $apiKey = null): bool { $qb = $this->createDomainQueryBuilder($authority, $apiKey); $qb->select('COUNT(d.id)'); @@ -55,7 +55,7 @@ class DomainRepository extends EntitySpecificationRepository implements DomainRe return ((int) $qb->getQuery()->getSingleScalarResult()) > 0; } - private function createDomainQueryBuilder(string $authority, ?ApiKey $apiKey): QueryBuilder + private function createDomainQueryBuilder(string $authority, ApiKey|null $apiKey): QueryBuilder { $qb = $this->getEntityManager()->createQueryBuilder(); $qb->from(Domain::class, 'd') @@ -72,7 +72,7 @@ class DomainRepository extends EntitySpecificationRepository implements DomainRe return $qb; } - private function determineExtraSpecs(?ApiKey $apiKey): iterable + private function determineExtraSpecs(ApiKey|null $apiKey): iterable { // FIXME The $apiKey->spec() method cannot be used here, as it returns a single spec which assumes the // ShortUrl is the root entity. Here, the Domain is the root entity. diff --git a/module/Core/src/Domain/Repository/DomainRepositoryInterface.php b/module/Core/src/Domain/Repository/DomainRepositoryInterface.php index d215e475..cc14bb10 100644 --- a/module/Core/src/Domain/Repository/DomainRepositoryInterface.php +++ b/module/Core/src/Domain/Repository/DomainRepositoryInterface.php @@ -15,9 +15,9 @@ interface DomainRepositoryInterface extends ObjectRepository, EntitySpecificatio /** * @return Domain[] */ - public function findDomains(?ApiKey $apiKey = null): array; + public function findDomains(ApiKey|null $apiKey = null): array; - public function findOneByAuthority(string $authority, ?ApiKey $apiKey = null): ?Domain; + public function findOneByAuthority(string $authority, ApiKey|null $apiKey = null): Domain|null; - public function domainExists(string $authority, ?ApiKey $apiKey = null): bool; + public function domainExists(string $authority, ApiKey|null $apiKey = null): bool; } diff --git a/module/Core/src/Domain/Spec/IsDomain.php b/module/Core/src/Domain/Spec/IsDomain.php index cf7463cc..2c78a85e 100644 --- a/module/Core/src/Domain/Spec/IsDomain.php +++ b/module/Core/src/Domain/Spec/IsDomain.php @@ -10,7 +10,7 @@ use Happyr\DoctrineSpecification\Specification\BaseSpecification; class IsDomain extends BaseSpecification { - public function __construct(private string $domainId, ?string $context = null) + public function __construct(private string $domainId, string|null $context = null) { parent::__construct($context); } diff --git a/module/Core/src/ErrorHandler/Model/NotFoundType.php b/module/Core/src/ErrorHandler/Model/NotFoundType.php index 99f7fbe6..de0c5460 100644 --- a/module/Core/src/ErrorHandler/Model/NotFoundType.php +++ b/module/Core/src/ErrorHandler/Model/NotFoundType.php @@ -13,7 +13,7 @@ use function rtrim; class NotFoundType { - private function __construct(private readonly ?VisitType $type) + private function __construct(private readonly VisitType|null $type) { } diff --git a/module/Core/src/ErrorHandler/NotFoundRedirectHandler.php b/module/Core/src/ErrorHandler/NotFoundRedirectHandler.php index 4e7360d5..f84123c1 100644 --- a/module/Core/src/ErrorHandler/NotFoundRedirectHandler.php +++ b/module/Core/src/ErrorHandler/NotFoundRedirectHandler.php @@ -40,7 +40,7 @@ readonly class NotFoundRedirectHandler implements MiddlewareInterface private function resolveDomainSpecificRedirect( UriInterface $currentUri, NotFoundType $notFoundType, - ): ?ResponseInterface { + ): ResponseInterface|null { $domain = $this->domainService->findByAuthority($currentUri->getAuthority()); if ($domain === null) { return null; diff --git a/module/Core/src/ErrorHandler/NotFoundTemplateHandler.php b/module/Core/src/ErrorHandler/NotFoundTemplateHandler.php index cd0f60be..9b59f886 100644 --- a/module/Core/src/ErrorHandler/NotFoundTemplateHandler.php +++ b/module/Core/src/ErrorHandler/NotFoundTemplateHandler.php @@ -23,7 +23,7 @@ class NotFoundTemplateHandler implements RequestHandlerInterface private Closure $readFile; - public function __construct(?callable $readFile = null) + public function __construct(callable|null $readFile = null) { $this->readFile = $readFile ? Closure::fromCallable($readFile) : fn (string $file) => file_get_contents($file); } diff --git a/module/Core/src/EventDispatcher/Event/AbstractVisitEvent.php b/module/Core/src/EventDispatcher/Event/AbstractVisitEvent.php index 87f7dba2..c1fa440a 100644 --- a/module/Core/src/EventDispatcher/Event/AbstractVisitEvent.php +++ b/module/Core/src/EventDispatcher/Event/AbstractVisitEvent.php @@ -11,7 +11,7 @@ abstract class AbstractVisitEvent implements JsonSerializable, JsonUnserializabl { final public function __construct( public readonly string $visitId, - public readonly ?string $originalIpAddress = null, + public readonly string|null $originalIpAddress = null, ) { } diff --git a/module/Core/src/EventDispatcher/LocateVisit.php b/module/Core/src/EventDispatcher/LocateVisit.php index 6f7fb7e8..d1d0d90a 100644 --- a/module/Core/src/EventDispatcher/LocateVisit.php +++ b/module/Core/src/EventDispatcher/LocateVisit.php @@ -45,7 +45,7 @@ readonly class LocateVisit $this->eventDispatcher->dispatch(new VisitLocated($visitId, $shortUrlVisited->originalIpAddress)); } - private function locateVisit(string $visitId, ?string $originalIpAddress, Visit $visit): void + private function locateVisit(string $visitId, string|null $originalIpAddress, Visit $visit): void { if (! $this->dbUpdater->databaseFileExists()) { $this->logger->warning('Tried to locate visit with id "{visitId}", but a GeoLite2 db was not found.', [ diff --git a/module/Core/src/EventDispatcher/PublishingUpdatesGenerator.php b/module/Core/src/EventDispatcher/PublishingUpdatesGenerator.php index b762af7e..e9437cc3 100644 --- a/module/Core/src/EventDispatcher/PublishingUpdatesGenerator.php +++ b/module/Core/src/EventDispatcher/PublishingUpdatesGenerator.php @@ -48,7 +48,7 @@ final readonly class PublishingUpdatesGenerator implements PublishingUpdatesGene ]); } - private function transformShortUrl(?ShortUrl $shortUrl): array + private function transformShortUrl(ShortUrl|null $shortUrl): array { return $shortUrl === null ? [] : $this->shortUrlTransformer->transform($shortUrl); } diff --git a/module/Core/src/EventDispatcher/Topic.php b/module/Core/src/EventDispatcher/Topic.php index 0cba5a09..8c7a7d45 100644 --- a/module/Core/src/EventDispatcher/Topic.php +++ b/module/Core/src/EventDispatcher/Topic.php @@ -12,7 +12,7 @@ enum Topic: string case NEW_ORPHAN_VISIT = 'https://shlink.io/new-orphan-visit'; case NEW_SHORT_URL = 'https://shlink.io/new-short-url'; - public static function newShortUrlVisit(?string $shortCode): string + public static function newShortUrlVisit(string|null $shortCode): string { return sprintf('%s/%s', self::NEW_VISIT->value, $shortCode ?? ''); } diff --git a/module/Core/src/Exception/IpCannotBeLocatedException.php b/module/Core/src/Exception/IpCannotBeLocatedException.php index 2ebc3e62..d22d341f 100644 --- a/module/Core/src/Exception/IpCannotBeLocatedException.php +++ b/module/Core/src/Exception/IpCannotBeLocatedException.php @@ -13,7 +13,7 @@ class IpCannotBeLocatedException extends RuntimeException string $message, public readonly UnlocatableIpType $type, int $code = 0, - ?Throwable $previous = null, + Throwable|null $previous = null, ) { parent::__construct($message, $code, $previous); } diff --git a/module/Core/src/Exception/NonUniqueSlugException.php b/module/Core/src/Exception/NonUniqueSlugException.php index 5336786c..8f9508a2 100644 --- a/module/Core/src/Exception/NonUniqueSlugException.php +++ b/module/Core/src/Exception/NonUniqueSlugException.php @@ -19,7 +19,7 @@ class NonUniqueSlugException extends InvalidArgumentException implements Problem private const TITLE = 'Invalid custom slug'; public const ERROR_CODE = 'non-unique-slug'; - public static function fromSlug(string $slug, ?string $domain = null): self + public static function fromSlug(string $slug, string|null $domain = null): self { $suffix = $domain === null ? '' : sprintf(' for domain "%s"', $domain); $e = new self(sprintf('Provided slug "%s" is already in use%s.', $slug, $suffix)); diff --git a/module/Core/src/Exception/ValidationException.php b/module/Core/src/Exception/ValidationException.php index 95da6d5e..f81c1d37 100644 --- a/module/Core/src/Exception/ValidationException.php +++ b/module/Core/src/Exception/ValidationException.php @@ -29,12 +29,12 @@ class ValidationException extends InvalidArgumentException implements ProblemDet /** * @param InputFilterInterface $inputFilter */ - public static function fromInputFilter(InputFilterInterface $inputFilter, ?Throwable $prev = null): self + public static function fromInputFilter(InputFilterInterface $inputFilter, Throwable|null $prev = null): self { return static::fromArray($inputFilter->getMessages(), $prev); } - public static function fromArray(array $invalidData, ?Throwable $prev = null): self + public static function fromArray(array $invalidData, Throwable|null $prev = null): self { $status = StatusCodeInterface::STATUS_BAD_REQUEST; $e = new self('Provided data is not valid', $status, $prev); diff --git a/module/Core/src/Matomo/MatomoOptions.php b/module/Core/src/Matomo/MatomoOptions.php index af0ace92..5f47280e 100644 --- a/module/Core/src/Matomo/MatomoOptions.php +++ b/module/Core/src/Matomo/MatomoOptions.php @@ -13,9 +13,9 @@ final readonly class MatomoOptions */ public function __construct( public bool $enabled = false, - public ?string $baseUrl = null, + public string|null $baseUrl = null, private string|int|null $siteId = null, - public ?string $apiToken = null, + public string|null $apiToken = null, ) { } @@ -29,7 +29,7 @@ final readonly class MatomoOptions ); } - public function siteId(): ?int + public function siteId(): int|null { if ($this->siteId === null) { return null; diff --git a/module/Core/src/Matomo/MatomoVisitSender.php b/module/Core/src/Matomo/MatomoVisitSender.php index d2a4484a..9fc0176a 100644 --- a/module/Core/src/Matomo/MatomoVisitSender.php +++ b/module/Core/src/Matomo/MatomoVisitSender.php @@ -45,7 +45,7 @@ readonly class MatomoVisitSender implements MatomoVisitSenderInterface return new SendVisitsResult($successfulVisits, $failedVisits); } - public function sendVisit(Visit $visit, ?string $originalIpAddress = null): void + public function sendVisit(Visit $visit, string|null $originalIpAddress = null): void { $tracker = $this->trackerBuilder->buildMatomoTracker(); diff --git a/module/Core/src/Matomo/MatomoVisitSenderInterface.php b/module/Core/src/Matomo/MatomoVisitSenderInterface.php index e1b1c3cb..6390104c 100644 --- a/module/Core/src/Matomo/MatomoVisitSenderInterface.php +++ b/module/Core/src/Matomo/MatomoVisitSenderInterface.php @@ -18,5 +18,5 @@ interface MatomoVisitSenderInterface VisitSendingProgressTrackerInterface|null $progressTracker = null, ): SendVisitsResult; - public function sendVisit(Visit $visit, ?string $originalIpAddress = null): void; + public function sendVisit(Visit $visit, string|null $originalIpAddress = null): void; } diff --git a/module/Core/src/Model/AbstractInfinitePaginableListParams.php b/module/Core/src/Model/AbstractInfinitePaginableListParams.php index d4b2aaab..70db853e 100644 --- a/module/Core/src/Model/AbstractInfinitePaginableListParams.php +++ b/module/Core/src/Model/AbstractInfinitePaginableListParams.php @@ -13,18 +13,18 @@ abstract class AbstractInfinitePaginableListParams public readonly int $page; public readonly int $itemsPerPage; - protected function __construct(?int $page, ?int $itemsPerPage) + protected function __construct(int|null $page, int|null $itemsPerPage) { $this->page = $this->determinePage($page); $this->itemsPerPage = $this->determineItemsPerPage($itemsPerPage); } - private function determinePage(?int $page): int + private function determinePage(int|null $page): int { return $page === null || $page <= 0 ? self::FIRST_PAGE : $page; } - private function determineItemsPerPage(?int $itemsPerPage): int + private function determineItemsPerPage(int|null $itemsPerPage): int { return $itemsPerPage === null || $itemsPerPage < 0 ? Paginator::ALL_ITEMS : $itemsPerPage; } diff --git a/module/Core/src/Model/DeviceType.php b/module/Core/src/Model/DeviceType.php index 3cd3e132..a4a15cdc 100644 --- a/module/Core/src/Model/DeviceType.php +++ b/module/Core/src/Model/DeviceType.php @@ -10,7 +10,7 @@ enum DeviceType: string case IOS = 'ios'; case DESKTOP = 'desktop'; - public static function matchFromUserAgent(string $userAgent): ?self + public static function matchFromUserAgent(string $userAgent): self|null { $detect = new MobileDetect(); $detect->setUserAgent($userAgent); diff --git a/module/Core/src/Model/Ordering.php b/module/Core/src/Model/Ordering.php index e1b91510..0e0edab7 100644 --- a/module/Core/src/Model/Ordering.php +++ b/module/Core/src/Model/Ordering.php @@ -10,7 +10,7 @@ final readonly class Ordering private const ASC_DIR = 'ASC'; private const DEFAULT_DIR = self::ASC_DIR; - public function __construct(public ?string $field = null, public string $direction = self::DEFAULT_DIR) + public function __construct(public string|null $field = null, public string $direction = self::DEFAULT_DIR) { } diff --git a/module/Core/src/Paginator/Adapter/AbstractCacheableCountPaginatorAdapter.php b/module/Core/src/Paginator/Adapter/AbstractCacheableCountPaginatorAdapter.php index 890c8845..e2a3b414 100644 --- a/module/Core/src/Paginator/Adapter/AbstractCacheableCountPaginatorAdapter.php +++ b/module/Core/src/Paginator/Adapter/AbstractCacheableCountPaginatorAdapter.php @@ -12,7 +12,7 @@ use Pagerfanta\Adapter\AdapterInterface; */ abstract class AbstractCacheableCountPaginatorAdapter implements AdapterInterface { - private ?int $count = null; + private int|null $count = null; final public function getNbResults(): int { diff --git a/module/Core/src/RedirectRule/Entity/RedirectCondition.php b/module/Core/src/RedirectRule/Entity/RedirectCondition.php index 59c2798b..99f5fb9c 100644 --- a/module/Core/src/RedirectRule/Entity/RedirectCondition.php +++ b/module/Core/src/RedirectRule/Entity/RedirectCondition.php @@ -24,7 +24,7 @@ class RedirectCondition extends AbstractEntity implements JsonSerializable private function __construct( private readonly RedirectConditionType $type, private readonly string $matchValue, - private readonly ?string $matchKey = null, + private readonly string|null $matchKey = null, ) { } diff --git a/module/Core/src/ShortUrl/DeleteShortUrlService.php b/module/Core/src/ShortUrl/DeleteShortUrlService.php index aeb08c47..b6ca5e8c 100644 --- a/module/Core/src/ShortUrl/DeleteShortUrlService.php +++ b/module/Core/src/ShortUrl/DeleteShortUrlService.php @@ -30,7 +30,7 @@ readonly class DeleteShortUrlService implements DeleteShortUrlServiceInterface public function deleteByShortCode( ShortUrlIdentifier $identifier, bool $ignoreThreshold = false, - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, ): void { $shortUrl = $this->urlResolver->resolveShortUrl($identifier, $apiKey); if (! $ignoreThreshold && $this->isThresholdReached($shortUrl)) { diff --git a/module/Core/src/ShortUrl/DeleteShortUrlServiceInterface.php b/module/Core/src/ShortUrl/DeleteShortUrlServiceInterface.php index 32eaffa1..e511c9e5 100644 --- a/module/Core/src/ShortUrl/DeleteShortUrlServiceInterface.php +++ b/module/Core/src/ShortUrl/DeleteShortUrlServiceInterface.php @@ -18,7 +18,7 @@ interface DeleteShortUrlServiceInterface public function deleteByShortCode( ShortUrlIdentifier $identifier, bool $ignoreThreshold = false, - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, ): void; /** diff --git a/module/Core/src/ShortUrl/Entity/ShortUrl.php b/module/Core/src/ShortUrl/Entity/ShortUrl.php index ac50064c..39bc5ed6 100644 --- a/module/Core/src/ShortUrl/Entity/ShortUrl.php +++ b/module/Core/src/ShortUrl/Entity/ShortUrl.php @@ -49,19 +49,19 @@ class ShortUrl extends AbstractEntity private Collection $tags = new ArrayCollection(), private Collection & Selectable $visits = new ArrayCollection(), private Collection & Selectable $visitsCounts = new ArrayCollection(), - private ?Chronos $validSince = null, - private ?Chronos $validUntil = null, - private ?int $maxVisits = null, - private ?Domain $domain = null, + private Chronos|null $validSince = null, + private Chronos|null $validUntil = null, + private int|null $maxVisits = null, + private Domain|null $domain = null, private bool $customSlugWasProvided = false, private int $shortCodeLength = 0, - public readonly ?ApiKey $authorApiKey = null, - private ?string $title = null, + public readonly ApiKey|null $authorApiKey = null, + private string|null $title = null, private bool $titleWasAutoResolved = false, private bool $crawlable = false, private bool $forwardQuery = true, - private ?string $importSource = null, - private ?string $importOriginalShortCode = null, + private string|null $importSource = null, + private string|null $importOriginalShortCode = null, private Collection $redirectRules = new ArrayCollection(), ) { } @@ -85,7 +85,7 @@ class ShortUrl extends AbstractEntity public static function create( ShortUrlCreation $creation, - ?ShortUrlRelationResolverInterface $relationResolver = null, + ShortUrlRelationResolverInterface|null $relationResolver = null, ): self { $relationResolver = $relationResolver ?? new SimpleShortUrlRelationResolver(); $shortCodeLength = $creation->shortCodeLength; @@ -115,7 +115,7 @@ class ShortUrl extends AbstractEntity public static function fromImport( ImportedShlinkUrl $url, bool $importShortCode, - ?ShortUrlRelationResolverInterface $relationResolver = null, + ShortUrlRelationResolverInterface|null $relationResolver = null, ): self { $meta = [ ShortUrlInputFilter::LONG_URL => $url->longUrl, @@ -141,7 +141,7 @@ class ShortUrl extends AbstractEntity public function update( ShortUrlEdition $shortUrlEdit, - ?ShortUrlRelationResolverInterface $relationResolver = null, + ShortUrlRelationResolverInterface|null $relationResolver = null, ): void { if ($shortUrlEdit->validSinceWasProvided()) { $this->validSince = $shortUrlEdit->validSince; @@ -185,7 +185,7 @@ class ShortUrl extends AbstractEntity return $this->shortCode; } - public function getDomain(): ?Domain + public function getDomain(): Domain|null { return $this->domain; } @@ -195,7 +195,7 @@ class ShortUrl extends AbstractEntity return $this->forwardQuery; } - public function title(): ?string + public function title(): string|null { return $this->title; } @@ -205,7 +205,7 @@ class ShortUrl extends AbstractEntity return count($this->visits) >= $visitsAmount; } - public function mostRecentImportedVisitDate(): ?Chronos + public function mostRecentImportedVisitDate(): Chronos|null { $criteria = Criteria::create()->where(Criteria::expr()->eq('type', VisitType::IMPORTED)) ->orderBy(['id' => 'DESC']) @@ -270,7 +270,7 @@ class ShortUrl extends AbstractEntity * Providing the raw authority as `string|null` would result in a fallback to `$this->domain` when the authority * was null. */ - public function toArray(?VisitsSummary $precalculatedSummary = null, callable|null $getAuthority = null): array + public function toArray(VisitsSummary|null $precalculatedSummary = null, callable|null $getAuthority = null): array { return [ 'shortCode' => $this->shortCode, diff --git a/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilder.php b/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilder.php index 375d8837..47ac25bf 100644 --- a/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilder.php +++ b/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilder.php @@ -25,7 +25,7 @@ readonly class ShortUrlRedirectionBuilder implements ShortUrlRedirectionBuilderI public function buildShortUrlRedirect( ShortUrl $shortUrl, ServerRequestInterface $request, - ?string $extraPath = null, + string|null $extraPath = null, ): string { $uri = new Uri($this->redirectionResolver->resolveLongUrl($shortUrl, $request)); $shouldForwardQuery = $shortUrl->forwardQuery(); @@ -58,7 +58,7 @@ readonly class ShortUrlRedirectionBuilder implements ShortUrlRedirectionBuilderI return Query::build($mergedQuery); } - private function resolvePath(string $basePath, ?string $extraPath): string + private function resolvePath(string $basePath, string|null $extraPath): string { return $extraPath === null ? $basePath : sprintf('%s%s', $basePath, $extraPath); } diff --git a/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilderInterface.php b/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilderInterface.php index 7f79e98a..849a3b3f 100644 --- a/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilderInterface.php +++ b/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilderInterface.php @@ -12,6 +12,6 @@ interface ShortUrlRedirectionBuilderInterface public function buildShortUrlRedirect( ShortUrl $shortUrl, ServerRequestInterface $request, - ?string $extraPath = null, + string|null $extraPath = null, ): string; } diff --git a/module/Core/src/ShortUrl/Helper/ShortUrlTitleResolutionHelper.php b/module/Core/src/ShortUrl/Helper/ShortUrlTitleResolutionHelper.php index 0950e042..df52c92d 100644 --- a/module/Core/src/ShortUrl/Helper/ShortUrlTitleResolutionHelper.php +++ b/module/Core/src/ShortUrl/Helper/ShortUrlTitleResolutionHelper.php @@ -61,7 +61,7 @@ readonly class ShortUrlTitleResolutionHelper implements ShortUrlTitleResolutionH return $title !== null ? $data->withResolvedTitle($title) : $data; } - private function fetchUrl(string $url): ?ResponseInterface + private function fetchUrl(string $url): ResponseInterface|null { try { return $this->httpClient->request(RequestMethodInterface::METHOD_GET, $url, [ @@ -80,7 +80,7 @@ readonly class ShortUrlTitleResolutionHelper implements ShortUrlTitleResolutionH } } - private function tryToResolveTitle(ResponseInterface $response, string $contentType): ?string + private function tryToResolveTitle(ResponseInterface $response, string $contentType): string|null { $collectedBody = ''; $body = $response->getBody(); diff --git a/module/Core/src/ShortUrl/Middleware/ExtraPathRedirectMiddleware.php b/module/Core/src/ShortUrl/Middleware/ExtraPathRedirectMiddleware.php index b164ffd6..7c868907 100644 --- a/module/Core/src/ShortUrl/Middleware/ExtraPathRedirectMiddleware.php +++ b/module/Core/src/ShortUrl/Middleware/ExtraPathRedirectMiddleware.php @@ -47,7 +47,7 @@ class ExtraPathRedirectMiddleware implements MiddlewareInterface return $this->tryToResolveRedirect($request, $handler); } - private function shouldApplyLogic(?NotFoundType $notFoundType): bool + private function shouldApplyLogic(NotFoundType|null $notFoundType): bool { if ($notFoundType === null || ! $this->urlShortenerOptions->appendExtraPath) { return false; diff --git a/module/Core/src/ShortUrl/Model/ShortUrlCreation.php b/module/Core/src/ShortUrl/Model/ShortUrlCreation.php index c9c85e1b..778e8d00 100644 --- a/module/Core/src/ShortUrl/Model/ShortUrlCreation.php +++ b/module/Core/src/ShortUrl/Model/ShortUrlCreation.php @@ -26,17 +26,17 @@ final readonly class ShortUrlCreation implements TitleResolutionModelInterface private function __construct( public string $longUrl, public ShortUrlMode $shortUrlMode, - public ?Chronos $validSince = null, - public ?Chronos $validUntil = null, - public ?string $customSlug = null, - public ?string $pathPrefix = null, - public ?int $maxVisits = null, + public Chronos|null $validSince = null, + public Chronos|null $validUntil = null, + public string|null $customSlug = null, + public string|null $pathPrefix = null, + public int|null $maxVisits = null, public bool $findIfExists = false, - public ?string $domain = null, + public string|null $domain = null, public int $shortCodeLength = 5, - public ?ApiKey $apiKey = null, + public ApiKey|null $apiKey = null, public array $tags = [], - public ?string $title = null, + public string|null $title = null, public bool $titleWasAutoResolved = false, public bool $crawlable = false, public bool $forwardQuery = true, diff --git a/module/Core/src/ShortUrl/Model/ShortUrlEdition.php b/module/Core/src/ShortUrl/Model/ShortUrlEdition.php index 6296f84d..69b571d0 100644 --- a/module/Core/src/ShortUrl/Model/ShortUrlEdition.php +++ b/module/Core/src/ShortUrl/Model/ShortUrlEdition.php @@ -21,17 +21,17 @@ final readonly class ShortUrlEdition implements TitleResolutionModelInterface */ private function __construct( private bool $longUrlPropWasProvided = false, - public ?string $longUrl = null, + public string|null $longUrl = null, private bool $validSincePropWasProvided = false, - public ?Chronos $validSince = null, + public Chronos|null $validSince = null, private bool $validUntilPropWasProvided = false, - public ?Chronos $validUntil = null, + public Chronos|null $validUntil = null, private bool $maxVisitsPropWasProvided = false, - public ?int $maxVisits = null, + public int|null $maxVisits = null, private bool $tagsPropWasProvided = false, public array $tags = [], private bool $titlePropWasProvided = false, - public ?string $title = null, + public string|null $title = null, public bool $titleWasAutoResolved = false, private bool $crawlablePropWasProvided = false, public bool $crawlable = false, diff --git a/module/Core/src/ShortUrl/Model/ShortUrlIdentifier.php b/module/Core/src/ShortUrl/Model/ShortUrlIdentifier.php index a7c2e2ff..ff44ed7f 100644 --- a/module/Core/src/ShortUrl/Model/ShortUrlIdentifier.php +++ b/module/Core/src/ShortUrl/Model/ShortUrlIdentifier.php @@ -11,7 +11,7 @@ use function sprintf; final readonly class ShortUrlIdentifier { - private function __construct(public string $shortCode, public ?string $domain = null) + private function __construct(public string $shortCode, public string|null $domain = null) { } @@ -39,7 +39,7 @@ final readonly class ShortUrlIdentifier return new self($shortUrl->getShortCode(), $domainAuthority); } - public static function fromShortCodeAndDomain(string $shortCode, ?string $domain = null): self + public static function fromShortCodeAndDomain(string $shortCode, string|null $domain = null): self { return new self($shortCode, $domain); } diff --git a/module/Core/src/ShortUrl/Model/ShortUrlsParams.php b/module/Core/src/ShortUrl/Model/ShortUrlsParams.php index e625087e..7b68ed37 100644 --- a/module/Core/src/ShortUrl/Model/ShortUrlsParams.php +++ b/module/Core/src/ShortUrl/Model/ShortUrlsParams.php @@ -22,7 +22,7 @@ final class ShortUrlsParams public readonly string|null $searchTerm, public readonly array $tags, public readonly Ordering $orderBy, - public readonly ?DateRange $dateRange, + public readonly DateRange|null $dateRange, public readonly bool $excludeMaxVisitsReached, public readonly bool $excludePastValidUntil, public readonly TagsMode $tagsMode = TagsMode::ANY, @@ -64,7 +64,7 @@ final class ShortUrlsParams ); } - private static function resolveTagsMode(?string $rawTagsMode): TagsMode + private static function resolveTagsMode(string|null $rawTagsMode): TagsMode { if ($rawTagsMode === null) { return TagsMode::ANY; diff --git a/module/Core/src/ShortUrl/Model/UrlShorteningResult.php b/module/Core/src/ShortUrl/Model/UrlShorteningResult.php index b9d4f993..6bfd91bc 100644 --- a/module/Core/src/ShortUrl/Model/UrlShorteningResult.php +++ b/module/Core/src/ShortUrl/Model/UrlShorteningResult.php @@ -11,7 +11,7 @@ final class UrlShorteningResult { private function __construct( public readonly ShortUrl $shortUrl, - private readonly ?Throwable $errorOnEventDispatching, + private readonly Throwable|null $errorOnEventDispatching, ) { } diff --git a/module/Core/src/ShortUrl/Model/Validation/ShortUrlInputFilter.php b/module/Core/src/ShortUrl/Model/Validation/ShortUrlInputFilter.php index 3cd7744a..5cd7fe38 100644 --- a/module/Core/src/ShortUrl/Model/Validation/ShortUrlInputFilter.php +++ b/module/Core/src/ShortUrl/Model/Validation/ShortUrlInputFilter.php @@ -109,7 +109,7 @@ class ShortUrlInputFilter extends InputFilter $title = InputFactory::basic(self::TITLE); $title->getFilterChain()->attach(new Filter\Callback( - static fn (?string $value) => $value === null ? $value : substr($value, 0, 512), + static fn (string|null $value) => $value === null ? $value : substr($value, 0, 512), )); $this->add($title); diff --git a/module/Core/src/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapter.php b/module/Core/src/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapter.php index ac3379df..1a7b97de 100644 --- a/module/Core/src/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapter.php +++ b/module/Core/src/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapter.php @@ -18,7 +18,7 @@ readonly class ShortUrlRepositoryAdapter implements AdapterInterface public function __construct( private ShortUrlListRepositoryInterface $repository, private ShortUrlsParams $params, - private ?ApiKey $apiKey, + private ApiKey|null $apiKey, private string $defaultDomain, ) { } diff --git a/module/Core/src/ShortUrl/Persistence/ShortUrlsCountFiltering.php b/module/Core/src/ShortUrl/Persistence/ShortUrlsCountFiltering.php index b27fe7c5..a8e42236 100644 --- a/module/Core/src/ShortUrl/Persistence/ShortUrlsCountFiltering.php +++ b/module/Core/src/ShortUrl/Persistence/ShortUrlsCountFiltering.php @@ -17,15 +17,15 @@ class ShortUrlsCountFiltering public readonly bool $searchIncludesDefaultDomain; public function __construct( - public readonly ?string $searchTerm = null, + public readonly string|null $searchTerm = null, public readonly array $tags = [], - public readonly ?TagsMode $tagsMode = null, - public readonly ?DateRange $dateRange = null, + public readonly TagsMode|null $tagsMode = null, + public readonly DateRange|null $dateRange = null, public readonly bool $excludeMaxVisitsReached = false, public readonly bool $excludePastValidUntil = false, - public readonly ?ApiKey $apiKey = null, - ?string $defaultDomain = null, - public readonly ?string $domain = null, + public readonly ApiKey|null $apiKey = null, + string|null $defaultDomain = null, + public readonly string|null $domain = null, ) { $this->searchIncludesDefaultDomain = !empty($searchTerm) && !empty($defaultDomain) && str_contains( strtolower($defaultDomain), @@ -33,7 +33,7 @@ class ShortUrlsCountFiltering ); } - public static function fromParams(ShortUrlsParams $params, ?ApiKey $apiKey, string $defaultDomain): self + public static function fromParams(ShortUrlsParams $params, ApiKey|null $apiKey, string $defaultDomain): self { return new self( $params->searchTerm, diff --git a/module/Core/src/ShortUrl/Persistence/ShortUrlsListFiltering.php b/module/Core/src/ShortUrl/Persistence/ShortUrlsListFiltering.php index b3946ab1..d0fa6418 100644 --- a/module/Core/src/ShortUrl/Persistence/ShortUrlsListFiltering.php +++ b/module/Core/src/ShortUrl/Persistence/ShortUrlsListFiltering.php @@ -13,19 +13,19 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; class ShortUrlsListFiltering extends ShortUrlsCountFiltering { public function __construct( - public readonly ?int $limit = null, - public readonly ?int $offset = null, + public readonly int|null $limit = null, + public readonly int|null $offset = null, public readonly Ordering $orderBy = new Ordering(), - ?string $searchTerm = null, + string|null $searchTerm = null, array $tags = [], - ?TagsMode $tagsMode = null, - ?DateRange $dateRange = null, + TagsMode|null $tagsMode = null, + DateRange|null $dateRange = null, bool $excludeMaxVisitsReached = false, bool $excludePastValidUntil = false, - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, // Used only to determine if search term includes default domain - ?string $defaultDomain = null, - ?string $domain = null, + string|null $defaultDomain = null, + string|null $domain = null, ) { parent::__construct( $searchTerm, @@ -44,7 +44,7 @@ class ShortUrlsListFiltering extends ShortUrlsCountFiltering int $limit, int $offset, ShortUrlsParams $params, - ?ApiKey $apiKey, + ApiKey|null $apiKey, string $defaultDomain, ): self { return new self( diff --git a/module/Core/src/ShortUrl/Repository/ShortUrlRepository.php b/module/Core/src/ShortUrl/Repository/ShortUrlRepository.php index 015c8eac..bb6abea2 100644 --- a/module/Core/src/ShortUrl/Repository/ShortUrlRepository.php +++ b/module/Core/src/ShortUrl/Repository/ShortUrlRepository.php @@ -23,7 +23,7 @@ use function strtolower; /** @extends EntitySpecificationRepository */ class ShortUrlRepository extends EntitySpecificationRepository implements ShortUrlRepositoryInterface { - public function findOneWithDomainFallback(ShortUrlIdentifier $identifier, ShortUrlMode $shortUrlMode): ?ShortUrl + public function findOneWithDomainFallback(ShortUrlIdentifier $identifier, ShortUrlMode $shortUrlMode): ShortUrl|null { // When ordering DESC, Postgres puts nulls at the beginning while the rest of supported DB engines put them at // the bottom @@ -52,7 +52,7 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU return $qb->getQuery()->getOneOrNullResult(); } - public function findOne(ShortUrlIdentifier $identifier, ?Specification $spec = null): ?ShortUrl + public function findOne(ShortUrlIdentifier $identifier, Specification|null $spec = null): ShortUrl|null { $qb = $this->createFindOneQueryBuilder($identifier, $spec); $qb->select('s'); @@ -60,12 +60,12 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU return $qb->getQuery()->getOneOrNullResult(); } - public function shortCodeIsInUse(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool + public function shortCodeIsInUse(ShortUrlIdentifier $identifier, Specification|null $spec = null): bool { return $this->doShortCodeIsInUse($identifier, $spec, null); } - public function shortCodeIsInUseWithLock(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool + public function shortCodeIsInUseWithLock(ShortUrlIdentifier $identifier, Specification|null $spec = null): bool { return $this->doShortCodeIsInUse($identifier, $spec, LockMode::PESSIMISTIC_WRITE); } @@ -73,8 +73,11 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU /** * @param LockMode::PESSIMISTIC_WRITE|null $lockMode */ - private function doShortCodeIsInUse(ShortUrlIdentifier $identifier, ?Specification $spec, ?LockMode $lockMode): bool - { + private function doShortCodeIsInUse( + ShortUrlIdentifier $identifier, + Specification|null $spec, + LockMode|null $lockMode, + ): bool { $qb = $this->createFindOneQueryBuilder($identifier, $spec)->select('s.id'); $query = $qb->getQuery(); @@ -85,7 +88,7 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU return $query->getOneOrNullResult() !== null; } - private function createFindOneQueryBuilder(ShortUrlIdentifier $identifier, ?Specification $spec): QueryBuilder + private function createFindOneQueryBuilder(ShortUrlIdentifier $identifier, Specification|null $spec): QueryBuilder { $qb = $this->getEntityManager()->createQueryBuilder(); $qb->from(ShortUrl::class, 's') @@ -101,7 +104,7 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU return $qb; } - public function findOneMatching(ShortUrlCreation $creation): ?ShortUrl + public function findOneMatching(ShortUrlCreation $creation): ShortUrl|null { $qb = $this->getEntityManager()->createQueryBuilder(); @@ -166,7 +169,7 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU } } - public function findOneByImportedUrl(ImportedShlinkUrl $url): ?ShortUrl + public function findOneByImportedUrl(ImportedShlinkUrl $url): ShortUrl|null { $qb = $this->createQueryBuilder('s'); $qb->andWhere($qb->expr()->eq('s.importOriginalShortCode', ':shortCode')) @@ -180,7 +183,7 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU return $qb->getQuery()->getOneOrNullResult(); } - private function whereDomainIs(QueryBuilder $qb, ?string $domain): void + private function whereDomainIs(QueryBuilder $qb, string|null $domain): void { if ($domain !== null) { $qb->join('s.domain', 'd') diff --git a/module/Core/src/ShortUrl/Repository/ShortUrlRepositoryInterface.php b/module/Core/src/ShortUrl/Repository/ShortUrlRepositoryInterface.php index d0934197..a96d0be8 100644 --- a/module/Core/src/ShortUrl/Repository/ShortUrlRepositoryInterface.php +++ b/module/Core/src/ShortUrl/Repository/ShortUrlRepositoryInterface.php @@ -16,15 +16,18 @@ use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl; /** @extends ObjectRepository */ interface ShortUrlRepositoryInterface extends ObjectRepository, EntitySpecificationRepositoryInterface { - public function findOneWithDomainFallback(ShortUrlIdentifier $identifier, ShortUrlMode $shortUrlMode): ?ShortUrl; + public function findOneWithDomainFallback( + ShortUrlIdentifier $identifier, + ShortUrlMode $shortUrlMode, + ): ShortUrl|null; - public function findOne(ShortUrlIdentifier $identifier, ?Specification $spec = null): ?ShortUrl; + public function findOne(ShortUrlIdentifier $identifier, Specification|null $spec = null): ShortUrl|null; - public function shortCodeIsInUse(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool; + public function shortCodeIsInUse(ShortUrlIdentifier $identifier, Specification|null $spec = null): bool; - public function shortCodeIsInUseWithLock(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool; + public function shortCodeIsInUseWithLock(ShortUrlIdentifier $identifier, Specification|null $spec = null): bool; - public function findOneMatching(ShortUrlCreation $creation): ?ShortUrl; + public function findOneMatching(ShortUrlCreation $creation): ShortUrl|null; - public function findOneByImportedUrl(ImportedShlinkUrl $url): ?ShortUrl; + public function findOneByImportedUrl(ImportedShlinkUrl $url): ShortUrl|null; } diff --git a/module/Core/src/ShortUrl/Resolver/PersistenceShortUrlRelationResolver.php b/module/Core/src/ShortUrl/Resolver/PersistenceShortUrlRelationResolver.php index 94fb314a..2e5f3e15 100644 --- a/module/Core/src/ShortUrl/Resolver/PersistenceShortUrlRelationResolver.php +++ b/module/Core/src/ShortUrl/Resolver/PersistenceShortUrlRelationResolver.php @@ -38,7 +38,7 @@ class PersistenceShortUrlRelationResolver implements ShortUrlRelationResolverInt $this->em->getEventManager()->addEventListener(Events::postFlush, $this); } - public function resolveDomain(?string $domain): ?Domain + public function resolveDomain(string|null $domain): Domain|null { if ($domain === null || $domain === $this->options->defaultDomain) { return null; diff --git a/module/Core/src/ShortUrl/Resolver/ShortUrlRelationResolverInterface.php b/module/Core/src/ShortUrl/Resolver/ShortUrlRelationResolverInterface.php index b5228214..6af627b5 100644 --- a/module/Core/src/ShortUrl/Resolver/ShortUrlRelationResolverInterface.php +++ b/module/Core/src/ShortUrl/Resolver/ShortUrlRelationResolverInterface.php @@ -10,7 +10,7 @@ use Shlinkio\Shlink\Core\Tag\Entity\Tag; interface ShortUrlRelationResolverInterface { - public function resolveDomain(?string $domain): ?Domain; + public function resolveDomain(string|null $domain): Domain|null; /** * @param string[] $tags diff --git a/module/Core/src/ShortUrl/Resolver/SimpleShortUrlRelationResolver.php b/module/Core/src/ShortUrl/Resolver/SimpleShortUrlRelationResolver.php index c1a9d0ab..5702c346 100644 --- a/module/Core/src/ShortUrl/Resolver/SimpleShortUrlRelationResolver.php +++ b/module/Core/src/ShortUrl/Resolver/SimpleShortUrlRelationResolver.php @@ -12,7 +12,7 @@ use function array_map; class SimpleShortUrlRelationResolver implements ShortUrlRelationResolverInterface { - public function resolveDomain(?string $domain): ?Domain + public function resolveDomain(string|null $domain): Domain|null { return $domain !== null ? Domain::withAuthority($domain) : null; } diff --git a/module/Core/src/ShortUrl/ShortUrlListService.php b/module/Core/src/ShortUrl/ShortUrlListService.php index 853a40b9..2a1adb26 100644 --- a/module/Core/src/ShortUrl/ShortUrlListService.php +++ b/module/Core/src/ShortUrl/ShortUrlListService.php @@ -22,7 +22,7 @@ readonly class ShortUrlListService implements ShortUrlListServiceInterface /** * @inheritDoc */ - public function listShortUrls(ShortUrlsParams $params, ?ApiKey $apiKey = null): Paginator + public function listShortUrls(ShortUrlsParams $params, ApiKey|null $apiKey = null): Paginator { $defaultDomain = $this->urlShortenerOptions->defaultDomain; $paginator = new Paginator(new ShortUrlRepositoryAdapter($this->repo, $params, $apiKey, $defaultDomain)); diff --git a/module/Core/src/ShortUrl/ShortUrlListServiceInterface.php b/module/Core/src/ShortUrl/ShortUrlListServiceInterface.php index b83abd4c..a8b8b2cc 100644 --- a/module/Core/src/ShortUrl/ShortUrlListServiceInterface.php +++ b/module/Core/src/ShortUrl/ShortUrlListServiceInterface.php @@ -14,5 +14,5 @@ interface ShortUrlListServiceInterface /** * @return Paginator */ - public function listShortUrls(ShortUrlsParams $params, ?ApiKey $apiKey = null): Paginator; + public function listShortUrls(ShortUrlsParams $params, ApiKey|null $apiKey = null): Paginator; } diff --git a/module/Core/src/ShortUrl/ShortUrlResolver.php b/module/Core/src/ShortUrl/ShortUrlResolver.php index 14727ff5..0f32768d 100644 --- a/module/Core/src/ShortUrl/ShortUrlResolver.php +++ b/module/Core/src/ShortUrl/ShortUrlResolver.php @@ -23,7 +23,7 @@ readonly class ShortUrlResolver implements ShortUrlResolverInterface /** * @throws ShortUrlNotFoundException */ - public function resolveShortUrl(ShortUrlIdentifier $identifier, ?ApiKey $apiKey = null): ShortUrl + public function resolveShortUrl(ShortUrlIdentifier $identifier, ApiKey|null $apiKey = null): ShortUrl { /** @var ShortUrlRepository $shortUrlRepo */ $shortUrlRepo = $this->em->getRepository(ShortUrl::class); diff --git a/module/Core/src/ShortUrl/ShortUrlResolverInterface.php b/module/Core/src/ShortUrl/ShortUrlResolverInterface.php index 9dd522c0..bcf7d40a 100644 --- a/module/Core/src/ShortUrl/ShortUrlResolverInterface.php +++ b/module/Core/src/ShortUrl/ShortUrlResolverInterface.php @@ -14,7 +14,7 @@ interface ShortUrlResolverInterface /** * @throws ShortUrlNotFoundException */ - public function resolveShortUrl(ShortUrlIdentifier $identifier, ?ApiKey $apiKey = null): ShortUrl; + public function resolveShortUrl(ShortUrlIdentifier $identifier, ApiKey|null $apiKey = null): ShortUrl; /** * Resolves a public short URL matching provided identifier. diff --git a/module/Core/src/ShortUrl/ShortUrlService.php b/module/Core/src/ShortUrl/ShortUrlService.php index d75f847d..b2c7e92f 100644 --- a/module/Core/src/ShortUrl/ShortUrlService.php +++ b/module/Core/src/ShortUrl/ShortUrlService.php @@ -29,7 +29,7 @@ readonly class ShortUrlService implements ShortUrlServiceInterface public function updateShortUrl( ShortUrlIdentifier $identifier, ShortUrlEdition $shortUrlEdit, - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, ): ShortUrl { if ($shortUrlEdit->longUrlWasProvided()) { $shortUrlEdit = $this->titleResolutionHelper->processTitle($shortUrlEdit); diff --git a/module/Core/src/ShortUrl/ShortUrlServiceInterface.php b/module/Core/src/ShortUrl/ShortUrlServiceInterface.php index c7892f55..fde21a70 100644 --- a/module/Core/src/ShortUrl/ShortUrlServiceInterface.php +++ b/module/Core/src/ShortUrl/ShortUrlServiceInterface.php @@ -18,6 +18,6 @@ interface ShortUrlServiceInterface public function updateShortUrl( ShortUrlIdentifier $identifier, ShortUrlEdition $shortUrlEdit, - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, ): ShortUrl; } diff --git a/module/Core/src/ShortUrl/ShortUrlVisitsDeleter.php b/module/Core/src/ShortUrl/ShortUrlVisitsDeleter.php index 8ad6713f..e8a07654 100644 --- a/module/Core/src/ShortUrl/ShortUrlVisitsDeleter.php +++ b/module/Core/src/ShortUrl/ShortUrlVisitsDeleter.php @@ -21,7 +21,7 @@ class ShortUrlVisitsDeleter implements ShortUrlVisitsDeleterInterface /** * @throws ShortUrlNotFoundException */ - public function deleteShortUrlVisits(ShortUrlIdentifier $identifier, ?ApiKey $apiKey = null): BulkDeleteResult + public function deleteShortUrlVisits(ShortUrlIdentifier $identifier, ApiKey|null $apiKey = null): BulkDeleteResult { $shortUrl = $this->resolver->resolveShortUrl($identifier, $apiKey); return new BulkDeleteResult($this->repository->deleteShortUrlVisits($shortUrl)); diff --git a/module/Core/src/ShortUrl/ShortUrlVisitsDeleterInterface.php b/module/Core/src/ShortUrl/ShortUrlVisitsDeleterInterface.php index 46e9fde5..625880dc 100644 --- a/module/Core/src/ShortUrl/ShortUrlVisitsDeleterInterface.php +++ b/module/Core/src/ShortUrl/ShortUrlVisitsDeleterInterface.php @@ -14,5 +14,5 @@ interface ShortUrlVisitsDeleterInterface /** * @throws ShortUrlNotFoundException */ - public function deleteShortUrlVisits(ShortUrlIdentifier $identifier, ?ApiKey $apiKey = null): BulkDeleteResult; + public function deleteShortUrlVisits(ShortUrlIdentifier $identifier, ApiKey|null $apiKey = null): BulkDeleteResult; } diff --git a/module/Core/src/ShortUrl/Spec/BelongsToApiKey.php b/module/Core/src/ShortUrl/Spec/BelongsToApiKey.php index 3c95593c..42f9c722 100644 --- a/module/Core/src/ShortUrl/Spec/BelongsToApiKey.php +++ b/module/Core/src/ShortUrl/Spec/BelongsToApiKey.php @@ -11,7 +11,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; class BelongsToApiKey extends BaseSpecification { - public function __construct(private ApiKey $apiKey, ?string $context = null) + public function __construct(private ApiKey $apiKey, string|null $context = null) { parent::__construct($context); } diff --git a/module/Core/src/ShortUrl/Spec/BelongsToDomain.php b/module/Core/src/ShortUrl/Spec/BelongsToDomain.php index 33eacec8..4a2aae62 100644 --- a/module/Core/src/ShortUrl/Spec/BelongsToDomain.php +++ b/module/Core/src/ShortUrl/Spec/BelongsToDomain.php @@ -10,7 +10,7 @@ use Happyr\DoctrineSpecification\Specification\BaseSpecification; class BelongsToDomain extends BaseSpecification { - public function __construct(private string $domainId, private ?string $dqlAlias = null) + public function __construct(private string $domainId, private string|null $dqlAlias = null) { parent::__construct(); } diff --git a/module/Core/src/ShortUrl/UrlShortener.php b/module/Core/src/ShortUrl/UrlShortener.php index 4a908c78..a0692e06 100644 --- a/module/Core/src/ShortUrl/UrlShortener.php +++ b/module/Core/src/ShortUrl/UrlShortener.php @@ -64,7 +64,7 @@ class UrlShortener implements UrlShortenerInterface return UrlShorteningResult::withoutErrorOnEventDispatching($newShortUrl); } - private function findExistingShortUrlIfExists(ShortUrlCreation $creation): ?ShortUrl + private function findExistingShortUrlIfExists(ShortUrlCreation $creation): ShortUrl|null { if (! $creation->findIfExists) { return null; diff --git a/module/Core/src/Spec/InDateRange.php b/module/Core/src/Spec/InDateRange.php index 994e6d63..d373a59d 100644 --- a/module/Core/src/Spec/InDateRange.php +++ b/module/Core/src/Spec/InDateRange.php @@ -11,7 +11,7 @@ use Shlinkio\Shlink\Common\Util\DateRange; class InDateRange extends BaseSpecification { - public function __construct(private ?DateRange $dateRange, private string $field = 'date') + public function __construct(private DateRange|null $dateRange, private string $field = 'date') { parent::__construct(); } diff --git a/module/Core/src/Tag/Model/OrderableField.php b/module/Core/src/Tag/Model/OrderableField.php index 39092e4d..0b7a4272 100644 --- a/module/Core/src/Tag/Model/OrderableField.php +++ b/module/Core/src/Tag/Model/OrderableField.php @@ -11,7 +11,7 @@ enum OrderableField: string case VISITS = 'visits'; case NON_BOT_VISITS = 'nonBotVisits'; - public static function toValidField(?string $field): self + public static function toValidField(string|null $field): self { if ($field === null) { return self::TAG; diff --git a/module/Core/src/Tag/Model/TagInfo.php b/module/Core/src/Tag/Model/TagInfo.php index 504181ec..dfa255bd 100644 --- a/module/Core/src/Tag/Model/TagInfo.php +++ b/module/Core/src/Tag/Model/TagInfo.php @@ -15,7 +15,7 @@ final readonly class TagInfo implements JsonSerializable public string $tag, public int $shortUrlsCount, int $visitsCount, - ?int $nonBotVisitsCount = null, + int|null $nonBotVisitsCount = null, ) { $this->visitsSummary = VisitsSummary::fromTotalAndNonBots($visitsCount, $nonBotVisitsCount ?? $visitsCount); } diff --git a/module/Core/src/Tag/Model/TagsListFiltering.php b/module/Core/src/Tag/Model/TagsListFiltering.php index 236dde4a..d8da71b7 100644 --- a/module/Core/src/Tag/Model/TagsListFiltering.php +++ b/module/Core/src/Tag/Model/TagsListFiltering.php @@ -10,15 +10,15 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; final class TagsListFiltering { public function __construct( - public readonly ?int $limit = null, - public readonly ?int $offset = null, - public readonly ?string $searchTerm = null, - public readonly ?Ordering $orderBy = null, - public readonly ?ApiKey $apiKey = null, + public readonly int|null $limit = null, + public readonly int|null $offset = null, + public readonly string|null $searchTerm = null, + public readonly Ordering|null $orderBy = null, + public readonly ApiKey|null $apiKey = null, ) { } - public static function fromRangeAndParams(int $limit, int $offset, TagsParams $params, ?ApiKey $apiKey): self + public static function fromRangeAndParams(int $limit, int $offset, TagsParams $params, ApiKey|null $apiKey): self { return new self($limit, $offset, $params->searchTerm, $params->orderBy, $apiKey); } diff --git a/module/Core/src/Tag/Model/TagsParams.php b/module/Core/src/Tag/Model/TagsParams.php index d094bcc0..7207b1a8 100644 --- a/module/Core/src/Tag/Model/TagsParams.php +++ b/module/Core/src/Tag/Model/TagsParams.php @@ -12,10 +12,10 @@ use function Shlinkio\Shlink\Common\parseOrderBy; final class TagsParams extends AbstractInfinitePaginableListParams { private function __construct( - public readonly ?string $searchTerm, + public readonly string|null $searchTerm, public readonly Ordering $orderBy, - ?int $page, - ?int $itemsPerPage, + int|null $page, + int|null $itemsPerPage, ) { parent::__construct($page, $itemsPerPage); } diff --git a/module/Core/src/Tag/Paginator/Adapter/AbstractTagsPaginatorAdapter.php b/module/Core/src/Tag/Paginator/Adapter/AbstractTagsPaginatorAdapter.php index 98126e27..e26ba2f4 100644 --- a/module/Core/src/Tag/Paginator/Adapter/AbstractTagsPaginatorAdapter.php +++ b/module/Core/src/Tag/Paginator/Adapter/AbstractTagsPaginatorAdapter.php @@ -21,7 +21,7 @@ abstract class AbstractTagsPaginatorAdapter implements AdapterInterface public function __construct( protected TagRepositoryInterface $repo, protected TagsParams $params, - protected ?ApiKey $apiKey, + protected ApiKey|null $apiKey, ) { } diff --git a/module/Core/src/Tag/Repository/TagRepository.php b/module/Core/src/Tag/Repository/TagRepository.php index a2820e7b..4545e46c 100644 --- a/module/Core/src/Tag/Repository/TagRepository.php +++ b/module/Core/src/Tag/Repository/TagRepository.php @@ -42,7 +42,7 @@ class TagRepository extends EntitySpecificationRepository implements TagReposito /** * @return TagInfo[] */ - public function findTagsWithInfo(?TagsListFiltering $filtering = null): array + public function findTagsWithInfo(TagsListFiltering|null $filtering = null): array { $orderField = OrderableField::toValidField($filtering?->orderBy?->field); $orderDir = $filtering?->orderBy?->direction ?? 'ASC'; @@ -134,7 +134,7 @@ class TagRepository extends EntitySpecificationRepository implements TagReposito ); } - public function tagExists(string $tag, ?ApiKey $apiKey = null): bool + public function tagExists(string $tag, ApiKey|null $apiKey = null): bool { $result = (int) $this->matchSingleScalarResult(Spec::andX( new CountTagsWithName($tag), diff --git a/module/Core/src/Tag/Repository/TagRepositoryInterface.php b/module/Core/src/Tag/Repository/TagRepositoryInterface.php index ccb33de0..236beb14 100644 --- a/module/Core/src/Tag/Repository/TagRepositoryInterface.php +++ b/module/Core/src/Tag/Repository/TagRepositoryInterface.php @@ -19,7 +19,7 @@ interface TagRepositoryInterface extends ObjectRepository, EntitySpecificationRe /** * @return TagInfo[] */ - public function findTagsWithInfo(?TagsListFiltering $filtering = null): array; + public function findTagsWithInfo(TagsListFiltering|null $filtering = null): array; - public function tagExists(string $tag, ?ApiKey $apiKey = null): bool; + public function tagExists(string $tag, ApiKey|null $apiKey = null): bool; } diff --git a/module/Core/src/Tag/TagService.php b/module/Core/src/Tag/TagService.php index de16fada..e3e5b92f 100644 --- a/module/Core/src/Tag/TagService.php +++ b/module/Core/src/Tag/TagService.php @@ -28,7 +28,7 @@ readonly class TagService implements TagServiceInterface /** * @inheritDoc */ - public function listTags(TagsParams $params, ?ApiKey $apiKey = null): Paginator + public function listTags(TagsParams $params, ApiKey|null $apiKey = null): Paginator { /** @var TagRepository $repo */ $repo = $this->em->getRepository(Tag::class); @@ -38,7 +38,7 @@ readonly class TagService implements TagServiceInterface /** * @inheritDoc */ - public function tagsInfo(TagsParams $params, ?ApiKey $apiKey = null): Paginator + public function tagsInfo(TagsParams $params, ApiKey|null $apiKey = null): Paginator { /** @var TagRepositoryInterface $repo */ $repo = $this->em->getRepository(Tag::class); @@ -60,7 +60,7 @@ readonly class TagService implements TagServiceInterface /** * @inheritDoc */ - public function deleteTags(array $tagNames, ?ApiKey $apiKey = null): void + public function deleteTags(array $tagNames, ApiKey|null $apiKey = null): void { if (ApiKey::isShortUrlRestricted($apiKey)) { throw ForbiddenTagOperationException::forDeletion(); @@ -74,7 +74,7 @@ readonly class TagService implements TagServiceInterface /** * @inheritDoc */ - public function renameTag(TagRenaming $renaming, ?ApiKey $apiKey = null): Tag + public function renameTag(TagRenaming $renaming, ApiKey|null $apiKey = null): Tag { if (ApiKey::isShortUrlRestricted($apiKey)) { throw ForbiddenTagOperationException::forRenaming(); diff --git a/module/Core/src/Tag/TagServiceInterface.php b/module/Core/src/Tag/TagServiceInterface.php index 60aeb7c7..c09370cf 100644 --- a/module/Core/src/Tag/TagServiceInterface.php +++ b/module/Core/src/Tag/TagServiceInterface.php @@ -19,23 +19,23 @@ interface TagServiceInterface /** * @return Paginator */ - public function listTags(TagsParams $params, ?ApiKey $apiKey = null): Paginator; + public function listTags(TagsParams $params, ApiKey|null $apiKey = null): Paginator; /** * @return Paginator */ - public function tagsInfo(TagsParams $params, ?ApiKey $apiKey = null): Paginator; + public function tagsInfo(TagsParams $params, ApiKey|null $apiKey = null): Paginator; /** * @param string[] $tagNames * @throws ForbiddenTagOperationException */ - public function deleteTags(array $tagNames, ?ApiKey $apiKey = null): void; + public function deleteTags(array $tagNames, ApiKey|null $apiKey = null): void; /** * @throws TagNotFoundException * @throws TagConflictException * @throws ForbiddenTagOperationException */ - public function renameTag(TagRenaming $renaming, ?ApiKey $apiKey = null): Tag; + public function renameTag(TagRenaming $renaming, ApiKey|null $apiKey = null): Tag; } diff --git a/module/Core/src/Util/IpAddressUtils.php b/module/Core/src/Util/IpAddressUtils.php index 66354c37..9adfa97d 100644 --- a/module/Core/src/Util/IpAddressUtils.php +++ b/module/Core/src/Util/IpAddressUtils.php @@ -56,7 +56,7 @@ final class IpAddressUtils * * @param string[] $ipAddressParts */ - private static function candidateToRange(string $candidate, array $ipAddressParts): ?RangeInterface + private static function candidateToRange(string $candidate, array $ipAddressParts): RangeInterface|null { return str_contains($candidate, '*') ? self::parseValueWithWildcards($candidate, $ipAddressParts) @@ -68,7 +68,7 @@ final class IpAddressUtils * Factory::parseRangeString can usually do this automatically, but only if wildcards are at the end. This also * covers cases where wildcards are in between. */ - private static function parseValueWithWildcards(string $value, array $ipAddressParts): ?RangeInterface + private static function parseValueWithWildcards(string $value, array $ipAddressParts): RangeInterface|null { $octets = explode('.', $value); $keys = array_keys($octets); diff --git a/module/Core/src/Visit/Entity/Visit.php b/module/Core/src/Visit/Entity/Visit.php index be8400dc..d02d7298 100644 --- a/module/Core/src/Visit/Entity/Visit.php +++ b/module/Core/src/Visit/Entity/Visit.php @@ -21,14 +21,14 @@ use function Shlinkio\Shlink\Core\normalizeDate; class Visit extends AbstractEntity implements JsonSerializable { private function __construct( - public readonly ?ShortUrl $shortUrl, + public readonly ShortUrl|null $shortUrl, public readonly VisitType $type, public readonly string $userAgent, public readonly string $referer, public readonly bool $potentialBot, - public readonly ?string $remoteAddr = null, - public readonly ?string $visitedUrl = null, - private ?VisitLocation $visitLocation = null, + public readonly string|null $remoteAddr = null, + public readonly string|null $visitedUrl = null, + private VisitLocation|null $visitLocation = null, public readonly Chronos $date = new Chronos(), ) { } @@ -53,8 +53,12 @@ class Visit extends AbstractEntity implements JsonSerializable return self::fromVisitor(null, VisitType::REGULAR_404, $visitor, $anonymize); } - private static function fromVisitor(?ShortUrl $shortUrl, VisitType $type, Visitor $visitor, bool $anonymize): self - { + private static function fromVisitor( + ShortUrl|null $shortUrl, + VisitType $type, + Visitor $visitor, + bool $anonymize, + ): self { return new self( shortUrl: $shortUrl, type: $type, @@ -66,7 +70,7 @@ class Visit extends AbstractEntity implements JsonSerializable ); } - private static function processAddress(?string $address, bool $anonymize): ?string + private static function processAddress(string|null $address, bool $anonymize): string|null { // Localhost address does not need to be anonymized if (! $anonymize || $address === null || $address === IpAddress::LOCALHOST) { @@ -96,7 +100,7 @@ class Visit extends AbstractEntity implements JsonSerializable private static function fromImportOrOrphanImport( ImportedShlinkVisit|ImportedShlinkOrphanVisit $importedVisit, VisitType $type, - ?ShortUrl $shortUrl = null, + ShortUrl|null $shortUrl = null, ): self { $importedLocation = $importedVisit->location; return new self( @@ -116,7 +120,7 @@ class Visit extends AbstractEntity implements JsonSerializable return ! empty($this->remoteAddr); } - public function getVisitLocation(): ?VisitLocation + public function getVisitLocation(): VisitLocation|null { return $this->visitLocation; } diff --git a/module/Core/src/Visit/Model/OrphanVisitsParams.php b/module/Core/src/Visit/Model/OrphanVisitsParams.php index 0fb2e99b..0e6afedc 100644 --- a/module/Core/src/Visit/Model/OrphanVisitsParams.php +++ b/module/Core/src/Visit/Model/OrphanVisitsParams.php @@ -12,11 +12,11 @@ use function sprintf; final class OrphanVisitsParams extends VisitsParams { public function __construct( - ?DateRange $dateRange = null, - ?int $page = null, - ?int $itemsPerPage = null, + DateRange|null $dateRange = null, + int|null $page = null, + int|null $itemsPerPage = null, bool $excludeBots = false, - public readonly ?OrphanVisitType $type = null, + public readonly OrphanVisitType|null $type = null, ) { parent::__construct($dateRange, $page, $itemsPerPage, $excludeBots); } diff --git a/module/Core/src/Visit/Model/Visitor.php b/module/Core/src/Visit/Model/Visitor.php index ca5d79b2..c914f334 100644 --- a/module/Core/src/Visit/Model/Visitor.php +++ b/module/Core/src/Visit/Model/Visitor.php @@ -21,10 +21,10 @@ final class Visitor public readonly string $userAgent; public readonly string $referer; public readonly string $visitedUrl; - public readonly ?string $remoteAddress; + public readonly string|null $remoteAddress; private bool $potentialBot; - public function __construct(string $userAgent, string $referer, ?string $remoteAddress, string $visitedUrl) + public function __construct(string $userAgent, string $referer, string|null $remoteAddress, string $visitedUrl) { $this->userAgent = $this->cropToLength($userAgent, self::USER_AGENT_MAX_LENGTH); $this->referer = $this->cropToLength($referer, self::REFERER_MAX_LENGTH); diff --git a/module/Core/src/Visit/Model/VisitsParams.php b/module/Core/src/Visit/Model/VisitsParams.php index 10713131..31e6e67d 100644 --- a/module/Core/src/Visit/Model/VisitsParams.php +++ b/module/Core/src/Visit/Model/VisitsParams.php @@ -14,9 +14,9 @@ class VisitsParams extends AbstractInfinitePaginableListParams public readonly DateRange $dateRange; public function __construct( - ?DateRange $dateRange = null, - ?int $page = null, - ?int $itemsPerPage = null, + DateRange|null $dateRange = null, + int|null $page = null, + int|null $itemsPerPage = null, public readonly bool $excludeBots = false, ) { parent::__construct($page, $itemsPerPage); diff --git a/module/Core/src/Visit/Model/VisitsStats.php b/module/Core/src/Visit/Model/VisitsStats.php index 22f05bd4..2f812aef 100644 --- a/module/Core/src/Visit/Model/VisitsStats.php +++ b/module/Core/src/Visit/Model/VisitsStats.php @@ -14,8 +14,8 @@ final readonly class VisitsStats implements JsonSerializable public function __construct( int $nonOrphanVisitsTotal, int $orphanVisitsTotal, - ?int $nonOrphanVisitsNonBots = null, - ?int $orphanVisitsNonBots = null, + int|null $nonOrphanVisitsNonBots = null, + int|null $orphanVisitsNonBots = null, ) { $this->nonOrphanVisitsSummary = VisitsSummary::fromTotalAndNonBots( $nonOrphanVisitsTotal, diff --git a/module/Core/src/Visit/Paginator/Adapter/DomainVisitsPaginatorAdapter.php b/module/Core/src/Visit/Paginator/Adapter/DomainVisitsPaginatorAdapter.php index 330d8692..184ecdd1 100644 --- a/module/Core/src/Visit/Paginator/Adapter/DomainVisitsPaginatorAdapter.php +++ b/module/Core/src/Visit/Paginator/Adapter/DomainVisitsPaginatorAdapter.php @@ -21,7 +21,7 @@ class DomainVisitsPaginatorAdapter extends AbstractCacheableCountPaginatorAdapte private readonly VisitRepositoryInterface $visitRepository, private readonly string $domain, private readonly VisitsParams $params, - private readonly ?ApiKey $apiKey, + private readonly ApiKey|null $apiKey, ) { } diff --git a/module/Core/src/Visit/Paginator/Adapter/NonOrphanVisitsPaginatorAdapter.php b/module/Core/src/Visit/Paginator/Adapter/NonOrphanVisitsPaginatorAdapter.php index 7929bcfd..5e3cdbe1 100644 --- a/module/Core/src/Visit/Paginator/Adapter/NonOrphanVisitsPaginatorAdapter.php +++ b/module/Core/src/Visit/Paginator/Adapter/NonOrphanVisitsPaginatorAdapter.php @@ -18,7 +18,7 @@ class NonOrphanVisitsPaginatorAdapter extends AbstractCacheableCountPaginatorAda public function __construct( private readonly VisitRepositoryInterface $repo, private readonly VisitsParams $params, - private readonly ?ApiKey $apiKey, + private readonly ApiKey|null $apiKey, ) { } diff --git a/module/Core/src/Visit/Paginator/Adapter/OrphanVisitsPaginatorAdapter.php b/module/Core/src/Visit/Paginator/Adapter/OrphanVisitsPaginatorAdapter.php index 9deedf9a..899ab831 100644 --- a/module/Core/src/Visit/Paginator/Adapter/OrphanVisitsPaginatorAdapter.php +++ b/module/Core/src/Visit/Paginator/Adapter/OrphanVisitsPaginatorAdapter.php @@ -18,7 +18,7 @@ class OrphanVisitsPaginatorAdapter extends AbstractCacheableCountPaginatorAdapte public function __construct( private readonly VisitRepositoryInterface $repo, private readonly OrphanVisitsParams $params, - private readonly ?ApiKey $apiKey, + private readonly ApiKey|null $apiKey, ) { } diff --git a/module/Core/src/Visit/Paginator/Adapter/ShortUrlVisitsPaginatorAdapter.php b/module/Core/src/Visit/Paginator/Adapter/ShortUrlVisitsPaginatorAdapter.php index 43bc02ff..efd68035 100644 --- a/module/Core/src/Visit/Paginator/Adapter/ShortUrlVisitsPaginatorAdapter.php +++ b/module/Core/src/Visit/Paginator/Adapter/ShortUrlVisitsPaginatorAdapter.php @@ -20,7 +20,7 @@ class ShortUrlVisitsPaginatorAdapter extends AbstractCacheableCountPaginatorAdap private readonly VisitRepositoryInterface $visitRepository, private readonly ShortUrlIdentifier $identifier, private readonly VisitsParams $params, - private readonly ?ApiKey $apiKey, + private readonly ApiKey|null $apiKey, ) { } diff --git a/module/Core/src/Visit/Paginator/Adapter/TagVisitsPaginatorAdapter.php b/module/Core/src/Visit/Paginator/Adapter/TagVisitsPaginatorAdapter.php index 93a182bd..909bd2ba 100644 --- a/module/Core/src/Visit/Paginator/Adapter/TagVisitsPaginatorAdapter.php +++ b/module/Core/src/Visit/Paginator/Adapter/TagVisitsPaginatorAdapter.php @@ -19,7 +19,7 @@ class TagVisitsPaginatorAdapter extends AbstractCacheableCountPaginatorAdapter private readonly VisitRepositoryInterface $visitRepository, private readonly string $tag, private readonly VisitsParams $params, - private readonly ?ApiKey $apiKey, + private readonly ApiKey|null $apiKey, ) { } diff --git a/module/Core/src/Visit/Persistence/OrphanVisitsCountFiltering.php b/module/Core/src/Visit/Persistence/OrphanVisitsCountFiltering.php index 88676df8..c09bc5ca 100644 --- a/module/Core/src/Visit/Persistence/OrphanVisitsCountFiltering.php +++ b/module/Core/src/Visit/Persistence/OrphanVisitsCountFiltering.php @@ -11,10 +11,10 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; class OrphanVisitsCountFiltering extends VisitsCountFiltering { public function __construct( - ?DateRange $dateRange = null, + DateRange|null $dateRange = null, bool $excludeBots = false, - ?ApiKey $apiKey = null, - public readonly ?OrphanVisitType $type = null, + ApiKey|null $apiKey = null, + public readonly OrphanVisitType|null $type = null, ) { parent::__construct($dateRange, $excludeBots, $apiKey); } diff --git a/module/Core/src/Visit/Persistence/OrphanVisitsListFiltering.php b/module/Core/src/Visit/Persistence/OrphanVisitsListFiltering.php index c2873cdf..d1e49605 100644 --- a/module/Core/src/Visit/Persistence/OrphanVisitsListFiltering.php +++ b/module/Core/src/Visit/Persistence/OrphanVisitsListFiltering.php @@ -11,12 +11,12 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; final class OrphanVisitsListFiltering extends OrphanVisitsCountFiltering { public function __construct( - ?DateRange $dateRange = null, + DateRange|null $dateRange = null, bool $excludeBots = false, - ?ApiKey $apiKey = null, - ?OrphanVisitType $type = null, - public readonly ?int $limit = null, - public readonly ?int $offset = null, + ApiKey|null $apiKey = null, + OrphanVisitType|null $type = null, + public readonly int|null $limit = null, + public readonly int|null $offset = null, ) { parent::__construct($dateRange, $excludeBots, $apiKey, $type); } diff --git a/module/Core/src/Visit/Persistence/VisitsCountFiltering.php b/module/Core/src/Visit/Persistence/VisitsCountFiltering.php index 570abc19..8948c960 100644 --- a/module/Core/src/Visit/Persistence/VisitsCountFiltering.php +++ b/module/Core/src/Visit/Persistence/VisitsCountFiltering.php @@ -10,9 +10,9 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; class VisitsCountFiltering { public function __construct( - public readonly ?DateRange $dateRange = null, + public readonly DateRange|null $dateRange = null, public readonly bool $excludeBots = false, - public readonly ?ApiKey $apiKey = null, + public readonly ApiKey|null $apiKey = null, ) { } } diff --git a/module/Core/src/Visit/Persistence/VisitsListFiltering.php b/module/Core/src/Visit/Persistence/VisitsListFiltering.php index 747a3ce0..eded82eb 100644 --- a/module/Core/src/Visit/Persistence/VisitsListFiltering.php +++ b/module/Core/src/Visit/Persistence/VisitsListFiltering.php @@ -10,11 +10,11 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; final class VisitsListFiltering extends VisitsCountFiltering { public function __construct( - ?DateRange $dateRange = null, + DateRange|null $dateRange = null, bool $excludeBots = false, - ?ApiKey $apiKey = null, - public readonly ?int $limit = null, - public readonly ?int $offset = null, + ApiKey|null $apiKey = null, + public readonly int|null $limit = null, + public readonly int|null $offset = null, ) { parent::__construct($dateRange, $excludeBots, $apiKey); } diff --git a/module/Core/src/Visit/Repository/VisitIterationRepository.php b/module/Core/src/Visit/Repository/VisitIterationRepository.php index 71590d7e..1370ed20 100644 --- a/module/Core/src/Visit/Repository/VisitIterationRepository.php +++ b/module/Core/src/Visit/Repository/VisitIterationRepository.php @@ -48,7 +48,7 @@ class VisitIterationRepository extends EntitySpecificationRepository implements /** * @return iterable */ - public function findAllVisits(?DateRange $dateRange = null, int $blockSize = self::DEFAULT_BLOCK_SIZE): iterable + public function findAllVisits(DateRange|null $dateRange = null, int $blockSize = self::DEFAULT_BLOCK_SIZE): iterable { $qb = $this->createQueryBuilder('v'); if ($dateRange?->startDate !== null) { diff --git a/module/Core/src/Visit/Repository/VisitIterationRepositoryInterface.php b/module/Core/src/Visit/Repository/VisitIterationRepositoryInterface.php index d4ffb864..2f416324 100644 --- a/module/Core/src/Visit/Repository/VisitIterationRepositoryInterface.php +++ b/module/Core/src/Visit/Repository/VisitIterationRepositoryInterface.php @@ -24,5 +24,8 @@ interface VisitIterationRepositoryInterface /** * @return iterable */ - public function findAllVisits(?DateRange $dateRange = null, int $blockSize = self::DEFAULT_BLOCK_SIZE): iterable; + public function findAllVisits( + DateRange|null $dateRange = null, + int $blockSize = self::DEFAULT_BLOCK_SIZE, + ): iterable; } diff --git a/module/Core/src/Visit/Repository/VisitRepository.php b/module/Core/src/Visit/Repository/VisitRepository.php index 1df109b3..1c85fe66 100644 --- a/module/Core/src/Visit/Repository/VisitRepository.php +++ b/module/Core/src/Visit/Repository/VisitRepository.php @@ -203,7 +203,7 @@ class VisitRepository extends EntitySpecificationRepository implements VisitRepo return $qb; } - private function applyDatesInline(QueryBuilder $qb, ?DateRange $dateRange): void + private function applyDatesInline(QueryBuilder $qb, DateRange|null $dateRange): void { $conn = $this->getEntityManager()->getConnection(); @@ -215,7 +215,7 @@ class VisitRepository extends EntitySpecificationRepository implements VisitRepo } } - private function resolveVisitsWithNativeQuery(QueryBuilder $qb, ?int $limit, ?int $offset): array + private function resolveVisitsWithNativeQuery(QueryBuilder $qb, int|null $limit, int|null $offset): array { // TODO Order by date and ID, not just by ID (order by date DESC, id DESC). // That ensures imported visits are properly ordered even if inserted in wrong chronological order. @@ -248,7 +248,7 @@ class VisitRepository extends EntitySpecificationRepository implements VisitRepo return $this->getEntityManager()->createNativeQuery($nativeQb->getSQL(), $rsm)->getResult(); } - public function findMostRecentOrphanVisit(): ?Visit + public function findMostRecentOrphanVisit(): Visit|null { $dql = <<trackingOptions->queryHasDisableTrackParam($query); } - private function shouldDisableTrackingFromAddress(?string $remoteAddr): bool + private function shouldDisableTrackingFromAddress(string|null $remoteAddr): bool { if ($remoteAddr === null || ! $this->trackingOptions->hasDisableTrackingFrom()) { return false; diff --git a/module/Core/src/Visit/VisitsDeleter.php b/module/Core/src/Visit/VisitsDeleter.php index 2b925e17..fb0f231a 100644 --- a/module/Core/src/Visit/VisitsDeleter.php +++ b/module/Core/src/Visit/VisitsDeleter.php @@ -15,7 +15,7 @@ class VisitsDeleter implements VisitsDeleterInterface { } - public function deleteOrphanVisits(?ApiKey $apiKey = null): BulkDeleteResult + public function deleteOrphanVisits(ApiKey|null $apiKey = null): BulkDeleteResult { $affectedItems = $apiKey?->hasRole(Role::NO_ORPHAN_VISITS) ? 0 : $this->repository->deleteOrphanVisits(); return new BulkDeleteResult($affectedItems); diff --git a/module/Core/src/Visit/VisitsDeleterInterface.php b/module/Core/src/Visit/VisitsDeleterInterface.php index 3a75a0d3..67fa5e72 100644 --- a/module/Core/src/Visit/VisitsDeleterInterface.php +++ b/module/Core/src/Visit/VisitsDeleterInterface.php @@ -9,5 +9,5 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; interface VisitsDeleterInterface { - public function deleteOrphanVisits(?ApiKey $apiKey = null): BulkDeleteResult; + public function deleteOrphanVisits(ApiKey|null $apiKey = null): BulkDeleteResult; } diff --git a/module/Core/src/Visit/VisitsStatsHelper.php b/module/Core/src/Visit/VisitsStatsHelper.php index 0952670b..f1533ddf 100644 --- a/module/Core/src/Visit/VisitsStatsHelper.php +++ b/module/Core/src/Visit/VisitsStatsHelper.php @@ -41,7 +41,7 @@ readonly class VisitsStatsHelper implements VisitsStatsHelperInterface { } - public function getVisitsStats(?ApiKey $apiKey = null): VisitsStats + public function getVisitsStats(ApiKey|null $apiKey = null): VisitsStats { /** @var OrphanVisitsCountRepository $orphanVisitsCountRepo */ $orphanVisitsCountRepo = $this->em->getRepository(OrphanVisitsCount::class); @@ -68,7 +68,7 @@ readonly class VisitsStatsHelper implements VisitsStatsHelperInterface public function visitsForShortUrl( ShortUrlIdentifier $identifier, VisitsParams $params, - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, ): Paginator { /** @var ShortUrlRepositoryInterface $repo */ $repo = $this->em->getRepository(ShortUrl::class); @@ -88,7 +88,7 @@ readonly class VisitsStatsHelper implements VisitsStatsHelperInterface /** * @inheritDoc */ - public function visitsForTag(string $tag, VisitsParams $params, ?ApiKey $apiKey = null): Paginator + public function visitsForTag(string $tag, VisitsParams $params, ApiKey|null $apiKey = null): Paginator { /** @var TagRepository $tagRepo */ $tagRepo = $this->em->getRepository(Tag::class); @@ -105,7 +105,7 @@ readonly class VisitsStatsHelper implements VisitsStatsHelperInterface /** * @inheritDoc */ - public function visitsForDomain(string $domain, VisitsParams $params, ?ApiKey $apiKey = null): Paginator + public function visitsForDomain(string $domain, VisitsParams $params, ApiKey|null $apiKey = null): Paginator { /** @var DomainRepository $domainRepo */ $domainRepo = $this->em->getRepository(Domain::class); @@ -122,7 +122,7 @@ readonly class VisitsStatsHelper implements VisitsStatsHelperInterface /** * @inheritDoc */ - public function orphanVisits(OrphanVisitsParams $params, ?ApiKey $apiKey = null): Paginator + public function orphanVisits(OrphanVisitsParams $params, ApiKey|null $apiKey = null): Paginator { /** @var VisitRepositoryInterface $repo */ $repo = $this->em->getRepository(Visit::class); @@ -130,7 +130,7 @@ readonly class VisitsStatsHelper implements VisitsStatsHelperInterface return $this->createPaginator(new OrphanVisitsPaginatorAdapter($repo, $params, $apiKey), $params); } - public function nonOrphanVisits(VisitsParams $params, ?ApiKey $apiKey = null): Paginator + public function nonOrphanVisits(VisitsParams $params, ApiKey|null $apiKey = null): Paginator { /** @var VisitRepositoryInterface $repo */ $repo = $this->em->getRepository(Visit::class); diff --git a/module/Core/src/Visit/VisitsStatsHelperInterface.php b/module/Core/src/Visit/VisitsStatsHelperInterface.php index 87e0980b..12e58933 100644 --- a/module/Core/src/Visit/VisitsStatsHelperInterface.php +++ b/module/Core/src/Visit/VisitsStatsHelperInterface.php @@ -17,7 +17,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; interface VisitsStatsHelperInterface { - public function getVisitsStats(?ApiKey $apiKey = null): VisitsStats; + public function getVisitsStats(ApiKey|null $apiKey = null): VisitsStats; /** * @return Paginator @@ -26,28 +26,28 @@ interface VisitsStatsHelperInterface public function visitsForShortUrl( ShortUrlIdentifier $identifier, VisitsParams $params, - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, ): Paginator; /** * @return Paginator * @throws TagNotFoundException */ - public function visitsForTag(string $tag, VisitsParams $params, ?ApiKey $apiKey = null): Paginator; + public function visitsForTag(string $tag, VisitsParams $params, ApiKey|null $apiKey = null): Paginator; /** * @return Paginator * @throws DomainNotFoundException */ - public function visitsForDomain(string $domain, VisitsParams $params, ?ApiKey $apiKey = null): Paginator; + public function visitsForDomain(string $domain, VisitsParams $params, ApiKey|null $apiKey = null): Paginator; /** * @return Paginator */ - public function orphanVisits(OrphanVisitsParams $params, ?ApiKey $apiKey = null): Paginator; + public function orphanVisits(OrphanVisitsParams $params, ApiKey|null $apiKey = null): Paginator; /** * @return Paginator */ - public function nonOrphanVisits(VisitsParams $params, ?ApiKey $apiKey = null): Paginator; + public function nonOrphanVisits(VisitsParams $params, ApiKey|null $apiKey = null): Paginator; } diff --git a/module/Core/test-db/Domain/Repository/DomainRepositoryTest.php b/module/Core/test-db/Domain/Repository/DomainRepositoryTest.php index 58817f38..0bae6bd8 100644 --- a/module/Core/test-db/Domain/Repository/DomainRepositoryTest.php +++ b/module/Core/test-db/Domain/Repository/DomainRepositoryTest.php @@ -128,7 +128,7 @@ class DomainRepositoryTest extends DatabaseTestCase self::assertFalse($this->repo->domainExists('foo.com', $detachedWithRedirectsApiKey)); } - private function createShortUrl(Domain $domain, ?ApiKey $apiKey = null): ShortUrl + private function createShortUrl(Domain $domain, ApiKey|null $apiKey = null): ShortUrl { return ShortUrl::create( ShortUrlCreation::fromRawData( @@ -139,7 +139,7 @@ class DomainRepositoryTest extends DatabaseTestCase { } - public function resolveDomain(?string $domain): ?Domain + public function resolveDomain(string|null $domain): Domain|null { return $this->domain; } diff --git a/module/Core/test-db/ShortUrl/Repository/ShortUrlRepositoryTest.php b/module/Core/test-db/ShortUrl/Repository/ShortUrlRepositoryTest.php index 074acdd4..535ca50f 100644 --- a/module/Core/test-db/ShortUrl/Repository/ShortUrlRepositoryTest.php +++ b/module/Core/test-db/ShortUrl/Repository/ShortUrlRepositoryTest.php @@ -404,7 +404,7 @@ class ShortUrlRepositoryTest extends DatabaseTestCase #[Test] public function importedShortUrlsAreFoundWhenExpected(): void { - $buildImported = static fn (string $shortCode, ?string $domain = null) => + $buildImported = static fn (string $shortCode, string|null $domain = null) => new ImportedShlinkUrl(ImportSource::BITLY, 'https://foo', [], Chronos::now(), $domain, $shortCode, null); $shortUrlWithoutDomain = ShortUrl::fromImport($buildImported('my-cool-slug'), true); diff --git a/module/Core/test-db/Tag/Paginator/Adapter/TagsPaginatorAdapterTest.php b/module/Core/test-db/Tag/Paginator/Adapter/TagsPaginatorAdapterTest.php index f88a8e7f..b7027f97 100644 --- a/module/Core/test-db/Tag/Paginator/Adapter/TagsPaginatorAdapterTest.php +++ b/module/Core/test-db/Tag/Paginator/Adapter/TagsPaginatorAdapterTest.php @@ -29,8 +29,8 @@ class TagsPaginatorAdapterTest extends DatabaseTestCase */ #[Test, DataProvider('provideFilters')] public function expectedListOfTagsIsReturned( - ?string $searchTerm, - ?string $orderBy, + string|null $searchTerm, + string|null $orderBy, int $offset, int $length, array $expectedTags, diff --git a/module/Core/test-db/Tag/Repository/TagRepositoryTest.php b/module/Core/test-db/Tag/Repository/TagRepositoryTest.php index 77f6aa6a..34210dbe 100644 --- a/module/Core/test-db/Tag/Repository/TagRepositoryTest.php +++ b/module/Core/test-db/Tag/Repository/TagRepositoryTest.php @@ -57,7 +57,7 @@ class TagRepositoryTest extends DatabaseTestCase } #[Test, DataProvider('provideFilters')] - public function properTagsInfoIsReturned(?TagsListFiltering $filtering, array $expectedList): void + public function properTagsInfoIsReturned(TagsListFiltering|null $filtering, array $expectedList): void { $names = ['foo', 'bar', 'baz', 'another']; foreach ($names as $name) { @@ -73,7 +73,7 @@ class TagRepositoryTest extends DatabaseTestCase [$firstUrlTags] = array_chunk($names, 3); $secondUrlTags = [$names[0]]; - $metaWithTags = static fn (array $tags, ?ApiKey $apiKey) => ShortUrlCreation::fromRawData( + $metaWithTags = static fn (array $tags, ApiKey|null $apiKey) => ShortUrlCreation::fromRawData( ['longUrl' => 'https://longUrl', 'tags' => $tags, 'apiKey' => $apiKey], ); diff --git a/module/Core/test-db/Visit/Repository/VisitRepositoryTest.php b/module/Core/test-db/Visit/Repository/VisitRepositoryTest.php index 8d7579b7..393e41da 100644 --- a/module/Core/test-db/Visit/Repository/VisitRepositoryTest.php +++ b/module/Core/test-db/Visit/Repository/VisitRepositoryTest.php @@ -534,7 +534,7 @@ class VisitRepositoryTest extends DatabaseTestCase private function createShortUrlsAndVisits( bool|string $withDomain = true, array $tags = [], - ?ApiKey $apiKey = null, + ApiKey|null $apiKey = null, ): array { $shortUrl = ShortUrl::create(ShortUrlCreation::fromRawData([ ShortUrlInputFilter::LONG_URL => 'https://longUrl', diff --git a/module/Core/test/Action/QrCodeActionTest.php b/module/Core/test/Action/QrCodeActionTest.php index 5e499403..f8dea217 100644 --- a/module/Core/test/Action/QrCodeActionTest.php +++ b/module/Core/test/Action/QrCodeActionTest.php @@ -190,7 +190,7 @@ class QrCodeActionTest extends TestCase #[Test, DataProvider('provideRoundBlockSize')] public function imageCanRemoveExtraMarginWhenBlockRoundIsDisabled( QrCodeOptions $defaultOptions, - ?string $roundBlockSize, + string|null $roundBlockSize, int $expectedColor, ): void { $code = 'abc123'; @@ -234,7 +234,7 @@ class QrCodeActionTest extends TestCase } #[Test, DataProvider('provideColors')] - public function properColorsAreUsed(?string $queryColor, ?string $optionsColor, int $expectedColor): void + public function properColorsAreUsed(string|null $queryColor, string|null $optionsColor, int $expectedColor): void { $code = 'abc123'; $req = ServerRequestFactory::fromGlobals() @@ -320,7 +320,7 @@ class QrCodeActionTest extends TestCase yield 'only enabled short URLs' => [false]; } - public function action(?QrCodeOptions $options = null): QrCodeAction + public function action(QrCodeOptions|null $options = null): QrCodeAction { return new QrCodeAction( $this->urlResolver, diff --git a/module/Core/test/Config/PostProcessor/ShortUrlMethodsProcessorTest.php b/module/Core/test/Config/PostProcessor/ShortUrlMethodsProcessorTest.php index 80d5203a..39e37f32 100644 --- a/module/Core/test/Config/PostProcessor/ShortUrlMethodsProcessorTest.php +++ b/module/Core/test/Config/PostProcessor/ShortUrlMethodsProcessorTest.php @@ -23,14 +23,14 @@ class ShortUrlMethodsProcessorTest extends TestCase #[Test, DataProvider('provideConfigs')] public function onlyFirstRouteIdentifiedAsRedirectIsEditedWithProperAllowedMethods( array $config, - ?array $expectedRoutes, + array|null $expectedRoutes, ): void { self::assertEquals($expectedRoutes, ($this->processor)($config)['routes'] ?? null); } public static function provideConfigs(): iterable { - $buildConfigWithStatus = static fn (int $status, ?array $expectedAllowedMethods) => [[ + $buildConfigWithStatus = static fn (int $status, array|null $expectedAllowedMethods) => [[ 'routes' => [ ['name' => 'foo'], ['name' => 'bar'], diff --git a/module/Core/test/Domain/DomainServiceTest.php b/module/Core/test/Domain/DomainServiceTest.php index 7e2fea18..b7f78c6b 100644 --- a/module/Core/test/Domain/DomainServiceTest.php +++ b/module/Core/test/Domain/DomainServiceTest.php @@ -33,7 +33,7 @@ class DomainServiceTest extends TestCase } #[Test, DataProvider('provideExcludedDomains')] - public function listDomainsDelegatesIntoRepository(array $domains, array $expectedResult, ?ApiKey $apiKey): void + public function listDomainsDelegatesIntoRepository(array $domains, array $expectedResult, ApiKey|null $apiKey): void { $repo = $this->createMock(DomainRepository::class); $repo->expects($this->once())->method('findDomains')->with($apiKey)->willReturn($domains); @@ -124,7 +124,7 @@ class DomainServiceTest extends TestCase } #[Test, DataProvider('provideFoundDomains')] - public function getOrCreateAlwaysPersistsDomain(?Domain $foundDomain, ?ApiKey $apiKey): void + public function getOrCreateAlwaysPersistsDomain(Domain|null $foundDomain, ApiKey|null $apiKey): void { $authority = 'example.com'; $repo = $this->createMock(DomainRepository::class); @@ -161,8 +161,10 @@ class DomainServiceTest extends TestCase } #[Test, DataProvider('provideFoundDomains')] - public function configureNotFoundRedirectsConfiguresFetchedDomain(?Domain $foundDomain, ?ApiKey $apiKey): void - { + public function configureNotFoundRedirectsConfiguresFetchedDomain( + Domain|null $foundDomain, + ApiKey|null $apiKey, + ): void { $authority = 'example.com'; $repo = $this->createMock(DomainRepository::class); $repo->method('findOneByAuthority')->with($authority, $apiKey)->willReturn($foundDomain); diff --git a/module/Core/test/EventDispatcher/LocateVisitTest.php b/module/Core/test/EventDispatcher/LocateVisitTest.php index 63595a6c..80e3e318 100644 --- a/module/Core/test/EventDispatcher/LocateVisitTest.php +++ b/module/Core/test/EventDispatcher/LocateVisitTest.php @@ -155,7 +155,7 @@ class LocateVisitTest extends TestCase } #[Test, DataProvider('provideIpAddresses')] - public function locatableVisitsResolveToLocation(Visit $visit, ?string $originalIpAddress): void + public function locatableVisitsResolveToLocation(Visit $visit, string|null $originalIpAddress): void { $ipAddr = $originalIpAddress ?? $visit->remoteAddr; $location = new Location('', '', '', '', 0.0, 0.0, ''); diff --git a/module/Core/test/EventDispatcher/Matomo/SendVisitToMatomoTest.php b/module/Core/test/EventDispatcher/Matomo/SendVisitToMatomoTest.php index 10726273..ed0ada96 100644 --- a/module/Core/test/EventDispatcher/Matomo/SendVisitToMatomoTest.php +++ b/module/Core/test/EventDispatcher/Matomo/SendVisitToMatomoTest.php @@ -57,7 +57,7 @@ class SendVisitToMatomoTest extends TestCase } #[Test, DataProvider('provideOriginalIpAddress')] - public function visitIsSentWhenItExists(?string $originalIpAddress): void + public function visitIsSentWhenItExists(string|null $originalIpAddress): void { $visitId = '123'; $visit = Visit::forBasePath(Visitor::emptyInstance()); diff --git a/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php b/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php index 08b4cdb7..7686f4ab 100644 --- a/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php +++ b/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php @@ -41,7 +41,7 @@ class PublishingUpdatesGeneratorTest extends TestCase } #[Test, DataProvider('provideMethod')] - public function visitIsProperlySerializedIntoUpdate(string $method, string $expectedTopic, ?string $title): void + public function visitIsProperlySerializedIntoUpdate(string $method, string $expectedTopic, string|null $title): void { $shortUrl = ShortUrl::create(ShortUrlCreation::fromRawData([ 'customSlug' => 'foo', diff --git a/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php b/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php index ac744824..1117d5d3 100644 --- a/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php +++ b/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php @@ -179,7 +179,7 @@ class NotifyVisitToRabbitMqTest extends TestCase ]; } - private function listener(?RabbitMqOptions $options = null): NotifyVisitToRabbitMq + private function listener(RabbitMqOptions|null $options = null): NotifyVisitToRabbitMq { return new NotifyVisitToRabbitMq( $this->helper, diff --git a/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php b/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php index dc604521..3b20ab0c 100644 --- a/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php +++ b/module/Core/test/EventDispatcher/UpdateGeoLiteDbTest.php @@ -77,7 +77,7 @@ class UpdateGeoLiteDbTest extends TestCase int $total, int $downloaded, bool $oldDbExists, - ?string $expectedMessage, + string|null $expectedMessage, ): void { $this->dbUpdater->expects($this->once())->method('checkDbUpdate')->withAnyParameters()->willReturnCallback( function ($_, callable $secondCallback) use ($total, $downloaded, $oldDbExists): GeolocationResult { diff --git a/module/Core/test/Exception/NonUniqueSlugExceptionTest.php b/module/Core/test/Exception/NonUniqueSlugExceptionTest.php index c1e0d158..84ec48eb 100644 --- a/module/Core/test/Exception/NonUniqueSlugExceptionTest.php +++ b/module/Core/test/Exception/NonUniqueSlugExceptionTest.php @@ -12,7 +12,7 @@ use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException; class NonUniqueSlugExceptionTest extends TestCase { #[Test, DataProvider('provideMessages')] - public function properlyCreatesExceptionFromSlug(string $expectedMessage, string $slug, ?string $domain): void + public function properlyCreatesExceptionFromSlug(string $expectedMessage, string $slug, string|null $domain): void { $expectedAdditional = ['customSlug' => $slug]; if ($domain !== null) { diff --git a/module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php b/module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php index aee8a29f..62e0afa2 100644 --- a/module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php +++ b/module/Core/test/Exception/ShortUrlNotFoundExceptionTest.php @@ -16,7 +16,7 @@ class ShortUrlNotFoundExceptionTest extends TestCase public function properlyCreatesExceptionFromNotFoundShortCode( string $expectedMessage, string $shortCode, - ?string $domain, + string|null $domain, ): void { $expectedAdditional = ['shortCode' => $shortCode]; if ($domain !== null) { diff --git a/module/Core/test/Exception/ValidationExceptionTest.php b/module/Core/test/Exception/ValidationExceptionTest.php index 5bb3baa8..3cb87250 100644 --- a/module/Core/test/Exception/ValidationExceptionTest.php +++ b/module/Core/test/Exception/ValidationExceptionTest.php @@ -20,7 +20,7 @@ use function print_r; class ValidationExceptionTest extends TestCase { #[Test, DataProvider('provideExceptions')] - public function createsExceptionFromInputFilter(?Throwable $prev): void + public function createsExceptionFromInputFilter(Throwable|null $prev): void { $invalidData = [ 'foo' => 'bar', diff --git a/module/Core/test/Importer/ImportedLinksProcessorTest.php b/module/Core/test/Importer/ImportedLinksProcessorTest.php index a1816563..36265aa3 100644 --- a/module/Core/test/Importer/ImportedLinksProcessorTest.php +++ b/module/Core/test/Importer/ImportedLinksProcessorTest.php @@ -127,7 +127,7 @@ class ImportedLinksProcessorTest extends TestCase $this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->repo->expects($this->exactly(count($urls)))->method('findOneByImportedUrl')->willReturnCallback( - fn (ImportedShlinkUrl $url): ?ShortUrl => contains( + fn (ImportedShlinkUrl $url): ShortUrl|null => contains( $url->longUrl, ['https://foo', 'https://baz2', 'https://baz3'], ) ? ShortUrl::fromImport($url, true) : null, @@ -175,7 +175,7 @@ class ImportedLinksProcessorTest extends TestCase ImportedShlinkUrl $importedUrl, string $expectedOutput, int $amountOfPersistedVisits, - ?ShortUrl $foundShortUrl, + ShortUrl|null $foundShortUrl, ): void { $this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->repo->expects($this->once())->method('findOneByImportedUrl')->willReturn($foundShortUrl); @@ -232,7 +232,7 @@ class ImportedLinksProcessorTest extends TestCase } #[Test, DataProvider('provideFoundShortUrls')] - public function visitsArePersistedWithProperShortUrl(ShortUrl $originalShortUrl, ?ShortUrl $foundShortUrl): void + public function visitsArePersistedWithProperShortUrl(ShortUrl $originalShortUrl, ShortUrl|null $foundShortUrl): void { $this->em->method('getRepository')->with(ShortUrl::class)->willReturn($this->repo); $this->repo->expects($this->once())->method('findOneByImportedUrl')->willReturn($originalShortUrl); @@ -273,7 +273,7 @@ class ImportedLinksProcessorTest extends TestCase public function properAmountOfOrphanVisitsIsImported( bool $importOrphanVisits, iterable $visits, - ?Visit $lastOrphanVisit, + Visit|null $lastOrphanVisit, int $expectedImportedVisits, ): void { $this->io->expects($this->exactly($importOrphanVisits ? 2 : 1))->method('title'); diff --git a/module/Core/test/Matomo/MatomoTrackerBuilderTest.php b/module/Core/test/Matomo/MatomoTrackerBuilderTest.php index 1b55405e..e0bd0fde 100644 --- a/module/Core/test/Matomo/MatomoTrackerBuilderTest.php +++ b/module/Core/test/Matomo/MatomoTrackerBuilderTest.php @@ -43,7 +43,7 @@ class MatomoTrackerBuilderTest extends TestCase self::assertEquals(MatomoTrackerBuilder::MATOMO_DEFAULT_TIMEOUT, $tracker->getRequestConnectTimeout()); } - private function builder(?MatomoOptions $options = null): MatomoTrackerBuilder + private function builder(MatomoOptions|null $options = null): MatomoTrackerBuilder { $options ??= new MatomoOptions(enabled: true, baseUrl: 'base_url', siteId: 5, apiToken: 'api_token'); return new MatomoTrackerBuilder($options); diff --git a/module/Core/test/Matomo/MatomoVisitSenderTest.php b/module/Core/test/Matomo/MatomoVisitSenderTest.php index 6a4659f1..bf568bfb 100644 --- a/module/Core/test/Matomo/MatomoVisitSenderTest.php +++ b/module/Core/test/Matomo/MatomoVisitSenderTest.php @@ -43,7 +43,7 @@ class MatomoVisitSenderTest extends TestCase } #[Test, DataProvider('provideTrackerMethods')] - public function visitIsSentToMatomo(Visit $visit, ?string $originalIpAddress, array $invokedMethods): void + public function visitIsSentToMatomo(Visit $visit, string|null $originalIpAddress, array $invokedMethods): void { $tracker = $this->createMock(MatomoTracker::class); $tracker->expects($this->once())->method('setUrl')->willReturn($tracker); diff --git a/module/Core/test/RedirectRule/Entity/RedirectConditionTest.php b/module/Core/test/RedirectRule/Entity/RedirectConditionTest.php index 3cd44ef0..b31d1fd3 100644 --- a/module/Core/test/RedirectRule/Entity/RedirectConditionTest.php +++ b/module/Core/test/RedirectRule/Entity/RedirectConditionTest.php @@ -42,7 +42,7 @@ class RedirectConditionTest extends TestCase #[TestWith(['en-UK', 'en', true], 'only lang')] #[TestWith(['es-AR', 'en', false], 'different only lang')] #[TestWith(['fr', 'fr-FR', false], 'less restrictive matching locale')] - public function matchesLanguage(?string $acceptLanguage, string $value, bool $expected): void + public function matchesLanguage(string|null $acceptLanguage, string $value, bool $expected): void { $request = ServerRequestFactory::fromGlobals(); if ($acceptLanguage !== null) { @@ -62,7 +62,7 @@ class RedirectConditionTest extends TestCase #[TestWith([IOS_USER_AGENT, DeviceType::IOS, true])] #[TestWith([IOS_USER_AGENT, DeviceType::ANDROID, false])] #[TestWith([DESKTOP_USER_AGENT, DeviceType::IOS, false])] - public function matchesDevice(?string $userAgent, DeviceType $value, bool $expected): void + public function matchesDevice(string|null $userAgent, DeviceType $value, bool $expected): void { $request = ServerRequestFactory::fromGlobals(); if ($userAgent !== null) { @@ -82,7 +82,7 @@ class RedirectConditionTest extends TestCase #[TestWith(['1.2.3.4', '192.168.1.0/24', false], 'no CIDR block match')] #[TestWith(['192.168.1.35', '192.168.1.*', true], 'wildcard pattern match')] #[TestWith(['1.2.3.4', '192.168.1.*', false], 'no wildcard pattern match')] - public function matchesRemoteIpAddress(?string $remoteIp, string $ipToMatch, bool $expected): void + public function matchesRemoteIpAddress(string|null $remoteIp, string $ipToMatch, bool $expected): void { $request = ServerRequestFactory::fromGlobals(); if ($remoteIp !== null) { diff --git a/module/Core/test/RedirectRule/ShortUrlRedirectionResolverTest.php b/module/Core/test/RedirectRule/ShortUrlRedirectionResolverTest.php index 3bf23863..f26627c6 100644 --- a/module/Core/test/RedirectRule/ShortUrlRedirectionResolverTest.php +++ b/module/Core/test/RedirectRule/ShortUrlRedirectionResolverTest.php @@ -36,7 +36,7 @@ class ShortUrlRedirectionResolverTest extends TestCase #[Test, DataProvider('provideData')] public function resolveLongUrlReturnsExpectedValue( ServerRequestInterface $request, - ?RedirectCondition $condition, + RedirectCondition|null $condition, string $expectedUrl, ): void { $shortUrl = ShortUrl::create(ShortUrlCreation::fromRawData([ diff --git a/module/Core/test/ShortUrl/Entity/ShortUrlTest.php b/module/Core/test/ShortUrl/Entity/ShortUrlTest.php index b3720254..29e9d88c 100644 --- a/module/Core/test/ShortUrl/Entity/ShortUrlTest.php +++ b/module/Core/test/ShortUrl/Entity/ShortUrlTest.php @@ -75,7 +75,7 @@ class ShortUrlTest extends TestCase } #[Test, DataProvider('provideLengths')] - public function shortCodesHaveExpectedLength(?int $length, int $expectedLength): void + public function shortCodesHaveExpectedLength(int|null $length, int $expectedLength): void { $shortUrl = ShortUrl::create(ShortUrlCreation::fromRawData( [ShortUrlInputFilter::SHORT_CODE_LENGTH => $length, 'longUrl' => 'https://longUrl'], @@ -94,7 +94,7 @@ class ShortUrlTest extends TestCase #[TestWith([null, '', 5])] #[TestWith(['foo bar/', 'foo-bar-', 13])] public function shortCodesHaveExpectedPrefix( - ?string $pathPrefix, + string|null $pathPrefix, string $expectedPrefix, int $expectedShortCodeLength, ): void { diff --git a/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php b/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php index de1402f6..f341585e 100644 --- a/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php @@ -32,7 +32,7 @@ class ShortCodeUniquenessHelperTest extends TestCase } #[Test, DataProvider('provideDomains')] - public function shortCodeIsRegeneratedIfAlreadyInUse(?Domain $domain, ?string $expectedAuthority): void + public function shortCodeIsRegeneratedIfAlreadyInUse(Domain|null $domain, string|null $expectedAuthority): void { $callIndex = 0; $expectedCalls = 3; diff --git a/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php b/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php index d1283a78..6f48a836 100644 --- a/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php @@ -35,8 +35,8 @@ class ShortUrlRedirectionBuilderTest extends TestCase public function buildShortUrlRedirectBuildsExpectedUrl( string $expectedUrl, ServerRequestInterface $request, - ?string $extraPath, - ?bool $forwardQuery, + string|null $extraPath, + bool|null $forwardQuery, ): void { $shortUrl = ShortUrl::create(ShortUrlCreation::fromRawData([ 'longUrl' => 'https://example.com/foo/bar?some=thing', diff --git a/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php b/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php index d28fdf0e..03799e10 100644 --- a/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php @@ -32,7 +32,7 @@ class ShortUrlStringifierTest extends TestCase public static function provideConfigAndShortUrls(): iterable { - $shortUrlWithShortCode = fn (string $shortCode, ?string $domain = null) => ShortUrl::create( + $shortUrlWithShortCode = fn (string $shortCode, string|null $domain = null) => ShortUrl::create( ShortUrlCreation::fromRawData([ 'longUrl' => 'https://longUrl', 'customSlug' => $shortCode, diff --git a/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php b/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php index 6815acb6..85168020 100644 --- a/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php +++ b/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php @@ -70,7 +70,7 @@ class ExtraPathRedirectMiddlewareTest extends TestCase public static function provideNonRedirectingRequests(): iterable { $baseReq = ServerRequestFactory::fromGlobals(); - $buildReq = static fn (?NotFoundType $type): ServerRequestInterface => + $buildReq = static fn (NotFoundType|null $type): ServerRequestInterface => $baseReq->withAttribute(NotFoundType::class, $type); yield 'disabled option' => [false, false, $buildReq(NotFoundType::fromRequest($baseReq, '/foo/bar'))]; @@ -127,7 +127,7 @@ class ExtraPathRedirectMiddlewareTest extends TestCase public function visitIsTrackedAndRedirectIsReturnedWhenShortUrlIsFoundAfterExpectedAmountOfIterations( bool $multiSegmentEnabled, int $expectedResolveCalls, - ?string $expectedExtraPath, + string|null $expectedExtraPath, ): void { $options = new UrlShortenerOptions(appendExtraPath: true, multiSegmentSlugsEnabled: $multiSegmentEnabled); @@ -170,7 +170,7 @@ class ExtraPathRedirectMiddlewareTest extends TestCase yield [true, 3, null]; } - private function middleware(?UrlShortenerOptions $options = null): ExtraPathRedirectMiddleware + private function middleware(UrlShortenerOptions|null $options = null): ExtraPathRedirectMiddleware { return new ExtraPathRedirectMiddleware( $this->resolver, diff --git a/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php b/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php index e963923b..ed9c6459 100644 --- a/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php +++ b/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php @@ -147,7 +147,7 @@ class ShortUrlCreationTest extends TestCase } #[Test, DataProvider('provideTitles')] - public function titleIsCroppedIfTooLong(?string $title, ?string $expectedTitle): void + public function titleIsCroppedIfTooLong(string|null $title, string|null $expectedTitle): void { $creation = ShortUrlCreation::fromRawData([ 'title' => $title, @@ -170,7 +170,7 @@ class ShortUrlCreationTest extends TestCase } #[Test, DataProvider('provideDomains')] - public function emptyDomainIsDiscarded(?string $domain, ?string $expectedDomain): void + public function emptyDomainIsDiscarded(string|null $domain, string|null $expectedDomain): void { $creation = ShortUrlCreation::fromRawData([ 'domain' => $domain, diff --git a/module/Core/test/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapterTest.php b/module/Core/test/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapterTest.php index 2ef213d2..473c2320 100644 --- a/module/Core/test/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapterTest.php +++ b/module/Core/test/ShortUrl/Paginator/Adapter/ShortUrlRepositoryAdapterTest.php @@ -28,11 +28,11 @@ class ShortUrlRepositoryAdapterTest extends TestCase #[Test, DataProvider('provideFilteringArgs')] public function getItemsFallsBackToFindList( - ?string $searchTerm = null, + string|null $searchTerm = null, array $tags = [], - ?string $startDate = null, - ?string $endDate = null, - ?string $orderBy = null, + string|null $startDate = null, + string|null $endDate = null, + string|null $orderBy = null, ): void { $params = ShortUrlsParams::fromRawData([ 'searchTerm' => $searchTerm, @@ -54,10 +54,10 @@ class ShortUrlRepositoryAdapterTest extends TestCase #[Test, DataProvider('provideFilteringArgs')] public function countFallsBackToCountList( - ?string $searchTerm = null, + string|null $searchTerm = null, array $tags = [], - ?string $startDate = null, - ?string $endDate = null, + string|null $startDate = null, + string|null $endDate = null, ): void { $params = ShortUrlsParams::fromRawData([ 'searchTerm' => $searchTerm, diff --git a/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php b/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php index 722ac347..934d8511 100644 --- a/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php +++ b/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php @@ -33,7 +33,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase } #[Test, DataProvider('provideDomainsThatEmpty')] - public function returnsEmptyInSomeCases(?string $domain): void + public function returnsEmptyInSomeCases(string|null $domain): void { $this->em->expects($this->never())->method('getRepository')->with(Domain::class); self::assertNull($this->resolver->resolveDomain($domain)); @@ -46,7 +46,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase } #[Test, DataProvider('provideFoundDomains')] - public function findsOrCreatesDomainWhenValueIsProvided(?Domain $foundDomain, string $authority): void + public function findsOrCreatesDomainWhenValueIsProvided(Domain|null $foundDomain, string $authority): void { $repo = $this->createMock(DomainRepository::class); $repo->expects($this->once())->method('findOneBy')->with(['authority' => $authority])->willReturn($foundDomain); @@ -79,7 +79,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase $tagRepo = $this->createMock(TagRepository::class); $tagRepo->expects($this->exactly($expectedLookedOutTags))->method('findOneBy')->with( $this->isType('array'), - )->willReturnCallback(function (array $criteria): ?Tag { + )->willReturnCallback(function (array $criteria): Tag|null { ['name' => $name] = $criteria; return $name === 'foo' ? new Tag($name) : null; }); diff --git a/module/Core/test/ShortUrl/Resolver/SimpleShortUrlRelationResolverTest.php b/module/Core/test/ShortUrl/Resolver/SimpleShortUrlRelationResolverTest.php index f74480ba..95e95785 100644 --- a/module/Core/test/ShortUrl/Resolver/SimpleShortUrlRelationResolverTest.php +++ b/module/Core/test/ShortUrl/Resolver/SimpleShortUrlRelationResolverTest.php @@ -21,7 +21,7 @@ class SimpleShortUrlRelationResolverTest extends TestCase } #[Test, DataProvider('provideDomains')] - public function resolvesExpectedDomain(?string $domain): void + public function resolvesExpectedDomain(string|null $domain): void { $result = $this->resolver->resolveDomain($domain); diff --git a/module/Core/test/ShortUrl/ShortUrlListServiceTest.php b/module/Core/test/ShortUrl/ShortUrlListServiceTest.php index 2ae5c584..c22bc206 100644 --- a/module/Core/test/ShortUrl/ShortUrlListServiceTest.php +++ b/module/Core/test/ShortUrl/ShortUrlListServiceTest.php @@ -30,7 +30,7 @@ class ShortUrlListServiceTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function listedUrlsAreReturnedFromEntityManager(?ApiKey $apiKey): void + public function listedUrlsAreReturnedFromEntityManager(ApiKey|null $apiKey): void { $list = [ ShortUrl::createFake(), diff --git a/module/Core/test/ShortUrl/ShortUrlResolverTest.php b/module/Core/test/ShortUrl/ShortUrlResolverTest.php index e8443a13..24571b41 100644 --- a/module/Core/test/ShortUrl/ShortUrlResolverTest.php +++ b/module/Core/test/ShortUrl/ShortUrlResolverTest.php @@ -42,7 +42,7 @@ class ShortUrlResolverTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function shortCodeIsProperlyParsed(?ApiKey $apiKey): void + public function shortCodeIsProperlyParsed(ApiKey|null $apiKey): void { $shortUrl = ShortUrl::withLongUrl('https://expected_url'); $shortCode = $shortUrl->getShortCode(); @@ -59,7 +59,7 @@ class ShortUrlResolverTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function exceptionIsThrownIfShortCodeIsNotFound(?ApiKey $apiKey): void + public function exceptionIsThrownIfShortCodeIsNotFound(ApiKey|null $apiKey): void { $shortCode = 'abc123'; $identifier = ShortUrlIdentifier::fromShortCodeAndDomain($shortCode); diff --git a/module/Core/test/ShortUrl/ShortUrlServiceTest.php b/module/Core/test/ShortUrl/ShortUrlServiceTest.php index 669015a0..c3554363 100644 --- a/module/Core/test/ShortUrl/ShortUrlServiceTest.php +++ b/module/Core/test/ShortUrl/ShortUrlServiceTest.php @@ -48,7 +48,7 @@ class ShortUrlServiceTest extends TestCase public function updateShortUrlUpdatesProvidedData( InvocationOrder $expectedValidateCalls, ShortUrlEdition $shortUrlEdit, - ?ApiKey $apiKey, + ApiKey|null $apiKey, ): void { $originalLongUrl = 'https://originalLongUrl'; $shortUrl = ShortUrl::withLongUrl($originalLongUrl); diff --git a/module/Core/test/Tag/TagServiceTest.php b/module/Core/test/Tag/TagServiceTest.php index f22a35f2..7e82eb1c 100644 --- a/module/Core/test/Tag/TagServiceTest.php +++ b/module/Core/test/Tag/TagServiceTest.php @@ -55,7 +55,7 @@ class TagServiceTest extends TestCase #[Test, DataProvider('provideApiKeysAndSearchTerm')] public function tagsInfoDelegatesOnRepository( - ?ApiKey $apiKey, + ApiKey|null $apiKey, TagsParams $params, TagsListFiltering $expectedFiltering, int $countCalls, @@ -101,7 +101,7 @@ class TagServiceTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function deleteTagsDelegatesOnRepository(?ApiKey $apiKey): void + public function deleteTagsDelegatesOnRepository(ApiKey|null $apiKey): void { $this->repo->expects($this->once())->method('deleteByName')->with(['foo', 'bar'])->willReturn(4); $this->service->deleteTags(['foo', 'bar'], $apiKey); @@ -122,7 +122,7 @@ class TagServiceTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function renameInvalidTagThrowsException(?ApiKey $apiKey): void + public function renameInvalidTagThrowsException(ApiKey|null $apiKey): void { $this->repo->expects($this->once())->method('findOneBy')->willReturn(null); $this->expectException(TagNotFoundException::class); @@ -152,7 +152,7 @@ class TagServiceTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function renameTagToAnExistingNameThrowsException(?ApiKey $apiKey): void + public function renameTagToAnExistingNameThrowsException(ApiKey|null $apiKey): void { $this->repo->expects($this->once())->method('findOneBy')->willReturn(new Tag('foo')); $this->repo->expects($this->once())->method('count')->willReturn(1); diff --git a/module/Core/test/Util/RedirectResponseHelperTest.php b/module/Core/test/Util/RedirectResponseHelperTest.php index 89d3fa5a..b01333d5 100644 --- a/module/Core/test/Util/RedirectResponseHelperTest.php +++ b/module/Core/test/Util/RedirectResponseHelperTest.php @@ -18,7 +18,7 @@ class RedirectResponseHelperTest extends TestCase int $configuredStatus, int $configuredLifetime, int $expectedStatus, - ?string $expectedCacheControl, + string|null $expectedCacheControl, ): void { $options = new RedirectOptions($configuredStatus, $configuredLifetime); @@ -46,7 +46,7 @@ class RedirectResponseHelperTest extends TestCase yield 'status 308 with negative expiration' => [308, -20, 308, 'private,max-age=30']; } - private function helper(?RedirectOptions $options = null): RedirectResponseHelper + private function helper(RedirectOptions|null $options = null): RedirectResponseHelper { return new RedirectResponseHelper($options ?? new RedirectOptions()); } diff --git a/module/Core/test/Visit/Entity/VisitTest.php b/module/Core/test/Visit/Entity/VisitTest.php index 923b2e6b..3556c1f1 100644 --- a/module/Core/test/Visit/Entity/VisitTest.php +++ b/module/Core/test/Visit/Entity/VisitTest.php @@ -103,8 +103,11 @@ class VisitTest extends TestCase } #[Test, DataProvider('provideAddresses')] - public function addressIsAnonymizedWhenRequested(bool $anonymize, ?string $address, ?string $expectedAddress): void - { + public function addressIsAnonymizedWhenRequested( + bool $anonymize, + string|null $address, + string|null $expectedAddress, + ): void { $visit = Visit::forValidShortUrl( ShortUrl::createFake(), new Visitor('Chrome', 'some site', $address, ''), diff --git a/module/Core/test/Visit/Paginator/Adapter/ShortUrlVisitsPaginatorAdapterTest.php b/module/Core/test/Visit/Paginator/Adapter/ShortUrlVisitsPaginatorAdapterTest.php index c96e5be5..d1f7c89b 100644 --- a/module/Core/test/Visit/Paginator/Adapter/ShortUrlVisitsPaginatorAdapterTest.php +++ b/module/Core/test/Visit/Paginator/Adapter/ShortUrlVisitsPaginatorAdapterTest.php @@ -58,7 +58,7 @@ class ShortUrlVisitsPaginatorAdapterTest extends TestCase } } - private function createAdapter(?ApiKey $apiKey): ShortUrlVisitsPaginatorAdapter + private function createAdapter(ApiKey|null $apiKey): ShortUrlVisitsPaginatorAdapter { return new ShortUrlVisitsPaginatorAdapter( $this->repo, diff --git a/module/Core/test/Visit/Paginator/Adapter/VisitsForTagPaginatorAdapterTest.php b/module/Core/test/Visit/Paginator/Adapter/VisitsForTagPaginatorAdapterTest.php index 59ce2082..c0cd4d0b 100644 --- a/module/Core/test/Visit/Paginator/Adapter/VisitsForTagPaginatorAdapterTest.php +++ b/module/Core/test/Visit/Paginator/Adapter/VisitsForTagPaginatorAdapterTest.php @@ -57,7 +57,7 @@ class VisitsForTagPaginatorAdapterTest extends TestCase } } - private function createAdapter(?ApiKey $apiKey): TagVisitsPaginatorAdapter + private function createAdapter(ApiKey|null $apiKey): TagVisitsPaginatorAdapter { return new TagVisitsPaginatorAdapter($this->repo, 'foo', VisitsParams::fromRawData([]), $apiKey); } diff --git a/module/Core/test/Visit/VisitsStatsHelperTest.php b/module/Core/test/Visit/VisitsStatsHelperTest.php index 61fb1293..10c11b64 100644 --- a/module/Core/test/Visit/VisitsStatsHelperTest.php +++ b/module/Core/test/Visit/VisitsStatsHelperTest.php @@ -56,7 +56,7 @@ class VisitsStatsHelperTest extends TestCase } #[Test, DataProvider('provideCounts')] - public function returnsExpectedVisitsStats(int $expectedCount, ?ApiKey $apiKey): void + public function returnsExpectedVisitsStats(int $expectedCount, ApiKey|null $apiKey): void { $callCount = 0; $visitsCountRepo = $this->createMock(ShortUrlVisitsCountRepository::class); @@ -94,7 +94,7 @@ class VisitsStatsHelperTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function infoReturnsVisitsForCertainShortCode(?ApiKey $apiKey): void + public function infoReturnsVisitsForCertainShortCode(ApiKey|null $apiKey): void { $shortCode = '123ABC'; $identifier = ShortUrlIdentifier::fromShortCodeAndDomain($shortCode); @@ -157,7 +157,7 @@ class VisitsStatsHelperTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function visitsForTagAreReturnedAsExpected(?ApiKey $apiKey): void + public function visitsForTagAreReturnedAsExpected(ApiKey|null $apiKey): void { $tag = 'foo'; $repo = $this->createMock(TagRepository::class); @@ -198,7 +198,7 @@ class VisitsStatsHelperTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function visitsForNonDefaultDomainAreReturnedAsExpected(?ApiKey $apiKey): void + public function visitsForNonDefaultDomainAreReturnedAsExpected(ApiKey|null $apiKey): void { $domain = 'foo.com'; $repo = $this->createMock(DomainRepository::class); @@ -229,7 +229,7 @@ class VisitsStatsHelperTest extends TestCase } #[Test, DataProviderExternal(ApiKeyDataProviders::class, 'adminApiKeysProvider')] - public function visitsForDefaultDomainAreReturnedAsExpected(?ApiKey $apiKey): void + public function visitsForDefaultDomainAreReturnedAsExpected(ApiKey|null $apiKey): void { $repo = $this->createMock(DomainRepository::class); $repo->expects($this->never())->method('domainExists'); diff --git a/module/Core/test/Visit/VisitsTrackerTest.php b/module/Core/test/Visit/VisitsTrackerTest.php index 414f5254..f45a27d8 100644 --- a/module/Core/test/Visit/VisitsTrackerTest.php +++ b/module/Core/test/Visit/VisitsTrackerTest.php @@ -79,7 +79,7 @@ class VisitsTrackerTest extends TestCase yield 'trackRegularNotFoundVisit' => ['trackRegularNotFoundVisit']; } - private function visitsTracker(?TrackingOptions $options = null): VisitsTracker + private function visitsTracker(TrackingOptions|null $options = null): VisitsTracker { return new VisitsTracker($this->em, $this->eventDispatcher, $options ?? new TrackingOptions()); } diff --git a/module/Rest/src/Action/Domain/Request/DomainRedirectsRequest.php b/module/Rest/src/Action/Domain/Request/DomainRedirectsRequest.php index e2b27e23..0c55f967 100644 --- a/module/Rest/src/Action/Domain/Request/DomainRedirectsRequest.php +++ b/module/Rest/src/Action/Domain/Request/DomainRedirectsRequest.php @@ -14,11 +14,11 @@ use function array_key_exists; class DomainRedirectsRequest { private string $authority; - private ?string $baseUrlRedirect = null; + private string|null $baseUrlRedirect = null; private bool $baseUrlRedirectWasProvided = false; - private ?string $regular404Redirect = null; + private string|null $regular404Redirect = null; private bool $regular404RedirectWasProvided = false; - private ?string $invalidShortUrlRedirect = null; + private string|null $invalidShortUrlRedirect = null; private bool $invalidShortUrlRedirectWasProvided = false; private function __construct() @@ -66,7 +66,7 @@ class DomainRedirectsRequest return $this->authority; } - public function toNotFoundRedirects(?NotFoundRedirectConfigInterface $defaults = null): NotFoundRedirects + public function toNotFoundRedirects(NotFoundRedirectConfigInterface|null $defaults = null): NotFoundRedirects { return NotFoundRedirects::withRedirects( $this->baseUrlRedirectWasProvided ? $this->baseUrlRedirect : $defaults?->baseUrlRedirect(), diff --git a/module/Rest/src/ApiKey/Model/ApiKeyMeta.php b/module/Rest/src/ApiKey/Model/ApiKeyMeta.php index e28a9ec3..020c1f27 100644 --- a/module/Rest/src/ApiKey/Model/ApiKeyMeta.php +++ b/module/Rest/src/ApiKey/Model/ApiKeyMeta.php @@ -14,8 +14,8 @@ final class ApiKeyMeta */ private function __construct( public readonly string $key, - public readonly ?string $name, - public readonly ?Chronos $expirationDate, + public readonly string|null $name, + public readonly Chronos|null $expirationDate, public readonly iterable $roleDefinitions, ) { } @@ -29,9 +29,9 @@ final class ApiKeyMeta * @param iterable $roleDefinitions */ public static function fromParams( - ?string $key = null, - ?string $name = null, - ?Chronos $expirationDate = null, + string|null $key = null, + string|null $name = null, + Chronos|null $expirationDate = null, iterable $roleDefinitions = [], ): self { return new self( diff --git a/module/Rest/src/ApiKey/Repository/ApiKeyRepository.php b/module/Rest/src/ApiKey/Repository/ApiKeyRepository.php index 2b7aa0a2..2d82b23e 100644 --- a/module/Rest/src/ApiKey/Repository/ApiKeyRepository.php +++ b/module/Rest/src/ApiKey/Repository/ApiKeyRepository.php @@ -17,10 +17,10 @@ class ApiKeyRepository extends EntitySpecificationRepository implements ApiKeyRe /** * Will create provided API key with admin permissions, only if there's no other API keys yet */ - public function createInitialApiKey(string $apiKey): ?ApiKey + public function createInitialApiKey(string $apiKey): ApiKey|null { $em = $this->getEntityManager(); - return $em->wrapInTransaction(function () use ($apiKey, $em): ?ApiKey { + return $em->wrapInTransaction(function () use ($apiKey, $em): ApiKey|null { // Ideally this would be a SELECT COUNT(...), but MsSQL and Postgres do not allow locking on aggregates // Because of that we check if at least one result exists $firstResult = $em->createQueryBuilder()->select('a.id') diff --git a/module/Rest/src/ApiKey/Repository/ApiKeyRepositoryInterface.php b/module/Rest/src/ApiKey/Repository/ApiKeyRepositoryInterface.php index 57c2a7f6..04e55519 100644 --- a/module/Rest/src/ApiKey/Repository/ApiKeyRepositoryInterface.php +++ b/module/Rest/src/ApiKey/Repository/ApiKeyRepositoryInterface.php @@ -16,5 +16,5 @@ interface ApiKeyRepositoryInterface extends ObjectRepository, EntitySpecificatio /** * Will create provided API key only if there's no API keys yet */ - public function createInitialApiKey(string $apiKey): ?ApiKey; + public function createInitialApiKey(string $apiKey): ApiKey|null; } diff --git a/module/Rest/src/ApiKey/Role.php b/module/Rest/src/ApiKey/Role.php index 4f3685db..7cca292d 100644 --- a/module/Rest/src/ApiKey/Role.php +++ b/module/Rest/src/ApiKey/Role.php @@ -38,7 +38,7 @@ enum Role: string }; } - public static function toSpec(ApiKeyRole $role, ?string $context = null): Specification + public static function toSpec(ApiKeyRole $role, string|null $context = null): Specification { return match ($role->role) { self::AUTHORED_SHORT_URLS => new BelongsToApiKey($role->apiKey, $context), diff --git a/module/Rest/src/ApiKey/Spec/WithApiKeySpecsEnsuringJoin.php b/module/Rest/src/ApiKey/Spec/WithApiKeySpecsEnsuringJoin.php index 122829ed..d7c2e7ba 100644 --- a/module/Rest/src/ApiKey/Spec/WithApiKeySpecsEnsuringJoin.php +++ b/module/Rest/src/ApiKey/Spec/WithApiKeySpecsEnsuringJoin.php @@ -11,8 +11,10 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; class WithApiKeySpecsEnsuringJoin extends BaseSpecification { - public function __construct(private readonly ?ApiKey $apiKey, private readonly string $fieldToJoin = 'shortUrls') - { + public function __construct( + private readonly ApiKey|null $apiKey, + private readonly string $fieldToJoin = 'shortUrls', + ) { parent::__construct(); } diff --git a/module/Rest/src/ConfigProvider.php b/module/Rest/src/ConfigProvider.php index 067c6952..1768c7c8 100644 --- a/module/Rest/src/ConfigProvider.php +++ b/module/Rest/src/ConfigProvider.php @@ -33,7 +33,7 @@ class ConfigProvider return $healthRoute !== null ? [...$prefixedRoutes, $healthRoute] : $prefixedRoutes; } - private static function buildUnversionedHealthRouteFromExistingRoutes(array $routes): ?array + private static function buildUnversionedHealthRouteFromExistingRoutes(array $routes): array|null { $healthRoutes = array_filter($routes, fn (array $route) => $route['path'] === '/health'); $healthRoute = reset($healthRoutes); diff --git a/module/Rest/src/Entity/ApiKey.php b/module/Rest/src/Entity/ApiKey.php index 46548dcf..1cca4f3a 100644 --- a/module/Rest/src/Entity/ApiKey.php +++ b/module/Rest/src/Entity/ApiKey.php @@ -23,8 +23,8 @@ class ApiKey extends AbstractEntity */ private function __construct( private string $key, - public readonly ?string $name = null, - public readonly ?Chronos $expirationDate = null, + public readonly string|null $name = null, + public readonly Chronos|null $expirationDate = null, private bool $enabled = true, private Collection $roles = new ArrayCollection(), ) { @@ -85,7 +85,7 @@ class ApiKey extends AbstractEntity return $this->key; } - public function spec(?string $context = null): Specification + public function spec(string|null $context = null): Specification { $specs = $this->roles->map(fn (ApiKeyRole $role) => Role::toSpec($role, $context))->getValues(); return Spec::andX(...$specs); @@ -100,7 +100,7 @@ class ApiKey extends AbstractEntity /** * @return ($apiKey is null ? true : boolean) */ - public static function isAdmin(?ApiKey $apiKey): bool + public static function isAdmin(ApiKey|null $apiKey): bool { return $apiKey === null || $apiKey->roles->isEmpty(); } @@ -108,7 +108,7 @@ class ApiKey extends AbstractEntity /** * Tells if provided API key has any of the roles restricting at the short URL level */ - public static function isShortUrlRestricted(?ApiKey $apiKey): bool + public static function isShortUrlRestricted(ApiKey|null $apiKey): bool { if ($apiKey === null) { return false; diff --git a/module/Rest/src/Service/ApiKeyCheckResult.php b/module/Rest/src/Service/ApiKeyCheckResult.php index ff74fb79..4a1fc1cf 100644 --- a/module/Rest/src/Service/ApiKeyCheckResult.php +++ b/module/Rest/src/Service/ApiKeyCheckResult.php @@ -8,7 +8,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; final class ApiKeyCheckResult { - public function __construct(public readonly ?ApiKey $apiKey = null) + public function __construct(public readonly ApiKey|null $apiKey = null) { } diff --git a/module/Rest/src/Service/ApiKeyService.php b/module/Rest/src/Service/ApiKeyService.php index 21f69f90..6c825a4a 100644 --- a/module/Rest/src/Service/ApiKeyService.php +++ b/module/Rest/src/Service/ApiKeyService.php @@ -28,7 +28,7 @@ class ApiKeyService implements ApiKeyServiceInterface return $apiKey; } - public function createInitial(string $key): ?ApiKey + public function createInitial(string $key): ApiKey|null { /** @var ApiKeyRepositoryInterface $repo */ $repo = $this->em->getRepository(ApiKey::class); @@ -67,7 +67,7 @@ class ApiKeyService implements ApiKeyServiceInterface return $apiKeys; } - private function getByKey(string $key): ?ApiKey + private function getByKey(string $key): ApiKey|null { /** @var ApiKey|null $apiKey */ $apiKey = $this->em->getRepository(ApiKey::class)->findOneBy([ diff --git a/module/Rest/src/Service/ApiKeyServiceInterface.php b/module/Rest/src/Service/ApiKeyServiceInterface.php index b82d7760..167041c5 100644 --- a/module/Rest/src/Service/ApiKeyServiceInterface.php +++ b/module/Rest/src/Service/ApiKeyServiceInterface.php @@ -12,7 +12,7 @@ interface ApiKeyServiceInterface { public function create(ApiKeyMeta $apiKeyMeta): ApiKey; - public function createInitial(string $key): ?ApiKey; + public function createInitial(string $key): ApiKey|null; public function check(string $key): ApiKeyCheckResult; diff --git a/module/Rest/test-api/Action/CreateShortUrlTest.php b/module/Rest/test-api/Action/CreateShortUrlTest.php index 42742bbb..212b545c 100644 --- a/module/Rest/test-api/Action/CreateShortUrlTest.php +++ b/module/Rest/test-api/Action/CreateShortUrlTest.php @@ -39,7 +39,7 @@ class CreateShortUrlTest extends ApiTestCase } #[Test, DataProvider('provideConflictingSlugs')] - public function failsToCreateShortUrlWithDuplicatedSlug(string $slug, ?string $domain): void + public function failsToCreateShortUrlWithDuplicatedSlug(string $slug, string|null $domain): void { $suffix = $domain === null ? '' : sprintf(' for domain "%s"', $domain); $detail = sprintf('Provided slug "%s" is already in use%s.', $slug, $suffix); @@ -171,8 +171,10 @@ class CreateShortUrlTest extends ApiTestCase } #[Test, DataProvider('provideConflictingSlugs')] - public function returnsErrorWhenRequestingReturnExistingButCustomSlugIsInUse(string $slug, ?string $domain): void - { + public function returnsErrorWhenRequestingReturnExistingButCustomSlugIsInUse( + string $slug, + string|null $domain, + ): void { $longUrl = 'https://www.alejandrocelaya.com'; [$firstStatusCode] = $this->createShortUrl(['longUrl' => $longUrl]); @@ -269,7 +271,7 @@ class CreateShortUrlTest extends ApiTestCase } #[Test, DataProvider('provideDomains')] - public function apiKeyDomainIsEnforced(?string $providedDomain): void + public function apiKeyDomainIsEnforced(string|null $providedDomain): void { [$statusCode, ['domain' => $returnedDomain]] = $this->createShortUrl( ['domain' => $providedDomain], @@ -315,7 +317,7 @@ class CreateShortUrlTest extends ApiTestCase #[Test] #[TestWith([null])] #[TestWith(['my-custom-slug'])] - public function prefixCanBeSet(?string $customSlug): void + public function prefixCanBeSet(string|null $customSlug): void { [$statusCode, $payload] = $this->createShortUrl([ 'longUrl' => 'https://github.com/shlinkio/shlink/issues/1557', diff --git a/module/Rest/test-api/Action/DeleteShortUrlTest.php b/module/Rest/test-api/Action/DeleteShortUrlTest.php index 06848c48..90df09c4 100644 --- a/module/Rest/test-api/Action/DeleteShortUrlTest.php +++ b/module/Rest/test-api/Action/DeleteShortUrlTest.php @@ -18,7 +18,7 @@ class DeleteShortUrlTest extends ApiTestCase #[Test, DataProviderExternal(ApiTestDataProviders::class, 'invalidUrlsProvider')] public function notFoundErrorIsReturnWhenDeletingInvalidUrl( string $shortCode, - ?string $domain, + string|null $domain, string $expectedDetail, string $apiKey, ): void { diff --git a/module/Rest/test-api/Action/EditShortUrlTest.php b/module/Rest/test-api/Action/EditShortUrlTest.php index 24f91e58..2146a95c 100644 --- a/module/Rest/test-api/Action/EditShortUrlTest.php +++ b/module/Rest/test-api/Action/EditShortUrlTest.php @@ -90,7 +90,7 @@ class EditShortUrlTest extends ApiTestCase #[Test, DataProviderExternal(ApiTestDataProviders::class, 'invalidUrlsProvider')] public function tryingToEditInvalidUrlReturnsNotFoundError( string $shortCode, - ?string $domain, + string|null $domain, string $expectedDetail, string $apiKey, ): void { @@ -125,7 +125,7 @@ class EditShortUrlTest extends ApiTestCase } #[Test, DataProvider('provideDomains')] - public function metadataIsEditedOnProperShortUrlBasedOnDomain(?string $domain, string $expectedUrl): void + public function metadataIsEditedOnProperShortUrlBasedOnDomain(string|null $domain, string $expectedUrl): void { $shortCode = 'ghi789'; $url = new Uri(sprintf('/short-urls/%s', $shortCode)); diff --git a/module/Rest/test-api/Action/ResolveShortUrlTest.php b/module/Rest/test-api/Action/ResolveShortUrlTest.php index 0c0ce5ec..e02c9247 100644 --- a/module/Rest/test-api/Action/ResolveShortUrlTest.php +++ b/module/Rest/test-api/Action/ResolveShortUrlTest.php @@ -45,7 +45,7 @@ class ResolveShortUrlTest extends ApiTestCase #[Test, DataProviderExternal(ApiTestDataProviders::class, 'invalidUrlsProvider')] public function tryingToResolveInvalidUrlReturnsNotFoundError( string $shortCode, - ?string $domain, + string|null $domain, string $expectedDetail, string $apiKey, ): void { diff --git a/module/Rest/test-api/Action/ShortUrlVisitsTest.php b/module/Rest/test-api/Action/ShortUrlVisitsTest.php index 8db002c4..658fe88a 100644 --- a/module/Rest/test-api/Action/ShortUrlVisitsTest.php +++ b/module/Rest/test-api/Action/ShortUrlVisitsTest.php @@ -21,7 +21,7 @@ class ShortUrlVisitsTest extends ApiTestCase #[Test, DataProviderExternal(ApiTestDataProviders::class, 'invalidUrlsProvider')] public function tryingToGetVisitsForInvalidUrlReturnsNotFoundError( string $shortCode, - ?string $domain, + string|null $domain, string $expectedDetail, string $apiKey, ): void { @@ -42,7 +42,7 @@ class ShortUrlVisitsTest extends ApiTestCase } #[Test, DataProvider('provideDomains')] - public function properVisitsAreReturnedWhenDomainIsProvided(?string $domain, int $expectedAmountOfVisits): void + public function properVisitsAreReturnedWhenDomainIsProvided(string|null $domain, int $expectedAmountOfVisits): void { $shortCode = 'ghi789'; $url = new Uri(sprintf('/short-urls/%s/visits', $shortCode)); diff --git a/module/Rest/test-api/Action/SingleStepCreateShortUrlTest.php b/module/Rest/test-api/Action/SingleStepCreateShortUrlTest.php index 038e3f38..974ac0a5 100644 --- a/module/Rest/test-api/Action/SingleStepCreateShortUrlTest.php +++ b/module/Rest/test-api/Action/SingleStepCreateShortUrlTest.php @@ -13,7 +13,7 @@ use Shlinkio\Shlink\TestUtils\ApiTest\ApiTestCase; class SingleStepCreateShortUrlTest extends ApiTestCase { #[Test, DataProvider('provideFormats')] - public function createsNewShortUrlWithExpectedResponse(?string $format, string $expectedContentType): void + public function createsNewShortUrlWithExpectedResponse(string|null $format, string $expectedContentType): void { $resp = $this->createShortUrl($format, 'valid_api_key'); @@ -43,7 +43,7 @@ class SingleStepCreateShortUrlTest extends ApiTestCase self::assertEquals('Invalid authorization', $payload['title']); } - private function createShortUrl(?string $format = 'json', ?string $apiKey = null): ResponseInterface + private function createShortUrl(string|null $format = 'json', string|null $apiKey = null): ResponseInterface { $query = [ 'longUrl' => 'https://app.shlink.io', diff --git a/module/Rest/test-api/Fixtures/ApiKeyFixture.php b/module/Rest/test-api/Fixtures/ApiKeyFixture.php index 949a80c3..1b4f64ea 100644 --- a/module/Rest/test-api/Fixtures/ApiKeyFixture.php +++ b/module/Rest/test-api/Fixtures/ApiKeyFixture.php @@ -49,7 +49,7 @@ class ApiKeyFixture extends AbstractFixture implements DependentFixtureInterface $manager->flush(); } - private function buildApiKey(string $key, bool $enabled, ?Chronos $expiresAt = null): ApiKey + private function buildApiKey(string $key, bool $enabled, Chronos|null $expiresAt = null): ApiKey { $apiKey = ApiKey::fromMeta(ApiKeyMeta::fromParams(expirationDate: $expiresAt)); $ref = new ReflectionObject($apiKey); diff --git a/module/Rest/test-api/Utils/UrlBuilder.php b/module/Rest/test-api/Utils/UrlBuilder.php index 6de96a81..e61d6ad4 100644 --- a/module/Rest/test-api/Utils/UrlBuilder.php +++ b/module/Rest/test-api/Utils/UrlBuilder.php @@ -11,7 +11,7 @@ use function sprintf; class UrlBuilder { - public static function buildShortUrlPath(string $shortCode, ?string $domain, string $suffix = ''): string + public static function buildShortUrlPath(string $shortCode, string|null $domain, string $suffix = ''): string { $url = new Uri(sprintf('/short-urls/%s%s', $shortCode, $suffix)); if ($domain !== null) { diff --git a/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php b/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php index 292c1748..45faf9f2 100644 --- a/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php +++ b/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php @@ -30,11 +30,11 @@ class DomainRedirectsRequestTest extends TestCase #[Test, DataProvider('provideValidData')] public function isProperlyCastToNotFoundRedirects( array $data, - ?NotFoundRedirectConfigInterface $defaults, + NotFoundRedirectConfigInterface|null $defaults, string $expectedAuthority, - ?string $expectedBaseUrlRedirect, - ?string $expectedRegular404Redirect, - ?string $expectedInvalidShortUrlRedirect, + string|null $expectedBaseUrlRedirect, + string|null $expectedRegular404Redirect, + string|null $expectedInvalidShortUrlRedirect, ): void { $request = DomainRedirectsRequest::fromRawData($data); $notFound = $request->toNotFoundRedirects($defaults); diff --git a/module/Rest/test/Action/MercureInfoActionTest.php b/module/Rest/test/Action/MercureInfoActionTest.php index ce4ad04f..69bfb56a 100644 --- a/module/Rest/test/Action/MercureInfoActionTest.php +++ b/module/Rest/test/Action/MercureInfoActionTest.php @@ -49,7 +49,7 @@ class MercureInfoActionTest extends TestCase } #[Test, DataProvider('provideDays')] - public function returnsExpectedInfoWhenEverythingIsOk(?int $days): void + public function returnsExpectedInfoWhenEverythingIsOk(int|null $days): void { $this->provider->expects($this->once())->method('buildSubscriptionToken')->willReturn('abc.123'); diff --git a/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php b/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php index a3beba1b..ae99f0a9 100644 --- a/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php +++ b/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php @@ -39,11 +39,11 @@ class ListShortUrlsActionTest extends TestCase public function properListReturnsSuccessResponse( array $query, int $expectedPage, - ?string $expectedSearchTerm, + string|null $expectedSearchTerm, array $expectedTags, - ?string $expectedOrderBy, - ?string $startDate = null, - ?string $endDate = null, + string|null $expectedOrderBy, + string|null $startDate = null, + string|null $endDate = null, ): void { $apiKey = ApiKey::create(); $request = ServerRequestFactory::fromGlobals()->withQueryParams($query) diff --git a/module/Rest/test/Action/Tag/DeleteTagsActionTest.php b/module/Rest/test/Action/Tag/DeleteTagsActionTest.php index 5d036097..7545cd6a 100644 --- a/module/Rest/test/Action/Tag/DeleteTagsActionTest.php +++ b/module/Rest/test/Action/Tag/DeleteTagsActionTest.php @@ -25,7 +25,7 @@ class DeleteTagsActionTest extends TestCase } #[Test, DataProvider('provideTags')] - public function processDelegatesIntoService(?array $tags): void + public function processDelegatesIntoService(array|null $tags): void { $request = (new ServerRequest()) ->withQueryParams(['tags' => $tags]) diff --git a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php index 100b146e..b74a435f 100644 --- a/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php +++ b/module/Rest/test/Middleware/CrossDomainMiddlewareTest.php @@ -82,7 +82,7 @@ class CrossDomainMiddlewareTest extends TestCase #[Test, DataProvider('provideRouteResults')] public function optionsRequestParsesRouteMatchToDetermineAllowedMethods( - ?string $allowHeader, + string|null $allowHeader, string $expectedAllowedMethods, ): void { $originalResponse = new Response(); diff --git a/module/Rest/test/Middleware/ShortUrl/CreateShortUrlContentNegotiationMiddlewareTest.php b/module/Rest/test/Middleware/ShortUrl/CreateShortUrlContentNegotiationMiddlewareTest.php index c847027c..7f4d0eba 100644 --- a/module/Rest/test/Middleware/ShortUrl/CreateShortUrlContentNegotiationMiddlewareTest.php +++ b/module/Rest/test/Middleware/ShortUrl/CreateShortUrlContentNegotiationMiddlewareTest.php @@ -40,7 +40,7 @@ class CreateShortUrlContentNegotiationMiddlewareTest extends TestCase } #[Test, DataProvider('provideData')] - public function properResponseIsReturned(?string $accept, array $query, string $expectedContentType): void + public function properResponseIsReturned(string|null $accept, array $query, string $expectedContentType): void { $request = (new ServerRequest())->withQueryParams($query); if ($accept !== null) { diff --git a/module/Rest/test/Service/ApiKeyServiceTest.php b/module/Rest/test/Service/ApiKeyServiceTest.php index 45364070..a799da27 100644 --- a/module/Rest/test/Service/ApiKeyServiceTest.php +++ b/module/Rest/test/Service/ApiKeyServiceTest.php @@ -35,7 +35,7 @@ class ApiKeyServiceTest extends TestCase * @param RoleDefinition[] $roles */ #[Test, DataProvider('provideCreationDate')] - public function apiKeyIsProperlyCreated(?Chronos $date, ?string $name, array $roles): void + public function apiKeyIsProperlyCreated(Chronos|null $date, string|null $name, array $roles): void { $this->em->expects($this->once())->method('flush'); $this->em->expects($this->once())->method('persist')->with($this->isInstanceOf(ApiKey::class)); @@ -68,7 +68,7 @@ class ApiKeyServiceTest extends TestCase } #[Test, DataProvider('provideInvalidApiKeys')] - public function checkReturnsFalseForInvalidApiKeys(?ApiKey $invalidKey): void + public function checkReturnsFalseForInvalidApiKeys(ApiKey|null $invalidKey): void { $this->repo->expects($this->once())->method('findOneBy')->with(['key' => '12345'])->willReturn($invalidKey); $this->em->method('getRepository')->with(ApiKey::class)->willReturn($this->repo); @@ -154,7 +154,7 @@ class ApiKeyServiceTest extends TestCase } #[Test, DataProvider('provideInitialApiKeys')] - public function createInitialDelegatesToRepository(?ApiKey $apiKey): void + public function createInitialDelegatesToRepository(ApiKey|null $apiKey): void { $this->repo->expects($this->once())->method('createInitialApiKey')->with('the_key')->willReturn($apiKey); $this->em->method('getRepository')->with(ApiKey::class)->willReturn($this->repo);