Merge pull request #2300 from acelaya-forks/feature/drop-8.2-support

Drop support for PHP 8.2
This commit is contained in:
Alejandro Celaya
2024-12-02 09:21:50 +01:00
committed by GitHub
110 changed files with 232 additions and 224 deletions

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
strategy: strategy:
matrix: matrix:
php-version: ['8.2', '8.3', '8.4'] php-version: ['8.3', '8.4']
env: env:
LC_ALL: C LC_ALL: C
steps: steps:

View File

@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
strategy: strategy:
matrix: matrix:
php-version: ['8.2', '8.3', '8.4'] php-version: ['8.3', '8.4']
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # rr get-binary picks this env automatically GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # rr get-binary picks this env automatically
steps: steps:

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
strategy: strategy:
matrix: matrix:
php-version: ['8.2', '8.3', '8.4'] php-version: ['8.3', '8.4']
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: './.github/actions/ci-setup' - uses: './.github/actions/ci-setup'

View File

@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
strategy: strategy:
matrix: matrix:
php-version: ['8.2'] php-version: ['8.3']
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Determine version - name: Determine version

View File

@@ -21,7 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
* *Nothing* * *Nothing*
### Removed ### Removed
* *Nothing* * * [#2247](https://github.com/shlinkio/shlink/issues/2247) Drop support for PHP 8.2
### Fixed ### Fixed
* *Nothing* * *Nothing*

View File

@@ -36,7 +36,7 @@ The idea is that you can just generate a container using the image and provide t
First, make sure the host where you are going to run shlink fulfills these requirements: First, make sure the host where you are going to run shlink fulfills these requirements:
* PHP 8.2 or 8.3 * PHP 8.3 or 8.4
* The next PHP extensions: json, curl, pdo, intl, gd and gmp/bcmath. * The next PHP extensions: json, curl, pdo, intl, gd and gmp/bcmath.
* apcu extension is recommended if you don't plan to use RoadRunner. * apcu extension is recommended if you don't plan to use RoadRunner.
* xml extension is required if you want to generate QR codes in svg format. * xml extension is required if you want to generate QR codes in svg format.

View File

@@ -12,7 +12,7 @@
} }
], ],
"require": { "require": {
"php": "^8.2", "php": "^8.3",
"ext-curl": "*", "ext-curl": "*",
"ext-gd": "*", "ext-gd": "*",
"ext-json": "*", "ext-json": "*",

View File

@@ -20,7 +20,7 @@ use function sprintf;
class DisableKeyCommand extends Command class DisableKeyCommand extends Command
{ {
public const NAME = 'api-key:disable'; public const string NAME = 'api-key:disable';
public function __construct(private readonly ApiKeyServiceInterface $apiKeyService) public function __construct(private readonly ApiKeyServiceInterface $apiKeyService)
{ {

View File

@@ -23,7 +23,7 @@ use function sprintf;
class GenerateKeyCommand extends Command class GenerateKeyCommand extends Command
{ {
public const NAME = 'api-key:generate'; public const string NAME = 'api-key:generate';
public function __construct( public function __construct(
private readonly ApiKeyServiceInterface $apiKeyService, private readonly ApiKeyServiceInterface $apiKeyService,

View File

@@ -13,7 +13,7 @@ use Symfony\Component\Console\Output\OutputInterface;
class InitialApiKeyCommand extends Command class InitialApiKeyCommand extends Command
{ {
public const NAME = 'api-key:initial'; public const string NAME = 'api-key:initial';
public function __construct(private readonly ApiKeyServiceInterface $apiKeyService) public function __construct(private readonly ApiKeyServiceInterface $apiKeyService)
{ {

View File

@@ -21,11 +21,11 @@ use function sprintf;
class ListKeysCommand extends Command class ListKeysCommand extends Command
{ {
private const ERROR_STRING_PATTERN = '<fg=red>%s</>'; private const string ERROR_STRING_PATTERN = '<fg=red>%s</>';
private const SUCCESS_STRING_PATTERN = '<info>%s</info>'; private const string SUCCESS_STRING_PATTERN = '<info>%s</info>';
private const WARNING_STRING_PATTERN = '<comment>%s</comment>'; private const string WARNING_STRING_PATTERN = '<comment>%s</comment>';
public const NAME = 'api-key:list'; public const string NAME = 'api-key:list';
public function __construct(private readonly ApiKeyServiceInterface $apiKeyService) public function __construct(private readonly ApiKeyServiceInterface $apiKeyService)
{ {

View File

@@ -19,7 +19,7 @@ use function Shlinkio\Shlink\Core\ArrayUtils\map;
class RenameApiKeyCommand extends Command class RenameApiKeyCommand extends Command
{ {
public const NAME = 'api-key:rename'; public const string NAME = 'api-key:rename';
public function __construct(private readonly ApiKeyServiceInterface $apiKeyService) public function __construct(private readonly ApiKeyServiceInterface $apiKeyService)
{ {

View File

@@ -21,7 +21,7 @@ use function sprintf;
class ReadEnvVarCommand extends Command class ReadEnvVarCommand extends Command
{ {
public const NAME = 'env-var:read'; public const string NAME = 'env-var:read';
/** @var Closure(string $envVar): mixed */ /** @var Closure(string $envVar): mixed */
private readonly Closure $loadEnvVar; private readonly Closure $loadEnvVar;

View File

@@ -24,9 +24,9 @@ class CreateDatabaseCommand extends AbstractDatabaseCommand
{ {
private readonly Connection $regularConn; private readonly Connection $regularConn;
public const NAME = 'db:create'; public const string NAME = 'db:create';
public const DOCTRINE_SCRIPT = 'bin/doctrine'; public const string DOCTRINE_SCRIPT = 'bin/doctrine';
public const DOCTRINE_CREATE_SCHEMA_COMMAND = 'orm:schema-tool:create'; public const string DOCTRINE_CREATE_SCHEMA_COMMAND = 'orm:schema-tool:create';
public function __construct( public function __construct(
LockFactory $locker, LockFactory $locker,

View File

@@ -11,9 +11,9 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class MigrateDatabaseCommand extends AbstractDatabaseCommand class MigrateDatabaseCommand extends AbstractDatabaseCommand
{ {
public const NAME = 'db:migrate'; public const string NAME = 'db:migrate';
public const DOCTRINE_MIGRATIONS_SCRIPT = 'vendor/doctrine/migrations/bin/doctrine-migrations.php'; public const string DOCTRINE_MIGRATIONS_SCRIPT = 'vendor/doctrine/migrations/bin/doctrine-migrations.php';
public const DOCTRINE_MIGRATE_COMMAND = 'migrations:migrate'; public const string DOCTRINE_MIGRATE_COMMAND = 'migrations:migrate';
protected function configure(): void protected function configure(): void
{ {

View File

@@ -21,7 +21,7 @@ use function str_contains;
class DomainRedirectsCommand extends Command class DomainRedirectsCommand extends Command
{ {
public const NAME = 'domain:redirects'; public const string NAME = 'domain:redirects';
public function __construct(private readonly DomainServiceInterface $domainService) public function __construct(private readonly DomainServiceInterface $domainService)
{ {

View File

@@ -16,7 +16,7 @@ use Symfony\Component\Console\Input\InputInterface;
class GetDomainVisitsCommand extends AbstractVisitsListCommand class GetDomainVisitsCommand extends AbstractVisitsListCommand
{ {
public const NAME = 'domain:visits'; public const string NAME = 'domain:visits';
public function __construct( public function __construct(
VisitsStatsHelperInterface $visitsHelper, VisitsStatsHelperInterface $visitsHelper,

View File

@@ -18,7 +18,7 @@ use function array_map;
class ListDomainsCommand extends Command class ListDomainsCommand extends Command
{ {
public const NAME = 'domain:list'; public const string NAME = 'domain:list';
public function __construct(private readonly DomainServiceInterface $domainService) public function __construct(private readonly DomainServiceInterface $domainService)
{ {

View File

@@ -22,7 +22,7 @@ use function sprintf;
class MatomoSendVisitsCommand extends Command implements VisitSendingProgressTrackerInterface class MatomoSendVisitsCommand extends Command implements VisitSendingProgressTrackerInterface
{ {
public const NAME = 'integration:matomo:send-visits'; public const string NAME = 'integration:matomo:send-visits';
private readonly bool $matomoEnabled; private readonly bool $matomoEnabled;
private SymfonyStyle $io; private SymfonyStyle $io;

View File

@@ -19,7 +19,7 @@ use function sprintf;
class ManageRedirectRulesCommand extends Command class ManageRedirectRulesCommand extends Command
{ {
public const NAME = 'short-url:manage-rules'; public const string NAME = 'short-url:manage-rules';
private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput; private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput;

View File

@@ -20,7 +20,7 @@ use function sprintf;
class CreateShortUrlCommand extends Command class CreateShortUrlCommand extends Command
{ {
public const NAME = 'short-url:create'; public const string NAME = 'short-url:create';
private SymfonyStyle $io; private SymfonyStyle $io;
private readonly ShortUrlDataInput $shortUrlDataInput; private readonly ShortUrlDataInput $shortUrlDataInput;

View File

@@ -17,7 +17,7 @@ use function sprintf;
class DeleteExpiredShortUrlsCommand extends Command class DeleteExpiredShortUrlsCommand extends Command
{ {
public const NAME = 'short-url:delete-expired'; public const string NAME = 'short-url:delete-expired';
public function __construct(private readonly DeleteShortUrlServiceInterface $deleteShortUrlService) public function __construct(private readonly DeleteShortUrlServiceInterface $deleteShortUrlService)
{ {

View File

@@ -19,7 +19,7 @@ use function sprintf;
class DeleteShortUrlCommand extends Command class DeleteShortUrlCommand extends Command
{ {
public const NAME = 'short-url:delete'; public const string NAME = 'short-url:delete';
private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput; private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput;

View File

@@ -16,7 +16,7 @@ use function sprintf;
class DeleteShortUrlVisitsCommand extends AbstractDeleteVisitsCommand class DeleteShortUrlVisitsCommand extends AbstractDeleteVisitsCommand
{ {
public const NAME = 'short-url:visits-delete'; public const string NAME = 'short-url:visits-delete';
private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput; private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput;

View File

@@ -19,7 +19,7 @@ use function sprintf;
class EditShortUrlCommand extends Command class EditShortUrlCommand extends Command
{ {
public const NAME = 'short-url:edit'; public const string NAME = 'short-url:edit';
private readonly ShortUrlDataInput $shortUrlDataInput; private readonly ShortUrlDataInput $shortUrlDataInput;
private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput; private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput;

View File

@@ -16,7 +16,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class GetShortUrlVisitsCommand extends AbstractVisitsListCommand class GetShortUrlVisitsCommand extends AbstractVisitsListCommand
{ {
public const NAME = 'short-url:visits'; public const string NAME = 'short-url:visits';
private ShortUrlIdentifierInput $shortUrlIdentifierInput; private ShortUrlIdentifierInput $shortUrlIdentifierInput;

View File

@@ -33,7 +33,7 @@ use function sprintf;
class ListShortUrlsCommand extends Command class ListShortUrlsCommand extends Command
{ {
public const NAME = 'short-url:list'; public const string NAME = 'short-url:list';
private readonly StartDateOption $startDateOption; private readonly StartDateOption $startDateOption;
private readonly EndDateOption $endDateOption; private readonly EndDateOption $endDateOption;

View File

@@ -17,7 +17,7 @@ use function sprintf;
class ResolveUrlCommand extends Command class ResolveUrlCommand extends Command
{ {
public const NAME = 'short-url:parse'; public const string NAME = 'short-url:parse';
private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput; private readonly ShortUrlIdentifierInput $shortUrlIdentifierInput;

View File

@@ -14,9 +14,9 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class DeleteTagsCommand extends Command class DeleteTagsCommand extends Command
{ {
public const NAME = 'tag:delete'; public const string NAME = 'tag:delete';
public function __construct(private TagServiceInterface $tagService) public function __construct(private readonly TagServiceInterface $tagService)
{ {
parent::__construct(); parent::__construct();
} }

View File

@@ -16,7 +16,7 @@ use Symfony\Component\Console\Input\InputInterface;
class GetTagVisitsCommand extends AbstractVisitsListCommand class GetTagVisitsCommand extends AbstractVisitsListCommand
{ {
public const NAME = 'tag:visits'; public const string NAME = 'tag:visits';
public function __construct( public function __construct(
VisitsStatsHelperInterface $visitsHelper, VisitsStatsHelperInterface $visitsHelper,

View File

@@ -17,7 +17,7 @@ use function array_map;
class ListTagsCommand extends Command class ListTagsCommand extends Command
{ {
public const NAME = 'tag:list'; public const string NAME = 'tag:list';
public function __construct(private readonly TagServiceInterface $tagService) public function __construct(private readonly TagServiceInterface $tagService)
{ {

View File

@@ -17,7 +17,7 @@ use Symfony\Component\Console\Style\SymfonyStyle;
class RenameTagCommand extends Command class RenameTagCommand extends Command
{ {
public const NAME = 'tag:rename'; public const string NAME = 'tag:rename';
public function __construct(private readonly TagServiceInterface $tagService) public function __construct(private readonly TagServiceInterface $tagService)
{ {

View File

@@ -6,7 +6,7 @@ namespace Shlinkio\Shlink\CLI\Command\Util;
final class LockedCommandConfig final class LockedCommandConfig
{ {
public const DEFAULT_TTL = 600.0; // 10 minutes public const float DEFAULT_TTL = 600.0; // 10 minutes
private function __construct( private function __construct(
public readonly string $lockName, public readonly string $lockName,

View File

@@ -13,7 +13,7 @@ use function sprintf;
class DeleteOrphanVisitsCommand extends AbstractDeleteVisitsCommand class DeleteOrphanVisitsCommand extends AbstractDeleteVisitsCommand
{ {
public const NAME = 'visit:orphan-delete'; public const string NAME = 'visit:orphan-delete';
public function __construct(private readonly VisitsDeleterInterface $deleter) public function __construct(private readonly VisitsDeleterInterface $deleter)
{ {

View File

@@ -18,7 +18,7 @@ use function sprintf;
class DownloadGeoLiteDbCommand extends Command class DownloadGeoLiteDbCommand extends Command
{ {
public const NAME = 'visit:download-db'; public const string NAME = 'visit:download-db';
private ProgressBar|null $progressBar = null; private ProgressBar|null $progressBar = null;

View File

@@ -14,7 +14,7 @@ use Symfony\Component\Console\Input\InputInterface;
class GetNonOrphanVisitsCommand extends AbstractVisitsListCommand class GetNonOrphanVisitsCommand extends AbstractVisitsListCommand
{ {
public const NAME = 'visit:non-orphan'; public const string NAME = 'visit:non-orphan';
public function __construct( public function __construct(
VisitsStatsHelperInterface $visitsHelper, VisitsStatsHelperInterface $visitsHelper,

View File

@@ -17,7 +17,7 @@ use function sprintf;
class GetOrphanVisitsCommand extends AbstractVisitsListCommand class GetOrphanVisitsCommand extends AbstractVisitsListCommand
{ {
public const NAME = 'visit:orphan'; public const string NAME = 'visit:orphan';
protected function configure(): void protected function configure(): void
{ {

View File

@@ -29,7 +29,7 @@ use function sprintf;
class LocateVisitsCommand extends AbstractLockedCommand implements VisitGeolocationHelperInterface class LocateVisitsCommand extends AbstractLockedCommand implements VisitGeolocationHelperInterface
{ {
public const NAME = 'visit:locate'; public const string NAME = 'visit:locate';
private SymfonyStyle $io; private SymfonyStyle $io;

View File

@@ -20,7 +20,7 @@ use function is_int;
class GeolocationDbUpdater implements GeolocationDbUpdaterInterface class GeolocationDbUpdater implements GeolocationDbUpdaterInterface
{ {
private const LOCK_NAME = 'geolocation-db-update'; private const string LOCK_NAME = 'geolocation-db-update';
/** @var Closure(): Reader */ /** @var Closure(): Reader */
private readonly Closure $geoLiteDbReaderFactory; private readonly Closure $geoLiteDbReaderFactory;

View File

@@ -6,7 +6,7 @@ namespace Shlinkio\Shlink\CLI\Util;
final class ExitCode final class ExitCode
{ {
public const EXIT_SUCCESS = 0; public const int EXIT_SUCCESS = 0;
public const EXIT_FAILURE = -1; public const int EXIT_FAILURE = -1;
public const EXIT_WARNING = 1; public const int EXIT_WARNING = 1;
} }

View File

@@ -12,8 +12,8 @@ use function array_pop;
final class ShlinkTable final class ShlinkTable
{ {
private const DEFAULT_STYLE_NAME = 'default'; private const string DEFAULT_STYLE_NAME = 'default';
private const TABLE_TITLE_STYLE = '<options=bold> %s </>'; private const string TABLE_TITLE_STYLE = '<options=bold> %s </>';
private function __construct(private readonly Table $baseTable, private readonly bool $withRowSeparators = false) private function __construct(private readonly Table $baseTable, private readonly bool $withRowSeparators = false)
{ {

View File

@@ -10,7 +10,7 @@ use Doctrine\Migrations\AbstractMigration;
final class Version20230211171904 extends AbstractMigration final class Version20230211171904 extends AbstractMigration
{ {
private const INDEX_NAME = 'IDX_visits_potential_bot'; private const string INDEX_NAME = 'IDX_visits_potential_bot';
public function up(Schema $schema): void public function up(Schema $schema): void
{ {

View File

@@ -10,7 +10,7 @@ use Doctrine\Migrations\AbstractMigration;
final class Version20230303164233 extends AbstractMigration final class Version20230303164233 extends AbstractMigration
{ {
private const INDEX_NAME = 'visits_potential_bot_IDX'; private const string INDEX_NAME = 'visits_potential_bot_IDX';
public function up(Schema $schema): void public function up(Schema $schema): void
{ {

View File

@@ -17,8 +17,12 @@ use function in_array;
*/ */
final class Version20240220214031 extends AbstractMigration final class Version20240220214031 extends AbstractMigration
{ {
private const DOMAINS_COLUMNS = ['base_url_redirect', 'regular_not_found_redirect', 'invalid_short_url_redirect']; private const array DOMAINS_COLUMNS = [
private const TEXT_COLUMNS = [ 'base_url_redirect',
'regular_not_found_redirect',
'invalid_short_url_redirect',
];
private const array TEXT_COLUMNS = [
'domains' => self::DOMAINS_COLUMNS, 'domains' => self::DOMAINS_COLUMNS,
'short_urls' => ['original_url'], 'short_urls' => ['original_url'],
]; ];

View File

@@ -11,7 +11,7 @@ use Doctrine\Migrations\AbstractMigration;
final class Version20241124112257 extends AbstractMigration final class Version20241124112257 extends AbstractMigration
{ {
private const COLUMN_NAME = 'redirect_url'; private const string COLUMN_NAME = 'redirect_url';
public function up(Schema $schema): void public function up(Schema $schema): void
{ {

View File

@@ -30,9 +30,9 @@ use const Shlinkio\Shlink\DEFAULT_QR_CODE_COLOR;
final class QrCodeParams final class QrCodeParams
{ {
private const MIN_SIZE = 50; private const int MIN_SIZE = 50;
private const MAX_SIZE = 1000; private const int MAX_SIZE = 1000;
private const SUPPORTED_FORMATS = ['png', 'svg']; private const array SUPPORTED_FORMATS = ['png', 'svg'];
private function __construct( private function __construct(
public readonly int $size, public readonly int $size,

View File

@@ -17,8 +17,8 @@ use function urlencode;
class NotFoundRedirectResolver implements NotFoundRedirectResolverInterface class NotFoundRedirectResolver implements NotFoundRedirectResolverInterface
{ {
private const DOMAIN_PLACEHOLDER = '{DOMAIN}'; private const string DOMAIN_PLACEHOLDER = '{DOMAIN}';
private const ORIGINAL_PATH_PLACEHOLDER = '{ORIGINAL_PATH}'; private const string ORIGINAL_PATH_PLACEHOLDER = '{ORIGINAL_PATH}';
public function __construct( public function __construct(
private readonly RedirectResponseHelperInterface $redirectResponseHelper, private readonly RedirectResponseHelperInterface $redirectResponseHelper,

View File

@@ -8,7 +8,7 @@ use function array_map;
class BasePathPrefixer class BasePathPrefixer
{ {
private const ELEMENTS_WITH_PATH = ['routes', 'middleware_pipeline']; private const array ELEMENTS_WITH_PATH = ['routes', 'middleware_pipeline'];
public function __invoke(array $config): array public function __invoke(array $config): array
{ {

View File

@@ -11,8 +11,8 @@ use function str_replace;
class MultiSegmentSlugProcessor class MultiSegmentSlugProcessor
{ {
private const SINGLE_SEGMENT_PATTERN = '{shortCode}'; private const string SINGLE_SEGMENT_PATTERN = '{shortCode}';
private const MULTI_SEGMENT_PATTERN = '{shortCode:.+}'; private const string MULTI_SEGMENT_PATTERN = '{shortCode:.+}';
public function __invoke(array $config): array public function __invoke(array $config): array
{ {

View File

@@ -11,7 +11,7 @@ use Shlinkio\Shlink\Core\Config\NotFoundRedirects;
class Domain extends AbstractEntity implements JsonSerializable, NotFoundRedirectConfigInterface class Domain extends AbstractEntity implements JsonSerializable, NotFoundRedirectConfigInterface
{ {
public const DEFAULT_AUTHORITY = 'DEFAULT'; public const string DEFAULT_AUTHORITY = 'DEFAULT';
private function __construct( private function __construct(
public readonly string $authority, public readonly string $authority,

View File

@@ -11,10 +11,10 @@ use Shlinkio\Shlink\Common\Validation\InputFactory;
/** @extends InputFilter<mixed> */ /** @extends InputFilter<mixed> */
class DomainRedirectsInputFilter extends InputFilter class DomainRedirectsInputFilter extends InputFilter
{ {
public const DOMAIN = 'domain'; public const string DOMAIN = 'domain';
public const BASE_URL_REDIRECT = 'baseUrlRedirect'; public const string BASE_URL_REDIRECT = 'baseUrlRedirect';
public const REGULAR_404_REDIRECT = 'regular404Redirect'; public const string REGULAR_404_REDIRECT = 'regular404Redirect';
public const INVALID_SHORT_URL_REDIRECT = 'invalidShortUrlRedirect'; public const string INVALID_SHORT_URL_REDIRECT = 'invalidShortUrlRedirect';
private function __construct() private function __construct()
{ {

View File

@@ -17,9 +17,9 @@ use function sprintf;
class NotFoundTemplateHandler implements RequestHandlerInterface class NotFoundTemplateHandler implements RequestHandlerInterface
{ {
private const TEMPLATES_BASE_DIR = __DIR__ . '/../../templates'; private const string TEMPLATES_BASE_DIR = __DIR__ . '/../../templates';
public const NOT_FOUND_TEMPLATE = '404.html'; public const string NOT_FOUND_TEMPLATE = '404.html';
public const INVALID_SHORT_CODE_TEMPLATE = 'invalid-short-code.html'; public const string INVALID_SHORT_CODE_TEMPLATE = 'invalid-short-code.html';
private Closure $readFile; private Closure $readFile;

View File

@@ -16,8 +16,8 @@ class DeleteShortUrlException extends DomainException implements ProblemDetailsE
{ {
use CommonProblemDetailsExceptionTrait; use CommonProblemDetailsExceptionTrait;
private const TITLE = 'Cannot delete short URL'; private const string TITLE = 'Cannot delete short URL';
public const ERROR_CODE = 'invalid-short-url-deletion'; public const string ERROR_CODE = 'invalid-short-url-deletion';
public static function fromVisitsThreshold(int $threshold, ShortUrlIdentifier $identifier): self public static function fromVisitsThreshold(int $threshold, ShortUrlIdentifier $identifier): self
{ {

View File

@@ -15,8 +15,8 @@ class DomainNotFoundException extends DomainException implements ProblemDetailsE
{ {
use CommonProblemDetailsExceptionTrait; use CommonProblemDetailsExceptionTrait;
private const TITLE = 'Domain not found'; private const string TITLE = 'Domain not found';
public const ERROR_CODE = 'domain-not-found'; public const string ERROR_CODE = 'domain-not-found';
private function __construct(string $message, array $additional) private function __construct(string $message, array $additional)
{ {

View File

@@ -14,8 +14,8 @@ class ForbiddenTagOperationException extends DomainException implements ProblemD
{ {
use CommonProblemDetailsExceptionTrait; use CommonProblemDetailsExceptionTrait;
private const TITLE = 'Forbidden tag operation'; private const string TITLE = 'Forbidden tag operation';
public const ERROR_CODE = 'forbidden-tag-operation'; public const string ERROR_CODE = 'forbidden-tag-operation';
public static function forDeletion(): self public static function forDeletion(): self
{ {

View File

@@ -16,8 +16,8 @@ class NonUniqueSlugException extends InvalidArgumentException implements Problem
{ {
use CommonProblemDetailsExceptionTrait; use CommonProblemDetailsExceptionTrait;
private const TITLE = 'Invalid custom slug'; private const string TITLE = 'Invalid custom slug';
public const ERROR_CODE = 'non-unique-slug'; public const string ERROR_CODE = 'non-unique-slug';
public static function fromSlug(string $slug, string|null $domain = null): self public static function fromSlug(string $slug, string|null $domain = null): self
{ {

View File

@@ -16,8 +16,8 @@ class ShortUrlNotFoundException extends DomainException implements ProblemDetail
{ {
use CommonProblemDetailsExceptionTrait; use CommonProblemDetailsExceptionTrait;
private const TITLE = 'Short URL not found'; private const string TITLE = 'Short URL not found';
public const ERROR_CODE = 'short-url-not-found'; public const string ERROR_CODE = 'short-url-not-found';
public static function fromNotFound(ShortUrlIdentifier $identifier): self public static function fromNotFound(ShortUrlIdentifier $identifier): self
{ {

View File

@@ -16,8 +16,8 @@ class TagConflictException extends RuntimeException implements ProblemDetailsExc
{ {
use CommonProblemDetailsExceptionTrait; use CommonProblemDetailsExceptionTrait;
private const TITLE = 'Tag conflict'; private const string TITLE = 'Tag conflict';
public const ERROR_CODE = 'tag-conflict'; public const string ERROR_CODE = 'tag-conflict';
public static function forExistingTag(Renaming $renaming): self public static function forExistingTag(Renaming $renaming): self
{ {

View File

@@ -15,8 +15,8 @@ class TagNotFoundException extends DomainException implements ProblemDetailsExce
{ {
use CommonProblemDetailsExceptionTrait; use CommonProblemDetailsExceptionTrait;
private const TITLE = 'Tag not found'; private const string TITLE = 'Tag not found';
public const ERROR_CODE = 'tag-not-found'; public const string ERROR_CODE = 'tag-not-found';
public static function fromTag(string $tag): self public static function fromTag(string $tag): self
{ {

View File

@@ -21,8 +21,8 @@ class ValidationException extends InvalidArgumentException implements ProblemDet
{ {
use CommonProblemDetailsExceptionTrait; use CommonProblemDetailsExceptionTrait;
private const TITLE = 'Invalid data'; private const string TITLE = 'Invalid data';
public const ERROR_CODE = 'invalid-data'; public const string ERROR_CODE = 'invalid-data';
private array $invalidElements; private array $invalidElements;

View File

@@ -9,7 +9,7 @@ use Shlinkio\Shlink\Core\Exception\RuntimeException;
readonly class MatomoTrackerBuilder implements MatomoTrackerBuilderInterface readonly class MatomoTrackerBuilder implements MatomoTrackerBuilderInterface
{ {
public const MATOMO_DEFAULT_TIMEOUT = 10; // Time in seconds public const int MATOMO_DEFAULT_TIMEOUT = 10; // Time in seconds
public function __construct(private MatomoOptions $options) public function __construct(private MatomoOptions $options)
{ {

View File

@@ -6,9 +6,9 @@ namespace Shlinkio\Shlink\Core\Model;
final readonly class Ordering final readonly class Ordering
{ {
private const DESC_DIR = 'DESC'; private const string DESC_DIR = 'DESC';
private const ASC_DIR = 'ASC'; private const string ASC_DIR = 'ASC';
private const DEFAULT_DIR = self::ASC_DIR; private const string DEFAULT_DIR = self::ASC_DIR;
public function __construct(public string|null $field = null, public string $direction = self::DEFAULT_DIR) public function __construct(public string|null $field = null, public string $direction = self::DEFAULT_DIR)
{ {

View File

@@ -17,14 +17,14 @@ use function Shlinkio\Shlink\Core\enumValues;
/** @extends InputFilter<mixed> */ /** @extends InputFilter<mixed> */
class RedirectRulesInputFilter extends InputFilter class RedirectRulesInputFilter extends InputFilter
{ {
public const REDIRECT_RULES = 'redirectRules'; public const string REDIRECT_RULES = 'redirectRules';
public const RULE_LONG_URL = 'longUrl'; public const string RULE_LONG_URL = 'longUrl';
public const RULE_CONDITIONS = 'conditions'; public const string RULE_CONDITIONS = 'conditions';
public const CONDITION_TYPE = 'type'; public const string CONDITION_TYPE = 'type';
public const CONDITION_MATCH_VALUE = 'matchValue'; public const string CONDITION_MATCH_VALUE = 'matchValue';
public const CONDITION_MATCH_KEY = 'matchKey'; public const string CONDITION_MATCH_KEY = 'matchKey';
private function __construct() private function __construct()
{ {

View File

@@ -21,14 +21,14 @@ use function trim;
readonly class ShortUrlTitleResolutionHelper implements ShortUrlTitleResolutionHelperInterface readonly class ShortUrlTitleResolutionHelper implements ShortUrlTitleResolutionHelperInterface
{ {
public const MAX_REDIRECTS = 15; public const int MAX_REDIRECTS = 15;
public const CHROME_USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) ' public const string CHROME_USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) '
. 'Chrome/121.0.0.0 Safari/537.36'; . 'Chrome/121.0.0.0 Safari/537.36';
// Matches the value inside a html title tag // Matches the value inside a html title tag
private const TITLE_TAG_VALUE = '/<title[^>]*>(.*?)<\/title>/i'; private const string TITLE_TAG_VALUE = '/<title[^>]*>(.*?)<\/title>/i';
// Matches the charset inside a Content-Type header // Matches the charset inside a Content-Type header
private const CHARSET_VALUE = '/charset=([^;]+)/i'; private const string CHARSET_VALUE = '/charset=([^;]+)/i';
public function __construct( public function __construct(
private ClientInterface $httpClient, private ClientInterface $httpClient,

View File

@@ -14,7 +14,7 @@ use function rtrim;
class TrimTrailingSlashMiddleware implements MiddlewareInterface class TrimTrailingSlashMiddleware implements MiddlewareInterface
{ {
private const SHORT_CODE_ATTR = 'shortCode'; private const string SHORT_CODE_ATTR = 'shortCode';
public function __construct(private readonly UrlShortenerOptions $options) public function __construct(private readonly UrlShortenerOptions $options)
{ {

View File

@@ -12,8 +12,8 @@ use function strpbrk;
class CustomSlugValidator extends AbstractValidator class CustomSlugValidator extends AbstractValidator
{ {
private const NOT_STRING = 'NOT_STRING'; private const string NOT_STRING = 'NOT_STRING';
private const CONTAINS_URL_CHARACTERS = 'CONTAINS_URL_CHARACTERS'; private const string CONTAINS_URL_CHARACTERS = 'CONTAINS_URL_CHARACTERS';
protected array $messageTemplates = [ protected array $messageTemplates = [
self::NOT_STRING => 'Provided value is not a string.', self::NOT_STRING => 'Provided value is not a string.',

View File

@@ -24,22 +24,22 @@ use const Shlinkio\Shlink\MIN_SHORT_CODES_LENGTH;
class ShortUrlInputFilter extends InputFilter class ShortUrlInputFilter extends InputFilter
{ {
// Fields for creation only // Fields for creation only
public const SHORT_CODE_LENGTH = 'shortCodeLength'; public const string SHORT_CODE_LENGTH = 'shortCodeLength';
public const CUSTOM_SLUG = 'customSlug'; public const string CUSTOM_SLUG = 'customSlug';
public const PATH_PREFIX = 'pathPrefix'; public const string PATH_PREFIX = 'pathPrefix';
public const FIND_IF_EXISTS = 'findIfExists'; public const string FIND_IF_EXISTS = 'findIfExists';
public const DOMAIN = 'domain'; public const string DOMAIN = 'domain';
// Fields for creation and edition // Fields for creation and edition
public const LONG_URL = 'longUrl'; public const string LONG_URL = 'longUrl';
public const VALID_SINCE = 'validSince'; public const string VALID_SINCE = 'validSince';
public const VALID_UNTIL = 'validUntil'; public const string VALID_UNTIL = 'validUntil';
public const MAX_VISITS = 'maxVisits'; public const string MAX_VISITS = 'maxVisits';
public const TITLE = 'title'; public const string TITLE = 'title';
public const TAGS = 'tags'; public const string TAGS = 'tags';
public const CRAWLABLE = 'crawlable'; public const string CRAWLABLE = 'crawlable';
public const FORWARD_QUERY = 'forwardQuery'; public const string FORWARD_QUERY = 'forwardQuery';
public const API_KEY = 'apiKey'; public const string API_KEY = 'apiKey';
public static function forCreation(array $data, UrlShortenerOptions $options): self public static function forCreation(array $data, UrlShortenerOptions $options): self
{ {

View File

@@ -16,17 +16,17 @@ use function Shlinkio\Shlink\Core\enumValues;
/** @extends InputFilter<mixed> */ /** @extends InputFilter<mixed> */
class ShortUrlsParamsInputFilter extends InputFilter class ShortUrlsParamsInputFilter extends InputFilter
{ {
public const PAGE = 'page'; public const string PAGE = 'page';
public const SEARCH_TERM = 'searchTerm'; public const string SEARCH_TERM = 'searchTerm';
public const TAGS = 'tags'; public const string TAGS = 'tags';
public const START_DATE = 'startDate'; public const string START_DATE = 'startDate';
public const END_DATE = 'endDate'; public const string END_DATE = 'endDate';
public const ITEMS_PER_PAGE = 'itemsPerPage'; public const string ITEMS_PER_PAGE = 'itemsPerPage';
public const TAGS_MODE = 'tagsMode'; public const string TAGS_MODE = 'tagsMode';
public const ORDER_BY = 'orderBy'; public const string ORDER_BY = 'orderBy';
public const EXCLUDE_MAX_VISITS_REACHED = 'excludeMaxVisitsReached'; public const string EXCLUDE_MAX_VISITS_REACHED = 'excludeMaxVisitsReached';
public const EXCLUDE_PAST_VALID_UNTIL = 'excludePastValidUntil'; public const string EXCLUDE_PAST_VALID_UNTIL = 'excludePastValidUntil';
public const DOMAIN = 'domain'; public const string DOMAIN = 'domain';
public function __construct(array $data) public function __construct(array $data)
{ {

View File

@@ -17,11 +17,11 @@ use const Shlinkio\Shlink\REDIRECT_URL_REQUEST_ATTRIBUTE;
final readonly class Visitor final readonly class Visitor
{ {
public const USER_AGENT_MAX_LENGTH = 512; public const int USER_AGENT_MAX_LENGTH = 512;
public const REFERER_MAX_LENGTH = 1024; public const int REFERER_MAX_LENGTH = 1024;
public const REMOTE_ADDRESS_MAX_LENGTH = 256; public const int REMOTE_ADDRESS_MAX_LENGTH = 256;
public const VISITED_URL_MAX_LENGTH = 2048; public const int VISITED_URL_MAX_LENGTH = 2048;
public const REDIRECT_URL_MAX_LENGTH = 2048; public const int REDIRECT_URL_MAX_LENGTH = 2048;
private function __construct( private function __construct(
public string $userAgent, public string $userAgent,

View File

@@ -9,7 +9,7 @@ use Shlinkio\Shlink\Core\Visit\Entity\Visit;
interface VisitIterationRepositoryInterface interface VisitIterationRepositoryInterface
{ {
public const DEFAULT_BLOCK_SIZE = 10000; public const int DEFAULT_BLOCK_SIZE = 10000;
/** /**
* @return iterable<Visit> * @return iterable<Visit>

View File

@@ -32,8 +32,8 @@ use const Shlinkio\Shlink\DEFAULT_QR_CODE_COLOR;
class QrCodeActionTest extends TestCase class QrCodeActionTest extends TestCase
{ {
private const WHITE = 0xFFFFFF; private const int WHITE = 0xFFFFFF;
private const BLACK = 0x0; private const int BLACK = 0x0;
private MockObject & ShortUrlResolverInterface $urlResolver; private MockObject & ShortUrlResolverInterface $urlResolver;

View File

@@ -23,7 +23,7 @@ use const Shlinkio\Shlink\REDIRECT_URL_REQUEST_ATTRIBUTE;
class RedirectActionTest extends TestCase class RedirectActionTest extends TestCase
{ {
private const LONG_URL = 'https://domain.com/foo/bar?some=thing'; private const string LONG_URL = 'https://domain.com/foo/bar?some=thing';
private RedirectAction $action; private RedirectAction $action;
private MockObject & ShortUrlResolverInterface $urlResolver; private MockObject & ShortUrlResolverInterface $urlResolver;

View File

@@ -22,7 +22,7 @@ use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
class ShortUrlTitleResolutionHelperTest extends TestCase class ShortUrlTitleResolutionHelperTest extends TestCase
{ {
private const LONG_URL = 'http://foobar.com/12345/hello?foo=bar'; private const string LONG_URL = 'http://foobar.com/12345/hello?foo=bar';
private MockObject & ClientInterface $httpClient; private MockObject & ClientInterface $httpClient;

View File

@@ -23,7 +23,7 @@ use const Shlinkio\Shlink\IP_ADDRESS_REQUEST_ATTRIBUTE;
class RequestTrackerTest extends TestCase class RequestTrackerTest extends TestCase
{ {
private const LONG_URL = 'https://domain.com/foo/bar?some=thing'; private const string LONG_URL = 'https://domain.com/foo/bar?some=thing';
private RequestTracker $requestTracker; private RequestTracker $requestTracker;
private MockObject & VisitsTrackerInterface $visitsTracker; private MockObject & VisitsTrackerInterface $visitsTracker;

View File

@@ -10,8 +10,8 @@ use Psr\Http\Server\RequestHandlerInterface;
abstract class AbstractRestAction implements RequestHandlerInterface, RequestMethodInterface, StatusCodeInterface abstract class AbstractRestAction implements RequestHandlerInterface, RequestMethodInterface, StatusCodeInterface
{ {
protected const ROUTE_PATH = ''; protected const string ROUTE_PATH = '';
protected const ROUTE_ALLOWED_METHODS = []; protected const array ROUTE_ALLOWED_METHODS = [];
public static function getRouteDef(array $prevMiddleware = [], array $postMiddleware = []): array public static function getRouteDef(array $prevMiddleware = [], array $postMiddleware = []): array
{ {

View File

@@ -14,10 +14,10 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class DomainRedirectsAction extends AbstractRestAction class DomainRedirectsAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/domains/redirects'; protected const string ROUTE_PATH = '/domains/redirects';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_PATCH]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_PATCH];
public function __construct(private DomainServiceInterface $domainService) public function __construct(private readonly DomainServiceInterface $domainService)
{ {
} }

View File

@@ -15,11 +15,13 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ListDomainsAction extends AbstractRestAction class ListDomainsAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/domains'; protected const string ROUTE_PATH = '/domains';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private DomainServiceInterface $domainService, private NotFoundRedirectOptions $options) public function __construct(
{ private readonly DomainServiceInterface $domainService,
private readonly NotFoundRedirectOptions $options,
) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface

View File

@@ -13,14 +13,14 @@ use Throwable;
class HealthAction extends AbstractRestAction class HealthAction extends AbstractRestAction
{ {
private const HEALTH_CONTENT_TYPE = 'application/health+json'; private const string HEALTH_CONTENT_TYPE = 'application/health+json';
private const STATUS_PASS = 'pass'; private const string STATUS_PASS = 'pass';
private const STATUS_FAIL = 'fail'; private const string STATUS_FAIL = 'fail';
public const ROUTE_PATH = '/health'; public const string ROUTE_PATH = '/health';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private EntityManagerInterface $em, private AppOptions $options) public function __construct(private readonly EntityManagerInterface $em, private readonly AppOptions $options)
{ {
} }

View File

@@ -15,11 +15,13 @@ use function sprintf;
class MercureInfoAction extends AbstractRestAction class MercureInfoAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/mercure-info'; protected const string ROUTE_PATH = '/mercure-info';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private JwtProviderInterface $jwtProvider, private array $mercureConfig) public function __construct(
{ private readonly JwtProviderInterface $jwtProvider,
private readonly array $mercureConfig,
) {
} }
public function handle(ServerRequestInterface $request): ResponseInterface public function handle(ServerRequestInterface $request): ResponseInterface

View File

@@ -13,8 +13,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ListRedirectRulesAction extends AbstractRestAction class ListRedirectRulesAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/short-urls/{shortCode}/redirect-rules'; protected const string ROUTE_PATH = '/short-urls/{shortCode}/redirect-rules';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct( public function __construct(
private readonly ShortUrlResolverInterface $urlResolver, private readonly ShortUrlResolverInterface $urlResolver,

View File

@@ -16,8 +16,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class SetRedirectRulesAction extends AbstractRestAction class SetRedirectRulesAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/short-urls/{shortCode}/redirect-rules'; protected const string ROUTE_PATH = '/short-urls/{shortCode}/redirect-rules';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_POST, self::METHOD_PATCH]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_POST, self::METHOD_PATCH];
public function __construct( public function __construct(
private readonly ShortUrlResolverInterface $urlResolver, private readonly ShortUrlResolverInterface $urlResolver,

View File

@@ -12,8 +12,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class CreateShortUrlAction extends AbstractCreateShortUrlAction class CreateShortUrlAction extends AbstractCreateShortUrlAction
{ {
protected const ROUTE_PATH = '/short-urls'; protected const string ROUTE_PATH = '/short-urls';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_POST]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_POST];
/** /**
* @throws ValidationException * @throws ValidationException

View File

@@ -14,8 +14,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class DeleteShortUrlAction extends AbstractRestAction class DeleteShortUrlAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/short-urls/{shortCode}'; protected const string ROUTE_PATH = '/short-urls/{shortCode}';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE];
public function __construct(private DeleteShortUrlServiceInterface $deleteShortUrlService) public function __construct(private DeleteShortUrlServiceInterface $deleteShortUrlService)
{ {

View File

@@ -14,8 +14,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class DeleteShortUrlVisitsAction extends AbstractRestAction class DeleteShortUrlVisitsAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/short-urls/{shortCode}/visits'; protected const string ROUTE_PATH = '/short-urls/{shortCode}/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE];
public function __construct(private readonly ShortUrlVisitsDeleterInterface $deleter) public function __construct(private readonly ShortUrlVisitsDeleterInterface $deleter)
{ {

View File

@@ -16,8 +16,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class EditShortUrlAction extends AbstractRestAction class EditShortUrlAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/short-urls/{shortCode}'; protected const string ROUTE_PATH = '/short-urls/{shortCode}';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_PATCH]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_PATCH];
public function __construct( public function __construct(
private readonly ShortUrlServiceInterface $shortUrlService, private readonly ShortUrlServiceInterface $shortUrlService,

View File

@@ -16,8 +16,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ListShortUrlsAction extends AbstractRestAction class ListShortUrlsAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/short-urls'; protected const string ROUTE_PATH = '/short-urls';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct( public function __construct(
private readonly ShortUrlListServiceInterface $shortUrlService, private readonly ShortUrlListServiceInterface $shortUrlService,

View File

@@ -15,8 +15,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ResolveShortUrlAction extends AbstractRestAction class ResolveShortUrlAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/short-urls/{shortCode}'; protected const string ROUTE_PATH = '/short-urls/{shortCode}';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct( public function __construct(
private readonly ShortUrlResolverInterface $urlResolver, private readonly ShortUrlResolverInterface $urlResolver,

View File

@@ -11,8 +11,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class SingleStepCreateShortUrlAction extends AbstractCreateShortUrlAction class SingleStepCreateShortUrlAction extends AbstractCreateShortUrlAction
{ {
protected const ROUTE_PATH = '/short-urls/shorten'; protected const string ROUTE_PATH = '/short-urls/shorten';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
protected function buildShortUrlData(Request $request): ShortUrlCreation protected function buildShortUrlData(Request $request): ShortUrlCreation
{ {

View File

@@ -13,10 +13,10 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class DeleteTagsAction extends AbstractRestAction class DeleteTagsAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/tags'; protected const string ROUTE_PATH = '/tags';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE];
public function __construct(private TagServiceInterface $tagService) public function __construct(private readonly TagServiceInterface $tagService)
{ {
} }

View File

@@ -15,8 +15,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class ListTagsAction extends AbstractRestAction class ListTagsAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/tags'; protected const string ROUTE_PATH = '/tags';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private readonly TagServiceInterface $tagService) public function __construct(private readonly TagServiceInterface $tagService)
{ {

View File

@@ -15,8 +15,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class TagsStatsAction extends AbstractRestAction class TagsStatsAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/tags/stats'; protected const string ROUTE_PATH = '/tags/stats';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private readonly TagServiceInterface $tagService) public function __construct(private readonly TagServiceInterface $tagService)
{ {

View File

@@ -14,10 +14,10 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class UpdateTagAction extends AbstractRestAction class UpdateTagAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/tags'; protected const string ROUTE_PATH = '/tags';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_PUT]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_PUT];
public function __construct(private TagServiceInterface $tagService) public function __construct(private readonly TagServiceInterface $tagService)
{ {
} }

View File

@@ -18,7 +18,7 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
abstract class AbstractListVisitsAction extends AbstractRestAction abstract class AbstractListVisitsAction extends AbstractRestAction
{ {
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(protected readonly VisitsStatsHelperInterface $visitsHelper) public function __construct(protected readonly VisitsStatsHelperInterface $visitsHelper)
{ {

View File

@@ -13,8 +13,8 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class DeleteOrphanVisitsAction extends AbstractRestAction class DeleteOrphanVisitsAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/visits/orphan'; protected const string ROUTE_PATH = '/visits/orphan';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_DELETE];
public function __construct(private readonly VisitsDeleterInterface $visitsDeleter) public function __construct(private readonly VisitsDeleterInterface $visitsDeleter)
{ {

View File

@@ -14,7 +14,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey;
class DomainVisitsAction extends AbstractListVisitsAction class DomainVisitsAction extends AbstractListVisitsAction
{ {
protected const ROUTE_PATH = '/domains/{domain}/visits'; protected const string ROUTE_PATH = '/domains/{domain}/visits';
public function __construct( public function __construct(
VisitsStatsHelperInterface $visitsHelper, VisitsStatsHelperInterface $visitsHelper,

View File

@@ -13,10 +13,10 @@ use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
class GlobalVisitsAction extends AbstractRestAction class GlobalVisitsAction extends AbstractRestAction
{ {
protected const ROUTE_PATH = '/visits'; protected const string ROUTE_PATH = '/visits';
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET]; protected const array ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
public function __construct(private VisitsStatsHelperInterface $statsHelper) public function __construct(private readonly VisitsStatsHelperInterface $statsHelper)
{ {
} }

View File

@@ -11,7 +11,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey;
class NonOrphanVisitsAction extends AbstractListVisitsAction class NonOrphanVisitsAction extends AbstractListVisitsAction
{ {
protected const ROUTE_PATH = '/visits/non-orphan'; protected const string ROUTE_PATH = '/visits/non-orphan';
protected function getVisitsPaginator( protected function getVisitsPaginator(
ServerRequestInterface $request, ServerRequestInterface $request,

View File

@@ -12,7 +12,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey;
class OrphanVisitsAction extends AbstractListVisitsAction class OrphanVisitsAction extends AbstractListVisitsAction
{ {
protected const ROUTE_PATH = '/visits/orphan'; protected const string ROUTE_PATH = '/visits/orphan';
protected function getVisitsPaginator( protected function getVisitsPaginator(
ServerRequestInterface $request, ServerRequestInterface $request,

View File

@@ -12,7 +12,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey;
class ShortUrlVisitsAction extends AbstractListVisitsAction class ShortUrlVisitsAction extends AbstractListVisitsAction
{ {
protected const ROUTE_PATH = '/short-urls/{shortCode}/visits'; protected const string ROUTE_PATH = '/short-urls/{shortCode}/visits';
protected function getVisitsPaginator(Request $request, VisitsParams $params, ApiKey $apiKey): Pagerfanta protected function getVisitsPaginator(Request $request, VisitsParams $params, ApiKey $apiKey): Pagerfanta
{ {

View File

@@ -11,7 +11,7 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey;
class TagVisitsAction extends AbstractListVisitsAction class TagVisitsAction extends AbstractListVisitsAction
{ {
protected const ROUTE_PATH = '/tags/{tag}/visits'; protected const string ROUTE_PATH = '/tags/{tag}/visits';
protected function getVisitsPaginator(Request $request, VisitsParams $params, ApiKey $apiKey): Pagerfanta protected function getVisitsPaginator(Request $request, VisitsParams $params, ApiKey $apiKey): Pagerfanta
{ {

Some files were not shown because too many files have changed in this diff Show More