mirror of
https://github.com/shlinkio/shlink.git
synced 2024-12-22 07:03:44 -06:00
Update to PHP coding standard 2.4.0
This commit is contained in:
parent
93a277a94d
commit
3f1d61e01e
@ -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*
|
||||
|
@ -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"
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.',
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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',
|
||||
|
@ -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');
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(...)
|
||||
|
@ -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);
|
||||
|
@ -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(
|
||||
|
@ -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(
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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');
|
||||
|
@ -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<mixed> $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<mixed> $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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(),
|
||||
|
@ -14,5 +14,5 @@ interface NotFoundRedirectResolverInterface
|
||||
NotFoundType $notFoundType,
|
||||
NotFoundRedirectConfigInterface $config,
|
||||
UriInterface $currentUri,
|
||||
): ?ResponseInterface;
|
||||
): ResponseInterface|null;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use function rtrim;
|
||||
|
||||
class NotFoundType
|
||||
{
|
||||
private function __construct(private readonly ?VisitType $type)
|
||||
private function __construct(private readonly VisitType|null $type)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -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.', [
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 ?? '');
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -29,12 +29,12 @@ class ValidationException extends InvalidArgumentException implements ProblemDet
|
||||
/**
|
||||
* @param InputFilterInterface<mixed> $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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -18,7 +18,7 @@ interface DeleteShortUrlServiceInterface
|
||||
public function deleteByShortCode(
|
||||
ShortUrlIdentifier $identifier,
|
||||
bool $ignoreThreshold = false,
|
||||
?ApiKey $apiKey = null,
|
||||
ApiKey|null $apiKey = null,
|
||||
): void;
|
||||
|
||||
/**
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -12,6 +12,6 @@ interface ShortUrlRedirectionBuilderInterface
|
||||
public function buildShortUrlRedirect(
|
||||
ShortUrl $shortUrl,
|
||||
ServerRequestInterface $request,
|
||||
?string $extraPath = null,
|
||||
string|null $extraPath = null,
|
||||
): string;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -11,7 +11,7 @@ final class UrlShorteningResult
|
||||
{
|
||||
private function __construct(
|
||||
public readonly ShortUrl $shortUrl,
|
||||
private readonly ?Throwable $errorOnEventDispatching,
|
||||
private readonly Throwable|null $errorOnEventDispatching,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
) {
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -23,7 +23,7 @@ use function strtolower;
|
||||
/** @extends EntitySpecificationRepository<ShortUrl> */
|
||||
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')
|
||||
|
@ -16,15 +16,18 @@ use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
|
||||
/** @extends ObjectRepository<ShortUrl> */
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -14,5 +14,5 @@ interface ShortUrlListServiceInterface
|
||||
/**
|
||||
* @return Paginator<ShortUrlWithVisitsSummary>
|
||||
*/
|
||||
public function listShortUrls(ShortUrlsParams $params, ?ApiKey $apiKey = null): Paginator;
|
||||
public function listShortUrls(ShortUrlsParams $params, ApiKey|null $apiKey = null): Paginator;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -18,6 +18,6 @@ interface ShortUrlServiceInterface
|
||||
public function updateShortUrl(
|
||||
ShortUrlIdentifier $identifier,
|
||||
ShortUrlEdition $shortUrlEdit,
|
||||
?ApiKey $apiKey = null,
|
||||
ApiKey|null $apiKey = null,
|
||||
): ShortUrl;
|
||||
}
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user