mirror of
https://github.com/shlinkio/shlink.git
synced 2026-03-11 09:43:13 +08:00
Update to PHP coding standard 2.4.0
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -19,23 +19,23 @@ interface TagServiceInterface
|
||||
/**
|
||||
* @return Paginator<Tag>
|
||||
*/
|
||||
public function listTags(TagsParams $params, ?ApiKey $apiKey = null): Paginator;
|
||||
public function listTags(TagsParams $params, ApiKey|null $apiKey = null): Paginator;
|
||||
|
||||
/**
|
||||
* @return Paginator<TagInfo>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
) {
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ class VisitIterationRepository extends EntitySpecificationRepository implements
|
||||
/**
|
||||
* @return iterable<Visit>
|
||||
*/
|
||||
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) {
|
||||
|
||||
@@ -24,5 +24,8 @@ interface VisitIterationRepositoryInterface
|
||||
/**
|
||||
* @return iterable<Visit>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 = <<<DQL
|
||||
SELECT v
|
||||
|
||||
@@ -53,5 +53,5 @@ interface VisitRepositoryInterface extends ObjectRepository, EntitySpecification
|
||||
|
||||
public function countNonOrphanVisits(VisitsCountFiltering $filtering): int;
|
||||
|
||||
public function findMostRecentOrphanVisit(): ?Visit;
|
||||
public function findMostRecentOrphanVisit(): Visit|null;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ readonly class RequestTracker implements RequestTrackerInterface, RequestMethodI
|
||||
return ! $this->trackingOptions->queryHasDisableTrackParam($query);
|
||||
}
|
||||
|
||||
private function shouldDisableTrackingFromAddress(?string $remoteAddr): bool
|
||||
private function shouldDisableTrackingFromAddress(string|null $remoteAddr): bool
|
||||
{
|
||||
if ($remoteAddr === null || ! $this->trackingOptions->hasDisableTrackingFrom()) {
|
||||
return false;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<Visit>
|
||||
@@ -26,28 +26,28 @@ interface VisitsStatsHelperInterface
|
||||
public function visitsForShortUrl(
|
||||
ShortUrlIdentifier $identifier,
|
||||
VisitsParams $params,
|
||||
?ApiKey $apiKey = null,
|
||||
ApiKey|null $apiKey = null,
|
||||
): Paginator;
|
||||
|
||||
/**
|
||||
* @return Paginator<Visit>
|
||||
* @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<Visit>
|
||||
* @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<Visit>
|
||||
*/
|
||||
public function orphanVisits(OrphanVisitsParams $params, ?ApiKey $apiKey = null): Paginator;
|
||||
public function orphanVisits(OrphanVisitsParams $params, ApiKey|null $apiKey = null): Paginator;
|
||||
|
||||
/**
|
||||
* @return Paginator<Visit>
|
||||
*/
|
||||
public function nonOrphanVisits(VisitsParams $params, ?ApiKey $apiKey = null): Paginator;
|
||||
public function nonOrphanVisits(VisitsParams $params, ApiKey|null $apiKey = null): Paginator;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user