diff --git a/.dockerignore b/.dockerignore index e3aff686..dff3cea1 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ bin/rr config/autoload/*local* +config/params/shlink_dev_env.* data/infra data/cache/* data/log/* diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4ee94c70..e44c5fee 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,11 +16,20 @@ The first thing you need to do is fork the repository, and clone it in your loca Then you will have to follow these steps: -* Copy all files with `.local.php.dist` extension from `config/autoload` by removing the dist extension. +* Copy the `config/params/shlink_dev_env.php.dist` in the same directory, but removing the `.dist` extension: - For example the `common.local.php.dist` file should be copied as `common.local.php`. + ``` + cp config/params/shlink_dev_env.php.dist config/params/shlink_dev_env.php + ``` + + The `shlink_dev_env.php` file is gitignored, so you can customize it as you want. For example, by adding your own GeoLite license key. + +* Do the same with the `docker-compose.override.yml.dist`: + + ``` + cp docker-compose.override.yml.dist docker-compose.override.yml + ``` -* Copy the file `docker-compose.override.yml.dist` by also removing the `dist` extension. * Start-up the project by running `docker compose up`. The first time this command is run, it will create several containers that are used during development, so it may take some time. diff --git a/Dockerfile b/Dockerfile index 4251b3e4..e6e94734 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,7 +43,7 @@ RUN apk add --no-cache git && \ php composer.phar install --no-dev --prefer-dist --optimize-autoloader --no-progress --no-interaction && \ php composer.phar clear-cache && \ rm -r docker composer.* && \ - sed -i "s/%SHLINK_VERSION%/${SHLINK_VERSION}/g" config/autoload/app_options.global.php + sed -i "s/%SHLINK_VERSION%/${SHLINK_VERSION}/g" module/Core/src/Config/Options/AppOptions.php # Prepare final image @@ -61,7 +61,6 @@ EXPOSE 8080 # Copy config specific for the image COPY docker/docker-entrypoint.sh docker-entrypoint.sh -COPY docker/config/shlink_in_docker.local.php config/autoload/shlink_in_docker.local.php COPY docker/config/php.ini ${PHP_INI_DIR}/conf.d/ USER ${USER_ID} diff --git a/bin/test/run-api-tests.sh b/bin/test/run-api-tests.sh index ffc152b7..4c519a9b 100755 --- a/bin/test/run-api-tests.sh +++ b/bin/test/run-api-tests.sh @@ -17,8 +17,12 @@ touch $OUTPUT_LOGS # Try to stop server just in case it hanged in last execution [ "$TEST_RUNTIME" = 'rr' ] && bin/rr stop -f -w . +# Resolve .env file absolute path, as it fails to load with relative paths +TESTS_DOTENV="${PWD}/config/test/shlink-test.env" + echo 'Starting server...' [ "$TEST_RUNTIME" = 'rr' ] && bin/rr serve -p -w . -c=config/roadrunner/.rr.test.yml \ + --dotenv "$TESTS_DOTENV" \ -o=logs.output="${PWD}/${OUTPUT_LOGS}" \ -o=logs.channels.http.output="${PWD}/${OUTPUT_LOGS}" \ -o=logs.channels.server.output="${PWD}/${OUTPUT_LOGS}" & diff --git a/bin/test/run-cli-tests.sh b/bin/test/run-cli-tests.sh new file mode 100755 index 00000000..96ea6cfa --- /dev/null +++ b/bin/test/run-cli-tests.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env sh + +export APP_ENV=test +export TEST_ENV=cli +export DB_DRIVER="${DB_DRIVER:-"maria"}" +export GENERATE_COVERAGE="${GENERATE_COVERAGE:-"no"}" + +[ "$GENERATE_COVERAGE" != 'no' ] && export XDEBUG_MODE=coverage + +# Load and export test env vars +set -a +. ./config/test/shlink-test.env +set +a + +vendor/bin/phpunit --order-by=random --testdox --testdox-summary -c phpunit-cli.xml $* +TESTS_EXIT_CODE=$? + +# Exit this script with the same code as the tests. If tests failed, this script has to fail +exit $TESTS_EXIT_CODE diff --git a/build.sh b/build.sh index 7b77295f..6786c492 100755 --- a/build.sh +++ b/build.sh @@ -35,8 +35,8 @@ ${composerBin} install --no-dev --prefer-dist --optimize-autoloader --no-progres echo 'Deleting dev files...' rm composer.* -# Update Shlink version in config -sed -i "s/%SHLINK_VERSION%/${version}/g" config/autoload/app_options.global.php +# Update Shlink version +sed -i "s/%SHLINK_VERSION%/${version}/g" module/Core/src/Config/Options/AppOptions.php # Compressing file echo 'Compressing files...' diff --git a/composer.json b/composer.json index 6f8feba4..3e2a089d 100644 --- a/composer.json +++ b/composer.json @@ -18,64 +18,64 @@ "ext-json": "*", "ext-mbstring": "*", "ext-pdo": "*", - "akrabat/ip-address-middleware": "^2.1", - "cakephp/chronos": "^3.0.2", - "doctrine/dbal": "^4.1", - "doctrine/migrations": "^3.6", - "doctrine/orm": "^3.2", + "akrabat/ip-address-middleware": "^2.3", + "cakephp/chronos": "^3.1", + "doctrine/dbal": "^4.2", + "doctrine/migrations": "^3.8", + "doctrine/orm": "^3.3", "endroid/qr-code": "^6.0", "friendsofphp/proxy-manager-lts": "^1.0", "geoip2/geoip2": "^3.0", - "guzzlehttp/guzzle": "^7.5", + "guzzlehttp/guzzle": "^7.9", "hidehalo/nanoid-php": "^1.1", "jaybizzle/crawler-detect": "^1.2.116", - "laminas/laminas-config": "^3.8", + "laminas/laminas-config": "^3.9", "laminas/laminas-config-aggregator": "^1.15", - "laminas/laminas-diactoros": "^3.3", - "laminas/laminas-inputfilter": "^2.27", - "laminas/laminas-servicemanager": "^3.21", - "laminas/laminas-stdlib": "^3.17", - "matomo/matomo-php-tracker": "^3.2", - "mezzio/mezzio": "^3.17", - "mezzio/mezzio-fastroute": "^3.11", - "mezzio/mezzio-problem-details": "^1.13", + "laminas/laminas-diactoros": "^3.5", + "laminas/laminas-inputfilter": "^2.30", + "laminas/laminas-servicemanager": "^3.22", + "laminas/laminas-stdlib": "^3.19", + "matomo/matomo-php-tracker": "^3.3", + "mezzio/mezzio": "^3.20", + "mezzio/mezzio-fastroute": "^3.12", + "mezzio/mezzio-problem-details": "^1.15", "mlocati/ip-lib": "^1.18", "mobiledetect/mobiledetectlib": "^4.8", "pagerfanta/core": "^3.8", "ramsey/uuid": "^4.7", "shlinkio/doctrine-specification": "^2.1.1", - "shlinkio/shlink-common": "dev-main#e0c872c as 6.4", - "shlinkio/shlink-config": "^3.2.1", + "shlinkio/shlink-common": "dev-main#16d19b7 as 6.4", + "shlinkio/shlink-config": "^3.3", "shlinkio/shlink-event-dispatcher": "^4.1", "shlinkio/shlink-importer": "^5.3.2", "shlinkio/shlink-installer": "^9.2", - "shlinkio/shlink-ip-geolocation": "^4.0", + "shlinkio/shlink-ip-geolocation": "dev-main#6f35bd4 as 4.1", "shlinkio/shlink-json": "^1.1", "spiral/roadrunner": "^2024.1", "spiral/roadrunner-cli": "^2.6", "spiral/roadrunner-http": "^3.5", "spiral/roadrunner-jobs": "^4.5", - "symfony/console": "^7.0", - "symfony/filesystem": "^7.0", - "symfony/lock": "^7.0", - "symfony/process": "^7.0", - "symfony/string": "^7.0" + "symfony/console": "^7.1", + "symfony/filesystem": "^7.1", + "symfony/lock": "^7.1", + "symfony/process": "^7.1", + "symfony/string": "^7.1" }, "require-dev": { "devizzent/cebe-php-openapi": "^1.0.1", "devster/ubench": "^2.1", - "phpstan/phpstan": "^1.11", - "phpstan/phpstan-doctrine": "^1.4", + "phpstan/phpstan": "^1.12", + "phpstan/phpstan-doctrine": "^1.5", "phpstan/phpstan-phpunit": "^1.4", "phpstan/phpstan-symfony": "^1.4", "phpunit/php-code-coverage": "^11.0", "phpunit/phpcov": "^10.0", - "phpunit/phpunit": "^11.3", + "phpunit/phpunit": "^11.4", "roave/security-advisories": "dev-master", "shlinkio/php-coding-standard": "~2.3.0", - "shlinkio/shlink-test-utils": "^4.1", - "symfony/var-dumper": "^7.0", - "veewee/composer-run-parallel": "^1.3" + "shlinkio/shlink-test-utils": "^4.1.1", + "symfony/var-dumper": "^7.1", + "veewee/composer-run-parallel": "^1.4" }, "conflict": { "symfony/var-exporter": ">=6.3.9,<=6.4.0" @@ -136,9 +136,9 @@ "test:api:mssql": "DB_DRIVER=mssql composer test:api -- $*", "test:api:ci": "GENERATE_COVERAGE=yes composer test:api && vendor/bin/phpcov merge build/coverage-api --php build/coverage-api.cov && rm build/coverage-api/*.cov", "test:api:pretty": "GENERATE_COVERAGE=yes composer test:api && vendor/bin/phpcov merge build/coverage-api --html build/coverage-api/coverage-html && rm build/coverage-api/*.cov", - "test:cli": "APP_ENV=test DB_DRIVER=maria TEST_ENV=cli php vendor/bin/phpunit --order-by=random --testdox --testdox-summary -c phpunit-cli.xml", - "test:cli:ci": "XDEBUG_MODE=coverage GENERATE_COVERAGE=yes composer test:cli && vendor/bin/phpcov merge build/coverage-cli --php build/coverage-cli.cov && rm build/coverage-cli/*.cov", - "test:cli:pretty": "XDEBUG_MODE=coverage GENERATE_COVERAGE=yes composer test:cli && vendor/bin/phpcov merge build/coverage-cli --html build/coverage-cli/coverage-html && rm build/coverage-cli/*.cov", + "test:cli": "bin/test/run-cli-tests.sh", + "test:cli:ci": "GENERATE_COVERAGE=yes composer test:cli && vendor/bin/phpcov merge build/coverage-cli --php build/coverage-cli.cov && rm build/coverage-cli/*.cov", + "test:cli:pretty": "GENERATE_COVERAGE=yes composer test:cli && vendor/bin/phpcov merge build/coverage-cli --html build/coverage-cli/coverage-html && rm build/coverage-cli/*.cov", "swagger:validate": "php-openapi validate docs/swagger/swagger.json", "swagger:inline": "php-openapi inline docs/swagger/swagger.json docs/swagger/swagger-inlined.json", "clean:dev": "rm -f data/database.sqlite && rm -f config/params/generated_config.php" diff --git a/config/autoload/.gitignore b/config/autoload/.gitignore deleted file mode 100644 index 1a83fda6..00000000 --- a/config/autoload/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -local.php -*.local.php diff --git a/config/autoload/app_options.global.php b/config/autoload/app_options.global.php deleted file mode 100644 index 0b7ec937..00000000 --- a/config/autoload/app_options.global.php +++ /dev/null @@ -1,12 +0,0 @@ - [ - 'name' => 'Shlink', - 'version' => '%SHLINK_VERSION%', - ], - -]; diff --git a/config/autoload/app_options.local.php.dist b/config/autoload/app_options.local.php.dist deleted file mode 100644 index 14633a61..00000000 --- a/config/autoload/app_options.local.php.dist +++ /dev/null @@ -1,11 +0,0 @@ - [ - 'version' => 'latest', - ], - -]; diff --git a/config/autoload/common.global.php b/config/autoload/common.global.php index c7db57f1..0ae55ce3 100644 --- a/config/autoload/common.global.php +++ b/config/autoload/common.global.php @@ -3,13 +3,18 @@ declare(strict_types=1); use Laminas\ConfigAggregator\ConfigAggregator; +use Shlinkio\Shlink\Core\Config\EnvVars; -return [ +return (function () { + $isDev = EnvVars::isDevEnv(); - 'debug' => false, + return [ - // Disabling config cache for cli, ensures it's never used for RoadRunner, and also that console - // commands don't generate a cache file that's then used by php-fpm web executions - ConfigAggregator::ENABLE_CACHE => PHP_SAPI !== 'cli', + 'debug' => $isDev, -]; + // Disabling config cache for cli, ensures it's never used for RoadRunner, and also that console + // commands don't generate a cache file that's then used by php-fpm web executions + ConfigAggregator::ENABLE_CACHE => ! $isDev && PHP_SAPI !== 'cli', + + ]; +})(); diff --git a/config/autoload/common.local.php.dist b/config/autoload/common.local.php.dist deleted file mode 100644 index f29c74b0..00000000 --- a/config/autoload/common.local.php.dist +++ /dev/null @@ -1,12 +0,0 @@ - true, - ConfigAggregator::ENABLE_CACHE => false, - -]; diff --git a/config/autoload/delete_short_urls.global.php b/config/autoload/delete_short_urls.global.php deleted file mode 100644 index 2d203ea1..00000000 --- a/config/autoload/delete_short_urls.global.php +++ /dev/null @@ -1,20 +0,0 @@ -loadFromEnv(); - - return [ - - 'delete_short_urls' => [ - 'check_visits_threshold' => $threshold !== null, - 'visits_threshold' => (int) ($threshold ?? DEFAULT_DELETE_SHORT_URL_THRESHOLD), - ], - - ]; -})(); diff --git a/config/autoload/dependencies.global.php b/config/autoload/dependencies.global.php index 469171ca..0a99d323 100644 --- a/config/autoload/dependencies.global.php +++ b/config/autoload/dependencies.global.php @@ -11,6 +11,7 @@ use Psr\Http\Client\ClientInterface; use Psr\Http\Message\ServerRequestFactoryInterface; use Psr\Http\Message\StreamFactoryInterface; use Psr\Http\Message\UploadedFileFactoryInterface; +use Shlinkio\Shlink\Core\Config\EnvVars; use Spiral\RoadRunner\Http\PSR7Worker; use Spiral\RoadRunner\WorkerInterface; use Symfony\Component\Filesystem\Filesystem; @@ -36,7 +37,7 @@ return [ 'lazy_services' => [ 'proxies_target_dir' => 'data/proxies', 'proxies_namespace' => 'ShlinkProxy', - 'write_proxy_files' => true, + 'write_proxy_files' => EnvVars::isProdEnv(), ], ], diff --git a/config/autoload/dependencies.local.php.dist b/config/autoload/dependencies.local.php.dist deleted file mode 100644 index d9569029..00000000 --- a/config/autoload/dependencies.local.php.dist +++ /dev/null @@ -1,24 +0,0 @@ - [ - 'lazy_services' => [ - 'write_proxy_files' => false, - ], - - 'initializers' => [ - function (ContainerInterface $container, $instance): void { - if ($instance instanceof Log\LoggerAwareInterface) { - $instance->setLogger($container->get(Log\LoggerInterface::class)); - } - }, - ], - ], - -]; diff --git a/config/autoload/entity-manager.local.php.dist b/config/autoload/entity-manager.local.php.dist deleted file mode 100644 index abe5dd87..00000000 --- a/config/autoload/entity-manager.local.php.dist +++ /dev/null @@ -1,46 +0,0 @@ - [ - 'connection' => [ - // MySQL - 'user' => 'root', - 'password' => 'root', - 'driver' => 'pdo_mysql', - 'host' => 'shlink_db_mysql', - 'dbname' => 'shlink', -// 'dbname' => 'shlink_foo', - 'charset' => 'utf8mb4', - - // MariaDB -// 'user' => 'root', -// 'password' => 'root', -// 'driver' => 'pdo_mysql', -// 'host' => 'shlink_db_maria', -// 'dbname' => 'shlink_foo', -// 'charset' => 'utf8mb4', - - // Postgres -// 'user' => 'postgres', -// 'password' => 'root', -// 'driver' => 'pdo_pgsql', -// 'host' => 'shlink_db_postgres', -// 'dbname' => 'shlink_foo', -// 'charset' => 'utf8', - - // MSSQL -// 'user' => 'sa', -// 'password' => 'Passw0rd!', -// 'driver' => 'pdo_sqlsrv', -// 'host' => 'shlink_db_ms', -// 'dbname' => 'shlink_foo', -// 'driverOptions' => [ -// 'TrustServerCertificate' => 'true', -// ], - ], - ], - -]; diff --git a/config/autoload/logger.global.php b/config/autoload/logger.global.php index c7d7d757..56ba42bb 100644 --- a/config/autoload/logger.global.php +++ b/config/autoload/logger.global.php @@ -14,23 +14,33 @@ use Shlinkio\Shlink\Common\Logger\LoggerFactory; use Shlinkio\Shlink\Common\Logger\LoggerType; use Shlinkio\Shlink\Common\Middleware\AccessLogMiddleware; use Shlinkio\Shlink\Common\Middleware\RequestIdMiddleware; +use Shlinkio\Shlink\Core\Config\EnvVars; use Shlinkio\Shlink\Core\EventDispatcher\Helper\RequestIdProvider; use Shlinkio\Shlink\EventDispatcher\Util\RequestIdProviderInterface; +use function Shlinkio\Shlink\Config\env; use function Shlinkio\Shlink\Config\runningInRoadRunner; return (static function (): array { + $isDev = EnvVars::isDevEnv(); $common = [ - 'level' => Level::Info->value, + 'level' => $isDev ? Level::Debug->value : Level::Info->value, 'processors' => [RequestIdMiddleware::class], 'line_format' => '[%datetime%] [%extra.' . RequestIdMiddleware::ATTRIBUTE . '%] %channel%.%level_name% - %message%', ]; + // In dev env or the docker container, stream Shlink logs to stderr, otherwise send them to a file + $useStreamForShlinkLogger = $isDev || env('SHLINK_RUNTIME') !== null; + return [ 'logger' => [ - 'Shlink' => [ + 'Shlink' => $useStreamForShlinkLogger ? [ + 'type' => LoggerType::STREAM->value, + 'destination' => 'php://stderr', + ...$common, + ] : [ 'type' => LoggerType::FILE->value, ...$common, ], diff --git a/config/autoload/logger.local.php.dist b/config/autoload/logger.local.php.dist deleted file mode 100644 index fe2c8c54..00000000 --- a/config/autoload/logger.local.php.dist +++ /dev/null @@ -1,18 +0,0 @@ - [ - 'Shlink' => [ - 'type' => LoggerType::STREAM->value, - 'destination' => 'php://stderr', - 'level' => Level::Debug->value, - ], - ], - -]; diff --git a/config/autoload/matomo.global.php b/config/autoload/matomo.global.php deleted file mode 100644 index d7369ea7..00000000 --- a/config/autoload/matomo.global.php +++ /dev/null @@ -1,16 +0,0 @@ - [ - 'enabled' => (bool) EnvVars::MATOMO_ENABLED->loadFromEnv(), - 'base_url' => EnvVars::MATOMO_BASE_URL->loadFromEnv(), - 'site_id' => EnvVars::MATOMO_SITE_ID->loadFromEnv(), - 'api_token' => EnvVars::MATOMO_API_TOKEN->loadFromEnv(), - ], - -]; diff --git a/config/autoload/matomo.local.php.dist b/config/autoload/matomo.local.php.dist deleted file mode 100644 index 2a940407..00000000 --- a/config/autoload/matomo.local.php.dist +++ /dev/null @@ -1,26 +0,0 @@ - [ -// 'enabled' => true, -// 'base_url' => 'http://shlink_matomo', -// 'site_id' => '...', -// 'api_token' => '...', - ], - -]; diff --git a/config/autoload/mercure.global.php b/config/autoload/mercure.global.php index c50e1f8e..83abed1a 100644 --- a/config/autoload/mercure.global.php +++ b/config/autoload/mercure.global.php @@ -8,34 +8,31 @@ use Shlinkio\Shlink\Core\Config\EnvVars; use Symfony\Component\Mercure\Hub; use Symfony\Component\Mercure\HubInterface; -return (static function (): array { - $publicUrl = EnvVars::MERCURE_PUBLIC_HUB_URL->loadFromEnv(); +return [ - return [ + // This config is used by shlink-common. Do not delete + 'mercure' => [ + 'public_hub_url' => EnvVars::MERCURE_PUBLIC_HUB_URL->loadFromEnv(), + 'internal_hub_url' => EnvVars::MERCURE_INTERNAL_HUB_URL->loadFromEnv(), + 'jwt_secret' => EnvVars::MERCURE_JWT_SECRET->loadFromEnv(), + 'jwt_issuer' => 'Shlink', + ], - 'mercure' => [ - 'public_hub_url' => $publicUrl, - 'internal_hub_url' => EnvVars::MERCURE_INTERNAL_HUB_URL->loadFromEnv(), - 'jwt_secret' => EnvVars::MERCURE_JWT_SECRET->loadFromEnv(), - 'jwt_issuer' => 'Shlink', - ], - - 'dependencies' => [ - 'delegators' => [ - LcobucciJwtProvider::class => [ - LazyServiceFactory::class, - ], - Hub::class => [ - LazyServiceFactory::class, - ], + 'dependencies' => [ + 'delegators' => [ + LcobucciJwtProvider::class => [ + LazyServiceFactory::class, ], - 'lazy_services' => [ - 'class_map' => [ - LcobucciJwtProvider::class => LcobucciJwtProvider::class, - Hub::class => HubInterface::class, - ], + Hub::class => [ + LazyServiceFactory::class, ], ], + 'lazy_services' => [ + 'class_map' => [ + LcobucciJwtProvider::class => LcobucciJwtProvider::class, + Hub::class => HubInterface::class, + ], + ], + ], - ]; -})(); +]; diff --git a/config/autoload/mercure.local.php.dist b/config/autoload/mercure.local.php.dist deleted file mode 100644 index 13a74022..00000000 --- a/config/autoload/mercure.local.php.dist +++ /dev/null @@ -1,13 +0,0 @@ - [ - 'public_hub_url' => 'http://localhost:8002', - 'internal_hub_url' => 'http://shlink_mercure_proxy', - 'jwt_secret' => 'mercure_jwt_key_long_enough_to_avoid_error', - ], - -]; diff --git a/config/autoload/qr-codes.global.php b/config/autoload/qr-codes.global.php deleted file mode 100644 index 23caadf2..00000000 --- a/config/autoload/qr-codes.global.php +++ /dev/null @@ -1,21 +0,0 @@ - [ - 'size' => (int) EnvVars::DEFAULT_QR_CODE_SIZE->loadFromEnv(), - 'margin' => (int) EnvVars::DEFAULT_QR_CODE_MARGIN->loadFromEnv(), - 'format' => EnvVars::DEFAULT_QR_CODE_FORMAT->loadFromEnv(), - 'error_correction' => EnvVars::DEFAULT_QR_CODE_ERROR_CORRECTION->loadFromEnv(), - 'round_block_size' => (bool) EnvVars::DEFAULT_QR_CODE_ROUND_BLOCK_SIZE->loadFromEnv(), - 'enabled_for_disabled_short_urls' => (bool) EnvVars::QR_CODE_FOR_DISABLED_SHORT_URLS->loadFromEnv(), - 'color' => EnvVars::DEFAULT_QR_CODE_COLOR->loadFromEnv(), - 'bg_color' => EnvVars::DEFAULT_QR_CODE_BG_COLOR->loadFromEnv(), - 'logo_url' => EnvVars::DEFAULT_QR_CODE_LOGO_URL->loadFromEnv(), - ], - -]; diff --git a/config/autoload/rabbit.global.php b/config/autoload/rabbit.global.php index 86e2dd6a..c9532377 100644 --- a/config/autoload/rabbit.global.php +++ b/config/autoload/rabbit.global.php @@ -6,6 +6,7 @@ use Shlinkio\Shlink\Core\Config\EnvVars; return [ + // This config is used by shlink-common. Do not delete 'rabbitmq' => [ 'enabled' => (bool) EnvVars::RABBITMQ_ENABLED->loadFromEnv(), 'host' => EnvVars::RABBITMQ_HOST->loadFromEnv(), diff --git a/config/autoload/rabbit.local.php.dist b/config/autoload/rabbit.local.php.dist deleted file mode 100644 index 37faf181..00000000 --- a/config/autoload/rabbit.local.php.dist +++ /dev/null @@ -1,15 +0,0 @@ - [ - 'enabled' => true, - 'host' => 'shlink_rabbitmq', - 'port' => 5672, - 'user' => 'rabbit', - 'password' => 'rabbit', - ], - -]; diff --git a/config/autoload/redirects.global.php b/config/autoload/redirects.global.php deleted file mode 100644 index dbf026db..00000000 --- a/config/autoload/redirects.global.php +++ /dev/null @@ -1,20 +0,0 @@ - [ - 'invalid_short_url' => EnvVars::DEFAULT_INVALID_SHORT_URL_REDIRECT->loadFromEnv(), - 'regular_404' => EnvVars::DEFAULT_REGULAR_404_REDIRECT->loadFromEnv(), - 'base_url' => EnvVars::DEFAULT_BASE_URL_REDIRECT->loadFromEnv(), - ], - - 'redirects' => [ - 'redirect_status_code' => (int) EnvVars::REDIRECT_STATUS_CODE->loadFromEnv(), - 'redirect_cache_lifetime' => (int) EnvVars::REDIRECT_CACHE_LIFETIME->loadFromEnv(), - ], - -]; diff --git a/config/autoload/redis.local.php.local b/config/autoload/redis.local.php.local deleted file mode 100644 index 7fd57112..00000000 --- a/config/autoload/redis.local.php.local +++ /dev/null @@ -1,26 +0,0 @@ - [ - 'redis' => [ - 'servers' => 'tcp://shlink_redis:6379', -// 'servers' => 'tcp://barbar@shlink_redis_acl:6379', -// 'servers' => 'tcp://foo:bar@shlink_redis_acl:6379', - ], - ], - - 'redis' => [ - 'pub_sub_enabled' => true, - ], - - 'dependencies' => [ - 'aliases' => [ - // With this config, a user could alias 'lock_store' => 'redis_lock_store' to override the default -// 'lock_store' => 'redis_lock_store', - ], - ], - -]; diff --git a/config/autoload/robots.global.php b/config/autoload/robots.global.php deleted file mode 100644 index 35235d72..00000000 --- a/config/autoload/robots.global.php +++ /dev/null @@ -1,14 +0,0 @@ - [ - 'allow-all-short-urls' => (bool) Config\EnvVars::ROBOTS_ALLOW_ALL_SHORT_URLS->loadFromEnv(), - 'user-agents' => splitByComma(Config\EnvVars::ROBOTS_USER_AGENTS->loadFromEnv()), - ], - -]; diff --git a/config/autoload/router.global.php b/config/autoload/router.global.php index db389f3a..0464ca83 100644 --- a/config/autoload/router.global.php +++ b/config/autoload/router.global.php @@ -13,7 +13,7 @@ return [ 'fastroute' => [ // Disabling config cache for cli, ensures it's never used for RoadRunner, and also that console // commands don't generate a cache file that's then used by php-fpm web executions - FastRouteRouter::CONFIG_CACHE_ENABLED => PHP_SAPI !== 'cli', + FastRouteRouter::CONFIG_CACHE_ENABLED => EnvVars::isProdEnv() && PHP_SAPI !== 'cli', FastRouteRouter::CONFIG_CACHE_FILE => 'data/cache/fastroute_cached_routes.php', ], ], diff --git a/config/autoload/router.local.php.dist b/config/autoload/router.local.php.dist deleted file mode 100644 index 39bd7169..00000000 --- a/config/autoload/router.local.php.dist +++ /dev/null @@ -1,16 +0,0 @@ - [ -// 'base_path' => '', - 'fastroute' => [ - FastRouteRouter::CONFIG_CACHE_ENABLED => false, - ], - ], - -]; diff --git a/config/autoload/routes.config.php b/config/autoload/routes.config.php index f7c6ce07..da3d1778 100644 --- a/config/autoload/routes.config.php +++ b/config/autoload/routes.config.php @@ -19,8 +19,6 @@ use function sprintf; return (static function (): array { $dropDomainMiddleware = Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class; $overrideDomainMiddleware = Middleware\ShortUrl\OverrideDomainMiddleware::class; - - // TODO This should be based on config, not the env var $shortUrlRouteSuffix = EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv() ? '[/]' : ''; return [ diff --git a/config/autoload/tracking.global.php b/config/autoload/tracking.global.php deleted file mode 100644 index 713a209e..00000000 --- a/config/autoload/tracking.global.php +++ /dev/null @@ -1,38 +0,0 @@ - [ - // Tells if IP addresses should be anonymized before persisting, to fulfil data protection regulations - // This applies only if IP address tracking is enabled - 'anonymize_remote_addr' => (bool) EnvVars::ANONYMIZE_REMOTE_ADDR->loadFromEnv(), - - // Tells if visits to not-found URLs should be tracked. The disable_tracking option takes precedence - 'track_orphan_visits' => (bool) EnvVars::TRACK_ORPHAN_VISITS->loadFromEnv(), - - // A query param that, if provided, will disable tracking of one particular visit. Always takes precedence - 'disable_track_param' => EnvVars::DISABLE_TRACK_PARAM->loadFromEnv(), - - // If true, visits will not be tracked at all - 'disable_tracking' => (bool) EnvVars::DISABLE_TRACKING->loadFromEnv(), - - // If true, visits will be tracked, but neither the IP address, nor the location will be resolved - 'disable_ip_tracking' => (bool) EnvVars::DISABLE_IP_TRACKING->loadFromEnv(), - - // If true, the referrer will not be tracked - 'disable_referrer_tracking' => (bool) EnvVars::DISABLE_REFERRER_TRACKING->loadFromEnv(), - - // If true, the user agent will not be tracked - 'disable_ua_tracking' => (bool) EnvVars::DISABLE_UA_TRACKING->loadFromEnv(), - - // A list of IP addresses, patterns or CIDR blocks from which tracking is disabled by default - 'disable_tracking_from' => splitByComma(EnvVars::DISABLE_TRACKING_FROM->loadFromEnv()), - ], - -]; diff --git a/config/autoload/url-shortener.global.php b/config/autoload/url-shortener.global.php deleted file mode 100644 index 98b07ea2..00000000 --- a/config/autoload/url-shortener.global.php +++ /dev/null @@ -1,34 +0,0 @@ -loadFromEnv(), - MIN_SHORT_CODES_LENGTH, - ); - $modeFromEnv = EnvVars::SHORT_URL_MODE->loadFromEnv(); - $mode = ShortUrlMode::tryFrom($modeFromEnv) ?? ShortUrlMode::STRICT; - - return [ - - 'url_shortener' => [ - 'domain' => [ // TODO Refactor this structure to url_shortener.schema and url_shortener.default_domain - 'schema' => ((bool) EnvVars::IS_HTTPS_ENABLED->loadFromEnv()) ? 'https' : 'http', - 'hostname' => EnvVars::DEFAULT_DOMAIN->loadFromEnv(), - ], - 'default_short_codes_length' => $shortCodesLength, - 'auto_resolve_titles' => (bool) EnvVars::AUTO_RESOLVE_TITLES->loadFromEnv(), - 'append_extra_path' => (bool) EnvVars::REDIRECT_APPEND_EXTRA_PATH->loadFromEnv(), - 'multi_segment_slugs_enabled' => (bool) EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->loadFromEnv(), - 'trailing_slash_enabled' => (bool) EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(), - 'mode' => $mode, - ], - - ]; -})(); diff --git a/config/autoload/url-shortener.local.php.dist b/config/autoload/url-shortener.local.php.dist deleted file mode 100644 index 715d2822..00000000 --- a/config/autoload/url-shortener.local.php.dist +++ /dev/null @@ -1,21 +0,0 @@ - [ - 'domain' => [ - 'schema' => 'http', - 'hostname' => sprintf('localhost:%s', match (true) { - runningInRoadRunner() => '8800', - default => '8000', - }), - ], -// 'multi_segment_slugs_enabled' => true, -// 'trailing_slash_enabled' => true, - ], - -]; diff --git a/config/config.php b/config/config.php index 40f88ea3..92c69ba0 100644 --- a/config/config.php +++ b/config/config.php @@ -8,10 +8,7 @@ use Laminas\ConfigAggregator; use Laminas\Diactoros; use Mezzio; use Mezzio\ProblemDetails; - -use function Shlinkio\Shlink\Config\env; - -$isTestEnv = env('APP_ENV') === 'test'; +use Shlinkio\Shlink\Core\Config\EnvVars; return (new ConfigAggregator\ConfigAggregator( providers: [ @@ -29,10 +26,10 @@ return (new ConfigAggregator\ConfigAggregator( CLI\ConfigProvider::class, Rest\ConfigProvider::class, new ConfigAggregator\PhpFileProvider('config/autoload/{,*.}global.php'), - // Local config should not be loaded during tests, whereas test config should be loaded ONLY during tests - new ConfigAggregator\PhpFileProvider( - $isTestEnv ? 'config/test/*.global.php' : 'config/autoload/{,*.}local.php', - ), + // Test config should be loaded ONLY during tests + EnvVars::isTestEnv() + ? new ConfigAggregator\PhpFileProvider('config/test/*.global.php') + : new ConfigAggregator\ArrayProvider([]), // Routes have to be loaded last new ConfigAggregator\PhpFileProvider('config/autoload/routes.config.php'), ], diff --git a/config/container.php b/config/container.php index 3a1e3355..e207fe16 100644 --- a/config/container.php +++ b/config/container.php @@ -15,8 +15,8 @@ chdir(dirname(__DIR__)); require 'vendor/autoload.php'; -// Promote env vars from installer config -loadEnvVarsFromConfig('config/params/generated_config.php', enumValues(EnvVars::class)); +// Promote env vars from installer or dev config +loadEnvVarsFromConfig('config/params/*.php', enumValues(EnvVars::class)); // This is one of the first files loaded. Configure the timezone and memory limit here ini_set('memory_limit', EnvVars::MEMORY_LIMIT->loadFromEnv()); diff --git a/config/params/.gitignore b/config/params/.gitignore index d6b7ef32..36565258 100644 --- a/config/params/.gitignore +++ b/config/params/.gitignore @@ -1,2 +1,3 @@ * !.gitignore +!*.dist diff --git a/config/params/shlink_dev_env.php.dist b/config/params/shlink_dev_env.php.dist new file mode 100644 index 00000000..2a3905dc --- /dev/null +++ b/config/params/shlink_dev_env.php.dist @@ -0,0 +1,76 @@ +value => 'dev', +// EnvVars::GEOLITE_LICENSE_KEY->value => '', + + // URL shortener + EnvVars::DEFAULT_DOMAIN->value => 'localhost:8800', + EnvVars::IS_HTTPS_ENABLED->value => false, + + // Database - MySQL + EnvVars::DB_DRIVER->value => 'mysql', + EnvVars::DB_USER->value => 'root', + EnvVars::DB_PASSWORD->value => 'root', + EnvVars::DB_NAME->value => 'shlink', +// EnvVars::DB_NAME->value => 'shlink_foo', + EnvVars::DB_HOST->value => 'shlink_db_mysql', + + // Database - Maria +// EnvVars::DB_DRIVER->value => 'maria', +// EnvVars::DB_USER->value => 'root', +// EnvVars::DB_PASSWORD->value => 'root', +// EnvVars::DB_NAME->value => 'shlink_foo', +// EnvVars::DB_HOST->value => 'shlink_db_maria', + + // Database - Postgres +// EnvVars::DB_DRIVER->value => 'postgres', +// EnvVars::DB_USER->value => 'postgres', +// EnvVars::DB_PASSWORD->value => 'root', +// EnvVars::DB_NAME->value => 'shlink_foo', +// EnvVars::DB_HOST->value => 'shlink_db_postgres', + + // Database - MSSQL +// EnvVars::DB_DRIVER->value => 'mssql', +// EnvVars::DB_USER->value => 'sa', +// EnvVars::DB_PASSWORD->value => 'Passw0rd!', +// EnvVars::DB_NAME->value => 'shlink_foo', +// EnvVars::DB_HOST->value => 'shlink_db_ms', + + // Matomo + // Dev matomo instance needs to be manually configured once before enabling the configuration below: + // 1. Go to http://localhost:8003 and follow the installation instructions. + // 2. Open data/infra/matomo/config/config.ini.php and replace `trusted_hosts[] = "localhost"` with + // `trusted_hosts[] = "localhost:8003"` (see https://github.com/matomo-org/matomo/issues/9549) + // 3. Go to http://localhost:8003/index.php?module=SitesManager&action=index and paste the ID for the site you just + // created into the `MATOMO_SITE_ID` var below. + // 4. Go to http://localhost:8003/index.php?module=UsersManager&action=userSecurity, scroll down, click + // "Create new token" and once generated, paste the token into the `MATOMO_API_TOKEN` var below. + // 5. Copy the config below and paste it in a new shlink-dev.local.env file. + EnvVars::MATOMO_ENABLED->value => false, + EnvVars::MATOMO_BASE_URL->value => 'http://shlink_matomo', +// EnvVars::MATOMO_SITE_ID->value => , +// EnvVars::MATOMO_API_TOKEN->value => , + + // Mercure + EnvVars::MERCURE_PUBLIC_HUB_URL->value => 'http://localhost:8002', + EnvVars::MERCURE_INTERNAL_HUB_URL->value => 'http://shlink_mercure_proxy', + EnvVars::MERCURE_JWT_SECRET->value => 'mercure_jwt_key_long_enough_to_avoid_error', + + // RabbitMQ + EnvVars::RABBITMQ_ENABLED->value => true, + EnvVars::RABBITMQ_HOST->value => 'shlink_rabbitmq', + EnvVars::RABBITMQ_PORT->value => 5672, + EnvVars::RABBITMQ_USER->value => 'rabbit', + EnvVars::RABBITMQ_PASSWORD->value => 'rabbit', + + // Redis + EnvVars::REDIS_PUB_SUB_ENABLED->value => true, + EnvVars::REDIS_SERVERS->value => 'tcp://shlink_redis:6379', + +]; diff --git a/config/test/shlink-test.env b/config/test/shlink-test.env new file mode 100644 index 00000000..48af9b6e --- /dev/null +++ b/config/test/shlink-test.env @@ -0,0 +1,5 @@ +APP_ENV=test + +# URL shortener +DEFAULT_DOMAIN=s.test +IS_HTTPS_ENABLED=false diff --git a/config/test/test_config.global.php b/config/test/test_config.global.php index aad5e9d0..bd6771e6 100644 --- a/config/test/test_config.global.php +++ b/config/test/test_config.global.php @@ -93,13 +93,6 @@ return [ ConfigAggregator::ENABLE_CACHE => false, FastRouteRouter::CONFIG_CACHE_ENABLED => false, - 'url_shortener' => [ - 'domain' => [ - 'schema' => 'http', - 'hostname' => 's.test', - ], - ], - 'routes' => [ // This route is used to test that title resolution is skipped if the long URL times out [ @@ -120,13 +113,6 @@ return [ ], ], - // Disable mercure integration during E2E tests - 'mercure' => [ - 'public_hub_url' => null, - 'internal_hub_url' => null, - 'jwt_secret' => null, - ], - 'dependencies' => [ 'services' => [ 'shlink_test_api_client' => new Client([ diff --git a/data/infra/roadrunner.Dockerfile b/data/infra/roadrunner.Dockerfile index 2cb660d2..0bf251f6 100644 --- a/data/infra/roadrunner.Dockerfile +++ b/data/infra/roadrunner.Dockerfile @@ -73,5 +73,7 @@ CMD \ if [[ ! -d "./vendor" ]]; then /usr/local/bin/composer install ; fi && \ # Download roadrunner binary if [[ ! -f "./bin/rr" ]]; then ./vendor/bin/rr get --no-interaction --no-config --location bin/ && chmod +x bin/rr ; fi && \ + # Create env file if it does not exist yet + if [[ ! -f "./config/params/shlink_dev_env.php" ]]; then cp ./config/params/shlink_dev_env.php.dist ./config/params/shlink_dev_env.php ; fi && \ # Run with `exec` so that signals are properly handled exec ./bin/rr serve -c config/roadrunner/.rr.dev.yml diff --git a/docker-compose.yml b/docker-compose.yml index 41f54cba..050e6803 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -34,6 +34,7 @@ services: - shlink_matomo environment: LC_ALL: C + DEFAULT_DOMAIN: localhost:8000 extra_hosts: - 'host.docker.internal:host-gateway' diff --git a/docker/config/shlink_in_docker.local.php b/docker/config/shlink_in_docker.local.php deleted file mode 100644 index 2d5d6a06..00000000 --- a/docker/config/shlink_in_docker.local.php +++ /dev/null @@ -1,18 +0,0 @@ - [ - 'Shlink' => [ - 'type' => LoggerType::STREAM->value, - 'destination' => 'php://stderr', - ], - ], - -]; diff --git a/docs/adr/2024-10-24-handle-dev-and-tests-config-via-env-vars-instead-of-local-config-files.md b/docs/adr/2024-10-24-handle-dev-and-tests-config-via-env-vars-instead-of-local-config-files.md new file mode 100644 index 00000000..004c2fce --- /dev/null +++ b/docs/adr/2024-10-24-handle-dev-and-tests-config-via-env-vars-instead-of-local-config-files.md @@ -0,0 +1,61 @@ +# Handle dev and tests config via env vars instead of local config files + +* Status: Accepted +* Date: 2024-10-24 + +## Context and problem statement + +Due to the tools used by Shlink (Zend Expressive first and Mezzio later), configuration has always been handled via the config aggregator, which is a package that continues with Zend Framework 2 config management philosophy: + +1. Define multiple config files, scoped to their own context, that are merge at runtime. +2. Overwrite with so-called "local" config files, which define values used only during development, and should not be shipped to production. + +However, since Shlink started to support other runtimes and added an official docker image, env vars have started to become a central part of the config definition system. + +That has evolved into a system where production config can be read from env vars, but dev config is expected to be defined via local config files, forcing to maintain two approaches to load config that need to coexist. + +On top of that, keeping dev configs in multiple files makes it harder to keep track of everything. + +Because of that, I'm proposing to switch to an env-var-based approach for dev custom configs, and get rid of local config files. + +## Considered options + +1. Define dev env vars in a single `.env` file which is loaded to containers via docker compose `env-file` option. +2. Define dev env vars in a single `.env` file which is loaded via RoadRunner config. +3. Define dev env vars in a single PHP file returning a map that's then loaded with `loadEnvVarsFromConfig`. +4. Keep local config files and don't change anything. + +## Decision outcome + +Defining env vars in a PHP file has the benefit that any change will take effect immediately, so the decision is to go with option 3. + +## Pros and Cons of the Options + +### 1 - .env file via docker compose + +* Good: because it does not require any special mechanism to feed the env vars into the app. +* Good: because it's a standard format known by many. +* Bad: because dev config gets leaked to tests when run inside the container, breaking some existing ones, and forcing to remember this for future tests. +* Bad: because any change to the env file requires the containers to be manually restarted, or putting some new mechanism in place to restart them automatically. + +### 2 - .env file via RoadRunner + +* Good: because it does not require any special mechanism to feed the env vars into the app. +* Good: because it's a standard format known by many. +* Good: because dev config does not get leaked into tests. +* Bad: because any change to the env file requires the containers to be manually restarted, or putting some new mechanism in place to restart them automatically. + +### 3 - PHP file via `loadEnvVarsFromConfig` + +* Good: because the existing call to `loadEnvVarsFromConfig` can be reused by tweaking a bit the glob pattern, so no new dependencies are needed. +* Good: because dev config does not get leaked into tests, and test-specific env vars can be fed using the same mechanism. +* Good: because changes are picked up instantly by both RoadRunner and php-fpm. +* Good: because env vars can be imported from `EnvVars` class, removing the chances of human mistakes and typos. +* Bad: because people not familiar with the project may not expect env vars to be defined in that format. + +### 4 - keep local config + +* Good: because no changes are needed in the project. +* Bad: because managing multiple local config files makes things harder to maintain. +* Bad: because setting-up the project from scratch requires more steps, or an external package to handle config files. +* Bad: because the project needs to keep two ways to load dev configs, and reading an env var does not warranty you are getting the single source of truth. diff --git a/docs/adr/README.md b/docs/adr/README.md index bafb80b5..fa0e7215 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -2,7 +2,8 @@ Here listed you will find the different architectural decisions taken in the project, including all the reasoning behind it, options considered, and final outcome. -* [2023-07-09Build `latest` docker image only for actual releases](2023-07-09-build-latest-docker-image-only-for-actual-releases.md) +* [2024-10-24 Handle dev and tests config via env vars instead of local config files](2024-10-24-handle-dev-and-tests-config-via-env-vars-instead-of-local-config-files.md) +* [2023-07-09 Build `latest` docker image only for actual releases](2023-07-09-build-latest-docker-image-only-for-actual-releases.md) * [2023-01-06 Support any HTTP method in short URLs](2023-01-06-support-any-http-method-in-short-urls.md) * [2022-08-05 Support multi-segment custom slugs](2022-08-05-support-multi-segment-custom-slugs.md) * [2022-01-15 Update env vars behavior to have precedence over installer options](2022-01-15-update-env-vars-behavior-to-have-precedence-over-installer-options.md) diff --git a/module/CLI/config/dependencies.config.php b/module/CLI/config/dependencies.config.php index 0ee1a331..2f098998 100644 --- a/module/CLI/config/dependencies.config.php +++ b/module/CLI/config/dependencies.config.php @@ -7,10 +7,10 @@ namespace Shlinkio\Shlink\CLI; use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory; use Laminas\ServiceManager\Factory\InvokableFactory; use Shlinkio\Shlink\Common\Doctrine\NoDbNameConnectionFactory; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Domain\DomainService; use Shlinkio\Shlink\Core\Matomo; -use Shlinkio\Shlink\Core\Options\TrackingOptions; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\RedirectRule\ShortUrlRedirectRuleService; use Shlinkio\Shlink\Core\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier; @@ -88,7 +88,7 @@ return [ TrackingOptions::class, ], Util\ProcessRunner::class => [SymfonyCli\Helper\ProcessHelper::class], - ApiKey\RoleResolver::class => [DomainService::class, 'config.url_shortener.domain.hostname'], + ApiKey\RoleResolver::class => [DomainService::class, UrlShortenerOptions::class], Command\ShortUrl\CreateShortUrlCommand::class => [ ShortUrl\UrlShortener::class, diff --git a/module/CLI/src/ApiKey/RoleResolver.php b/module/CLI/src/ApiKey/RoleResolver.php index 76787451..ece56c77 100644 --- a/module/CLI/src/ApiKey/RoleResolver.php +++ b/module/CLI/src/ApiKey/RoleResolver.php @@ -5,6 +5,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\ApiKey; use Shlinkio\Shlink\CLI\Exception\InvalidRoleConfigException; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition; use Shlinkio\Shlink\Rest\ApiKey\Role; @@ -12,11 +13,11 @@ use Symfony\Component\Console\Input\InputInterface; use function is_string; -class RoleResolver implements RoleResolverInterface +readonly class RoleResolver implements RoleResolverInterface { public function __construct( - private readonly DomainServiceInterface $domainService, - private readonly string $defaultDomain, + private DomainServiceInterface $domainService, + private UrlShortenerOptions $urlShortenerOptions, ) { } @@ -39,7 +40,7 @@ class RoleResolver implements RoleResolverInterface private function resolveRoleForAuthority(string $domainAuthority): RoleDefinition { - if ($domainAuthority === $this->defaultDomain) { + if ($domainAuthority === $this->urlShortenerOptions->defaultDomain) { throw InvalidRoleConfigException::forDomainOnlyWithDefaultDomain(); } diff --git a/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php b/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php index 0273da71..fdff2ddc 100644 --- a/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php +++ b/module/CLI/src/Command/ShortUrl/CreateShortUrlCommand.php @@ -6,8 +6,8 @@ namespace Shlinkio\Shlink\CLI\Command\ShortUrl; use Shlinkio\Shlink\CLI\Input\ShortUrlDataInput; use Shlinkio\Shlink\CLI\Util\ExitCode; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\UrlShortenerInterface; use Symfony\Component\Console\Command\Command; diff --git a/module/CLI/src/Factory/ApplicationFactory.php b/module/CLI/src/Factory/ApplicationFactory.php index ab716f7e..89cf4271 100644 --- a/module/CLI/src/Factory/ApplicationFactory.php +++ b/module/CLI/src/Factory/ApplicationFactory.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Factory; use Psr\Container\ContainerInterface; -use Shlinkio\Shlink\Core\Options\AppOptions; +use Shlinkio\Shlink\Core\Config\Options\AppOptions; use Symfony\Component\Console\Application as CliApp; use Symfony\Component\Console\CommandLoader\ContainerCommandLoader; diff --git a/module/CLI/src/GeoLite/GeolocationDbUpdater.php b/module/CLI/src/GeoLite/GeolocationDbUpdater.php index ff42c930..85ae1d3a 100644 --- a/module/CLI/src/GeoLite/GeolocationDbUpdater.php +++ b/module/CLI/src/GeoLite/GeolocationDbUpdater.php @@ -9,7 +9,7 @@ use Closure; use GeoIp2\Database\Reader; use MaxMind\Db\Reader\Metadata; use Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException; -use Shlinkio\Shlink\Core\Options\TrackingOptions; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException; use Shlinkio\Shlink\IpGeolocation\Exception\MissingLicenseException; use Shlinkio\Shlink\IpGeolocation\Exception\WrongIpException; diff --git a/module/CLI/src/Input/ShortUrlDataInput.php b/module/CLI/src/Input/ShortUrlDataInput.php index 10c2da7c..2d3bf91e 100644 --- a/module/CLI/src/Input/ShortUrlDataInput.php +++ b/module/CLI/src/Input/ShortUrlDataInput.php @@ -4,7 +4,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\CLI\Input; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlEdition; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter; diff --git a/module/CLI/test/ApiKey/RoleResolverTest.php b/module/CLI/test/ApiKey/RoleResolverTest.php index cbd4f0fa..184780d7 100644 --- a/module/CLI/test/ApiKey/RoleResolverTest.php +++ b/module/CLI/test/ApiKey/RoleResolverTest.php @@ -10,6 +10,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\CLI\ApiKey\RoleResolver; use Shlinkio\Shlink\CLI\Exception\InvalidRoleConfigException; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition; @@ -24,7 +25,7 @@ class RoleResolverTest extends TestCase protected function setUp(): void { $this->domainService = $this->createMock(DomainServiceInterface::class); - $this->resolver = new RoleResolver($this->domainService, 'default.com'); + $this->resolver = new RoleResolver($this->domainService, new UrlShortenerOptions('default.com')); } #[Test, DataProvider('provideRoles')] diff --git a/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php b/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php index 0bc77aca..32240fc5 100644 --- a/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php +++ b/module/CLI/test/Command/Domain/DomainRedirectsCommandTest.php @@ -10,10 +10,10 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\CLI\Command\Domain\DomainRedirectsCommand; use Shlinkio\Shlink\Core\Config\NotFoundRedirects; +use Shlinkio\Shlink\Core\Config\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Model\DomainItem; -use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; use ShlinkioTest\Shlink\CLI\Util\CliTestUtils; use Symfony\Component\Console\Tester\CommandTester; diff --git a/module/CLI/test/Command/Domain/ListDomainsCommandTest.php b/module/CLI/test/Command/Domain/ListDomainsCommandTest.php index cfa09e18..2621f940 100644 --- a/module/CLI/test/Command/Domain/ListDomainsCommandTest.php +++ b/module/CLI/test/Command/Domain/ListDomainsCommandTest.php @@ -11,10 +11,10 @@ use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\CLI\Command\Domain\ListDomainsCommand; use Shlinkio\Shlink\CLI\Util\ExitCode; use Shlinkio\Shlink\Core\Config\NotFoundRedirects; +use Shlinkio\Shlink\Core\Config\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Model\DomainItem; -use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; use ShlinkioTest\Shlink\CLI\Util\CliTestUtils; use Symfony\Component\Console\Tester\CommandTester; diff --git a/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php b/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php index 33031c6b..19c57481 100644 --- a/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php +++ b/module/CLI/test/Command/ShortUrl/CreateShortUrlCommandTest.php @@ -12,8 +12,8 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\CLI\Command\ShortUrl\CreateShortUrlCommand; use Shlinkio\Shlink\CLI\Util\ExitCode; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; @@ -37,10 +37,7 @@ class CreateShortUrlCommandTest extends TestCase $command = new CreateShortUrlCommand( $this->urlShortener, $this->stringifier, - new UrlShortenerOptions( - domain: ['hostname' => 'example.com', 'schema' => ''], - defaultShortCodesLength: 5, - ), + new UrlShortenerOptions(defaultDomain: 'example.com', defaultShortCodesLength: 5), ); $this->commandTester = CliTestUtils::testerForCommand($command); } diff --git a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php index 6016da1c..176800ab 100644 --- a/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php +++ b/module/CLI/test/Command/ShortUrl/ListShortUrlsCommandTest.php @@ -37,7 +37,7 @@ class ListShortUrlsCommandTest extends TestCase { $this->shortUrlService = $this->createMock(ShortUrlListServiceInterface::class); $command = new ListShortUrlsCommand($this->shortUrlService, new ShortUrlDataTransformer( - new ShortUrlStringifier([]), + new ShortUrlStringifier(), )); $this->commandTester = CliTestUtils::testerForCommand($command); } diff --git a/module/CLI/test/Factory/ApplicationFactoryTest.php b/module/CLI/test/Factory/ApplicationFactoryTest.php index 83b0fc66..88b1280b 100644 --- a/module/CLI/test/Factory/ApplicationFactoryTest.php +++ b/module/CLI/test/Factory/ApplicationFactoryTest.php @@ -8,7 +8,7 @@ use Laminas\ServiceManager\ServiceManager; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\CLI\Factory\ApplicationFactory; -use Shlinkio\Shlink\Core\Options\AppOptions; +use Shlinkio\Shlink\Core\Config\Options\AppOptions; use ShlinkioTest\Shlink\CLI\Util\CliTestUtils; class ApplicationFactoryTest extends TestCase diff --git a/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php b/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php index cbb4af5c..3b0f452e 100644 --- a/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php +++ b/module/CLI/test/GeoLite/GeolocationDbUpdaterTest.php @@ -14,7 +14,7 @@ use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\CLI\Exception\GeolocationDbUpdateFailedException; use Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater; use Shlinkio\Shlink\CLI\GeoLite\GeolocationResult; -use Shlinkio\Shlink\Core\Options\TrackingOptions; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use Shlinkio\Shlink\IpGeolocation\Exception\DbUpdateException; use Shlinkio\Shlink\IpGeolocation\Exception\MissingLicenseException; use Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdaterInterface; diff --git a/module/Core/config/dependencies.config.php b/module/Core/config/dependencies.config.php index 8f8b609b..552d5e2a 100644 --- a/module/Core/config/dependencies.config.php +++ b/module/Core/config/dependencies.config.php @@ -8,8 +8,7 @@ use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory; use Laminas\ServiceManager\Factory\InvokableFactory; use Psr\EventDispatcher\EventDispatcherInterface; use Shlinkio\Shlink\Common\Doctrine\EntityRepositoryFactory; -use Shlinkio\Shlink\Config\Factory\ValinorConfigFactory; -use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; +use Shlinkio\Shlink\Core\Config\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier; use Shlinkio\Shlink\Importer\ImportedLinksProcessorInterface; use Shlinkio\Shlink\IpGeolocation\Resolver\IpLocationResolverInterface; @@ -24,15 +23,15 @@ return [ ErrorHandler\NotFoundRedirectHandler::class => ConfigAbstractFactory::class, ErrorHandler\NotFoundTemplateHandler::class => InvokableFactory::class, - Options\AppOptions::class => [ValinorConfigFactory::class, 'config.app_options'], - Options\DeleteShortUrlsOptions::class => [ValinorConfigFactory::class, 'config.delete_short_urls'], - Options\NotFoundRedirectOptions::class => [ValinorConfigFactory::class, 'config.not_found_redirects'], - Options\RedirectOptions::class => [ValinorConfigFactory::class, 'config.redirects'], - Options\UrlShortenerOptions::class => [ValinorConfigFactory::class, 'config.url_shortener'], - Options\TrackingOptions::class => [ValinorConfigFactory::class, 'config.tracking'], - Options\QrCodeOptions::class => [ValinorConfigFactory::class, 'config.qr_codes'], - Options\RabbitMqOptions::class => [ValinorConfigFactory::class, 'config.rabbitmq'], - Options\RobotsOptions::class => [ValinorConfigFactory::class, 'config.robots'], + Config\Options\AppOptions::class => [Config\Options\AppOptions::class, 'fromEnv'], + Config\Options\DeleteShortUrlsOptions::class => [Config\Options\DeleteShortUrlsOptions::class, 'fromEnv'], + Config\Options\NotFoundRedirectOptions::class => [Config\Options\NotFoundRedirectOptions::class, 'fromEnv'], + Config\Options\RedirectOptions::class => [Config\Options\RedirectOptions::class, 'fromEnv'], + Config\Options\UrlShortenerOptions::class => [Config\Options\UrlShortenerOptions::class, 'fromEnv'], + Config\Options\TrackingOptions::class => [Config\Options\TrackingOptions::class, 'fromEnv'], + Config\Options\QrCodeOptions::class => [Config\Options\QrCodeOptions::class, 'fromEnv'], + Config\Options\RabbitMqOptions::class => [Config\Options\RabbitMqOptions::class, 'fromEnv'], + Config\Options\RobotsOptions::class => [Config\Options\RobotsOptions::class, 'fromEnv'], RedirectRule\ShortUrlRedirectRuleService::class => ConfigAbstractFactory::class, RedirectRule\ShortUrlRedirectionResolver::class => ConfigAbstractFactory::class, @@ -101,7 +100,7 @@ return [ Crawling\CrawlingHelper::class => ConfigAbstractFactory::class, - Matomo\MatomoOptions::class => [ValinorConfigFactory::class, 'config.matomo'], + Matomo\MatomoOptions::class => [Matomo\MatomoOptions::class, 'fromEnv'], Matomo\MatomoTrackerBuilder::class => ConfigAbstractFactory::class, Matomo\MatomoVisitSender::class => ConfigAbstractFactory::class, ], @@ -137,9 +136,9 @@ return [ Visit\VisitsTracker::class => [ 'em', EventDispatcherInterface::class, - Options\TrackingOptions::class, + Config\Options\TrackingOptions::class, ], - Visit\RequestTracker::class => [Visit\VisitsTracker::class, Options\TrackingOptions::class], + Visit\RequestTracker::class => [Visit\VisitsTracker::class, Config\Options\TrackingOptions::class], Visit\VisitsDeleter::class => [Visit\Repository\VisitDeleterRepository::class], ShortUrl\ShortUrlService::class => [ 'em', @@ -149,7 +148,7 @@ return [ ], ShortUrl\ShortUrlListService::class => [ ShortUrl\Repository\ShortUrlListRepository::class, - Options\UrlShortenerOptions::class, + Config\Options\UrlShortenerOptions::class, ], Visit\Geolocation\VisitLocator::class => ['em', Visit\Repository\VisitIterationRepository::class], Visit\Geolocation\VisitToLocationHelper::class => [IpLocationResolverInterface::class], @@ -157,20 +156,20 @@ return [ Tag\TagService::class => ['em'], ShortUrl\DeleteShortUrlService::class => [ 'em', - Options\DeleteShortUrlsOptions::class, + Config\Options\DeleteShortUrlsOptions::class, ShortUrl\ShortUrlResolver::class, ShortUrl\Repository\ExpiredShortUrlsRepository::class, ], - ShortUrl\ShortUrlResolver::class => ['em', Options\UrlShortenerOptions::class], + ShortUrl\ShortUrlResolver::class => ['em', Config\Options\UrlShortenerOptions::class], ShortUrl\ShortUrlVisitsDeleter::class => [ Visit\Repository\VisitDeleterRepository::class, ShortUrl\ShortUrlResolver::class, ], - ShortUrl\Helper\ShortCodeUniquenessHelper::class => ['em', Options\UrlShortenerOptions::class], - Domain\DomainService::class => ['em', 'config.url_shortener.domain.hostname'], + ShortUrl\Helper\ShortCodeUniquenessHelper::class => ['em', Config\Options\UrlShortenerOptions::class], + Domain\DomainService::class => ['em', Config\Options\UrlShortenerOptions::class], Util\DoctrineBatchHelper::class => ['em'], - Util\RedirectResponseHelper::class => [Options\RedirectOptions::class], + Util\RedirectResponseHelper::class => [Config\Options\RedirectOptions::class], Config\NotFoundRedirectResolver::class => [Util\RedirectResponseHelper::class, 'Logger_Shlink'], @@ -188,19 +187,25 @@ return [ ShortUrl\ShortUrlResolver::class, ShortUrl\Helper\ShortUrlStringifier::class, 'Logger_Shlink', - Options\QrCodeOptions::class, + Config\Options\QrCodeOptions::class, ], - Action\RobotsAction::class => [Crawling\CrawlingHelper::class, Options\RobotsOptions::class], + Action\RobotsAction::class => [Crawling\CrawlingHelper::class, Config\Options\RobotsOptions::class], ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class => [ 'em', - Options\UrlShortenerOptions::class, + Config\Options\UrlShortenerOptions::class, Lock\LockFactory::class, ], - ShortUrl\Helper\ShortUrlStringifier::class => ['config.url_shortener.domain', 'config.router.base_path'], - ShortUrl\Helper\ShortUrlTitleResolutionHelper::class => ['httpClient', Options\UrlShortenerOptions::class], + ShortUrl\Helper\ShortUrlStringifier::class => [ + Config\Options\UrlShortenerOptions::class, + 'config.router.base_path', + ], + ShortUrl\Helper\ShortUrlTitleResolutionHelper::class => [ + 'httpClient', + Config\Options\UrlShortenerOptions::class, + ], ShortUrl\Helper\ShortUrlRedirectionBuilder::class => [ - Options\TrackingOptions::class, + Config\Options\TrackingOptions::class, RedirectRule\ShortUrlRedirectionResolver::class, ], ShortUrl\Transformer\ShortUrlDataTransformer::class => [ShortUrl\Helper\ShortUrlStringifier::class], @@ -209,9 +214,9 @@ return [ Visit\RequestTracker::class, ShortUrl\Helper\ShortUrlRedirectionBuilder::class, Util\RedirectResponseHelper::class, - Options\UrlShortenerOptions::class, + Config\Options\UrlShortenerOptions::class, ], - ShortUrl\Middleware\TrimTrailingSlashMiddleware::class => [Options\UrlShortenerOptions::class], + ShortUrl\Middleware\TrimTrailingSlashMiddleware::class => [Config\Options\UrlShortenerOptions::class], EventDispatcher\PublishingUpdatesGenerator::class => [ShortUrl\Transformer\ShortUrlDataTransformer::class], diff --git a/module/Core/config/event_dispatcher.config.php b/module/Core/config/event_dispatcher.config.php index f401f255..2491d606 100644 --- a/module/Core/config/event_dispatcher.config.php +++ b/module/Core/config/event_dispatcher.config.php @@ -129,14 +129,14 @@ return (static function (): array { EventDispatcher\PublishingUpdatesGenerator::class, 'em', 'Logger_Shlink', - Options\RabbitMqOptions::class, + Config\Options\RabbitMqOptions::class, ], EventDispatcher\RabbitMq\NotifyNewShortUrlToRabbitMq::class => [ RabbitMqPublishingHelper::class, EventDispatcher\PublishingUpdatesGenerator::class, 'em', 'Logger_Shlink', - Options\RabbitMqOptions::class, + Config\Options\RabbitMqOptions::class, ], EventDispatcher\RedisPubSub\NotifyVisitToRedis::class => [ RedisPublishingHelper::class, @@ -167,7 +167,7 @@ return (static function (): array { ], EventDispatcher\Helper\EnabledListenerChecker::class => [ - Options\RabbitMqOptions::class, + Config\Options\RabbitMqOptions::class, 'config.redis.pub_sub_enabled', MercureOptions::class, GeoLite2Options::class, diff --git a/module/Core/src/Action/Model/QrCodeParams.php b/module/Core/src/Action/Model/QrCodeParams.php index 2a3907cc..46d90056 100644 --- a/module/Core/src/Action/Model/QrCodeParams.php +++ b/module/Core/src/Action/Model/QrCodeParams.php @@ -12,7 +12,7 @@ use Endroid\QrCode\Writer\PngWriter; use Endroid\QrCode\Writer\SvgWriter; use Endroid\QrCode\Writer\WriterInterface; use Psr\Http\Message\ServerRequestInterface; -use Shlinkio\Shlink\Core\Options\QrCodeOptions; +use Shlinkio\Shlink\Core\Config\Options\QrCodeOptions; use function ctype_xdigit; use function hexdec; diff --git a/module/Core/src/Action/QrCodeAction.php b/module/Core/src/Action/QrCodeAction.php index 4da8bb32..607fab50 100644 --- a/module/Core/src/Action/QrCodeAction.php +++ b/module/Core/src/Action/QrCodeAction.php @@ -13,8 +13,8 @@ use Psr\Http\Server\RequestHandlerInterface; use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Common\Response\QrCodeResponse; use Shlinkio\Shlink\Core\Action\Model\QrCodeParams; +use Shlinkio\Shlink\Core\Config\Options\QrCodeOptions; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; -use Shlinkio\Shlink\Core\Options\QrCodeOptions; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface; diff --git a/module/Core/src/Action/RobotsAction.php b/module/Core/src/Action/RobotsAction.php index 29c2c8d2..21b7d21e 100644 --- a/module/Core/src/Action/RobotsAction.php +++ b/module/Core/src/Action/RobotsAction.php @@ -9,8 +9,8 @@ use GuzzleHttp\Psr7\Response; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; +use Shlinkio\Shlink\Core\Config\Options\RobotsOptions; use Shlinkio\Shlink\Core\Crawling\CrawlingHelperInterface; -use Shlinkio\Shlink\Core\Options\RobotsOptions; use function sprintf; diff --git a/module/Core/src/Config/EnvVars.php b/module/Core/src/Config/EnvVars.php index 2fe5dfd9..6cdf6297 100644 --- a/module/Core/src/Config/EnvVars.php +++ b/module/Core/src/Config/EnvVars.php @@ -27,6 +27,7 @@ use const Shlinkio\Shlink\DEFAULT_SHORT_CODES_LENGTH; enum EnvVars: string { + case APP_ENV = 'APP_ENV'; case DELETE_SHORT_URL_THRESHOLD = 'DELETE_SHORT_URL_THRESHOLD'; case DB_DRIVER = 'DB_DRIVER'; case DB_NAME = 'DB_NAME'; @@ -117,6 +118,7 @@ enum EnvVars: string private function defaultValue(): string|int|bool|null { return match ($this) { + self::APP_ENV => 'prod', self::MEMORY_LIMIT => '512M', self::TIMEZONE => date_default_timezone_get(), @@ -174,4 +176,19 @@ enum EnvVars: string { return $this->loadFromEnv() !== null; } + + public static function isProdEnv(): bool + { + return self::APP_ENV->loadFromEnv() === 'prod'; + } + + public static function isDevEnv(): bool + { + return self::APP_ENV->loadFromEnv() === 'dev'; + } + + public static function isTestEnv(): bool + { + return self::APP_ENV->loadFromEnv() === 'test'; + } } diff --git a/module/Core/src/Config/Options/AppOptions.php b/module/Core/src/Config/Options/AppOptions.php new file mode 100644 index 00000000..71e3f507 --- /dev/null +++ b/module/Core/src/Config/Options/AppOptions.php @@ -0,0 +1,27 @@ +name, $this->version); + } +} diff --git a/module/Core/src/Config/Options/DeleteShortUrlsOptions.php b/module/Core/src/Config/Options/DeleteShortUrlsOptions.php new file mode 100644 index 00000000..97916d36 --- /dev/null +++ b/module/Core/src/Config/Options/DeleteShortUrlsOptions.php @@ -0,0 +1,28 @@ +loadFromEnv(); + + return new self( + visitsThreshold: (int) ($threshold ?? DEFAULT_DELETE_SHORT_URL_THRESHOLD), + checkVisitsThreshold: $threshold !== null, + ); + } +} diff --git a/module/Core/src/Options/NotFoundRedirectOptions.php b/module/Core/src/Config/Options/NotFoundRedirectOptions.php similarity index 54% rename from module/Core/src/Options/NotFoundRedirectOptions.php rename to module/Core/src/Config/Options/NotFoundRedirectOptions.php index fe99ac7e..e6ef6a24 100644 --- a/module/Core/src/Options/NotFoundRedirectOptions.php +++ b/module/Core/src/Config/Options/NotFoundRedirectOptions.php @@ -2,19 +2,29 @@ declare(strict_types=1); -namespace Shlinkio\Shlink\Core\Options; +namespace Shlinkio\Shlink\Core\Config\Options; +use Shlinkio\Shlink\Core\Config\EnvVars; use Shlinkio\Shlink\Core\Config\NotFoundRedirectConfigInterface; -final class NotFoundRedirectOptions implements NotFoundRedirectConfigInterface +final readonly class NotFoundRedirectOptions implements NotFoundRedirectConfigInterface { public function __construct( - public readonly ?string $invalidShortUrl = null, - public readonly ?string $regular404 = null, - public readonly ?string $baseUrl = null, + public ?string $invalidShortUrl = null, + public ?string $regular404 = null, + public ?string $baseUrl = null, ) { } + public static function fromEnv(): self + { + return new self( + invalidShortUrl: EnvVars::DEFAULT_INVALID_SHORT_URL_REDIRECT->loadFromEnv(), + regular404: EnvVars::DEFAULT_REGULAR_404_REDIRECT->loadFromEnv(), + baseUrl: EnvVars::DEFAULT_BASE_URL_REDIRECT->loadFromEnv(), + ); + } + public function invalidShortUrlRedirect(): ?string { return $this->invalidShortUrl; diff --git a/module/Core/src/Options/QrCodeOptions.php b/module/Core/src/Config/Options/QrCodeOptions.php similarity index 54% rename from module/Core/src/Options/QrCodeOptions.php rename to module/Core/src/Config/Options/QrCodeOptions.php index da130d17..4d85e6cc 100644 --- a/module/Core/src/Options/QrCodeOptions.php +++ b/module/Core/src/Config/Options/QrCodeOptions.php @@ -2,7 +2,9 @@ declare(strict_types=1); -namespace Shlinkio\Shlink\Core\Options; +namespace Shlinkio\Shlink\Core\Config\Options; + +use Shlinkio\Shlink\Core\Config\EnvVars; use const Shlinkio\Shlink\DEFAULT_QR_CODE_BG_COLOR; use const Shlinkio\Shlink\DEFAULT_QR_CODE_COLOR; @@ -13,7 +15,7 @@ use const Shlinkio\Shlink\DEFAULT_QR_CODE_MARGIN; use const Shlinkio\Shlink\DEFAULT_QR_CODE_ROUND_BLOCK_SIZE; use const Shlinkio\Shlink\DEFAULT_QR_CODE_SIZE; -readonly final class QrCodeOptions +final readonly class QrCodeOptions { public function __construct( public int $size = DEFAULT_QR_CODE_SIZE, @@ -27,4 +29,19 @@ readonly final class QrCodeOptions public ?string $logoUrl = null, ) { } + + public static function fromEnv(): self + { + return new self( + size: (int) EnvVars::DEFAULT_QR_CODE_SIZE->loadFromEnv(), + margin: (int) EnvVars::DEFAULT_QR_CODE_MARGIN->loadFromEnv(), + format: EnvVars::DEFAULT_QR_CODE_FORMAT->loadFromEnv(), + errorCorrection: EnvVars::DEFAULT_QR_CODE_ERROR_CORRECTION->loadFromEnv(), + roundBlockSize: (bool) EnvVars::DEFAULT_QR_CODE_ROUND_BLOCK_SIZE->loadFromEnv(), + enabledForDisabledShortUrls: (bool) EnvVars::QR_CODE_FOR_DISABLED_SHORT_URLS->loadFromEnv(), + color: EnvVars::DEFAULT_QR_CODE_COLOR->loadFromEnv(), + bgColor: EnvVars::DEFAULT_QR_CODE_BG_COLOR->loadFromEnv(), + logoUrl: EnvVars::DEFAULT_QR_CODE_LOGO_URL->loadFromEnv(), + ); + } } diff --git a/module/Core/src/Config/Options/RabbitMqOptions.php b/module/Core/src/Config/Options/RabbitMqOptions.php new file mode 100644 index 00000000..4bc86e34 --- /dev/null +++ b/module/Core/src/Config/Options/RabbitMqOptions.php @@ -0,0 +1,19 @@ +loadFromEnv()); + } +} diff --git a/module/Core/src/Options/RedirectOptions.php b/module/Core/src/Config/Options/RedirectOptions.php similarity index 59% rename from module/Core/src/Options/RedirectOptions.php rename to module/Core/src/Config/Options/RedirectOptions.php index dd9f0a6d..75faf097 100644 --- a/module/Core/src/Options/RedirectOptions.php +++ b/module/Core/src/Config/Options/RedirectOptions.php @@ -2,18 +2,19 @@ declare(strict_types=1); -namespace Shlinkio\Shlink\Core\Options; +namespace Shlinkio\Shlink\Core\Config\Options; use Fig\Http\Message\StatusCodeInterface; +use Shlinkio\Shlink\Core\Config\EnvVars; use Shlinkio\Shlink\Core\Util\RedirectStatus; use const Shlinkio\Shlink\DEFAULT_REDIRECT_CACHE_LIFETIME; use const Shlinkio\Shlink\DEFAULT_REDIRECT_STATUS_CODE; -final class RedirectOptions +final readonly class RedirectOptions { - public readonly RedirectStatus $redirectStatusCode; - public readonly int $redirectCacheLifetime; + public RedirectStatus $redirectStatusCode; + public int $redirectCacheLifetime; public function __construct( int $redirectStatusCode = StatusCodeInterface::STATUS_FOUND, @@ -24,4 +25,12 @@ final class RedirectOptions ? $redirectCacheLifetime : DEFAULT_REDIRECT_CACHE_LIFETIME; } + + public static function fromEnv(): self + { + return new self( + redirectStatusCode: (int) EnvVars::REDIRECT_STATUS_CODE->loadFromEnv(), + redirectCacheLifetime: (int) EnvVars::REDIRECT_CACHE_LIFETIME->loadFromEnv(), + ); + } } diff --git a/module/Core/src/Config/Options/RobotsOptions.php b/module/Core/src/Config/Options/RobotsOptions.php new file mode 100644 index 00000000..6a8c364c --- /dev/null +++ b/module/Core/src/Config/Options/RobotsOptions.php @@ -0,0 +1,33 @@ +loadFromEnv(), + userAgents: splitByComma(EnvVars::ROBOTS_USER_AGENTS->loadFromEnv()), + ); + } + + public function hasUserAgents(): bool + { + return count($this->userAgents) > 0; + } +} diff --git a/module/Core/src/Config/Options/TrackingOptions.php b/module/Core/src/Config/Options/TrackingOptions.php new file mode 100644 index 00000000..eddfba34 --- /dev/null +++ b/module/Core/src/Config/Options/TrackingOptions.php @@ -0,0 +1,62 @@ +loadFromEnv(), + trackOrphanVisits: (bool) EnvVars::TRACK_ORPHAN_VISITS->loadFromEnv(), + disableTrackParam: EnvVars::DISABLE_TRACK_PARAM->loadFromEnv(), + disableTracking: (bool) EnvVars::DISABLE_TRACKING->loadFromEnv(), + disableIpTracking: (bool) EnvVars::DISABLE_IP_TRACKING->loadFromEnv(), + disableReferrerTracking: (bool) EnvVars::DISABLE_REFERRER_TRACKING->loadFromEnv(), + disableUaTracking: (bool) EnvVars::DISABLE_UA_TRACKING->loadFromEnv(), + disableTrackingFrom: splitByComma(EnvVars::DISABLE_TRACKING_FROM->loadFromEnv()), + ); + } + + public function hasDisableTrackingFrom(): bool + { + return ! empty($this->disableTrackingFrom); + } + + public function queryHasDisableTrackParam(array $query): bool + { + return $this->disableTrackParam !== null && array_key_exists($this->disableTrackParam, $query); + } +} diff --git a/module/Core/src/Config/Options/UrlShortenerOptions.php b/module/Core/src/Config/Options/UrlShortenerOptions.php new file mode 100644 index 00000000..98b450b4 --- /dev/null +++ b/module/Core/src/Config/Options/UrlShortenerOptions.php @@ -0,0 +1,56 @@ +loadFromEnv(), + MIN_SHORT_CODES_LENGTH, + ); + $mode = EnvVars::SHORT_URL_MODE->loadFromEnv(); + + return new self( + defaultDomain: EnvVars::DEFAULT_DOMAIN->loadFromEnv(), + schema: ((bool) EnvVars::IS_HTTPS_ENABLED->loadFromEnv()) ? 'https' : 'http', + defaultShortCodesLength: $shortCodesLength, + autoResolveTitles: (bool) EnvVars::AUTO_RESOLVE_TITLES->loadFromEnv(), + appendExtraPath: (bool) EnvVars::REDIRECT_APPEND_EXTRA_PATH->loadFromEnv(), + multiSegmentSlugsEnabled: (bool) EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->loadFromEnv(), + trailingSlashEnabled: (bool) EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(), + mode: ShortUrlMode::tryFrom($mode) ?? ShortUrlMode::STRICT, + ); + } + + public function isLooseMode(): bool + { + return $this->mode === ShortUrlMode::LOOSE; + } +} diff --git a/module/Core/src/Config/PostProcessor/MultiSegmentSlugProcessor.php b/module/Core/src/Config/PostProcessor/MultiSegmentSlugProcessor.php index 585f78b6..c4078890 100644 --- a/module/Core/src/Config/PostProcessor/MultiSegmentSlugProcessor.php +++ b/module/Core/src/Config/PostProcessor/MultiSegmentSlugProcessor.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\Config\PostProcessor; +use Shlinkio\Shlink\Core\Config\EnvVars; + use function array_map; use function str_replace; @@ -14,7 +16,7 @@ class MultiSegmentSlugProcessor public function __invoke(array $config): array { - $multiSegmentEnabled = $config['url_shortener']['multi_segment_slugs_enabled'] ?? false; + $multiSegmentEnabled = (bool) EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->loadFromEnv(); if (! $multiSegmentEnabled) { return $config; } diff --git a/module/Core/src/Domain/DomainService.php b/module/Core/src/Domain/DomainService.php index 93adbf5f..e514af55 100644 --- a/module/Core/src/Domain/DomainService.php +++ b/module/Core/src/Domain/DomainService.php @@ -7,6 +7,7 @@ namespace Shlinkio\Shlink\Core\Domain; use Doctrine\ORM\EntityManagerInterface; use Shlinkio\Shlink\Core\Config\EmptyNotFoundRedirectConfig; use Shlinkio\Shlink\Core\Config\NotFoundRedirects; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Model\DomainItem; use Shlinkio\Shlink\Core\Domain\Repository\DomainRepositoryInterface; @@ -16,9 +17,9 @@ use Shlinkio\Shlink\Rest\Entity\ApiKey; use function array_map; -class DomainService implements DomainServiceInterface +readonly class DomainService implements DomainServiceInterface { - public function __construct(private readonly EntityManagerInterface $em, private readonly string $defaultDomain) + public function __construct(private EntityManagerInterface $em, private UrlShortenerOptions $urlShortenerOptions) { } @@ -35,7 +36,10 @@ class DomainService implements DomainServiceInterface } return [ - DomainItem::forDefaultDomain($this->defaultDomain, $default ?? new EmptyNotFoundRedirectConfig()), + DomainItem::forDefaultDomain( + $this->urlShortenerOptions->defaultDomain, + $default ?? new EmptyNotFoundRedirectConfig(), + ), ...$mappedDomains, ]; } @@ -52,7 +56,7 @@ class DomainService implements DomainServiceInterface $restOfDomains = []; foreach ($allDomains as $domain) { - if ($domain->authority === $this->defaultDomain) { + if ($domain->authority === $this->urlShortenerOptions->defaultDomain) { $defaultDomain = $domain; } else { $restOfDomains[] = $domain; diff --git a/module/Core/src/ErrorHandler/NotFoundRedirectHandler.php b/module/Core/src/ErrorHandler/NotFoundRedirectHandler.php index 4138a72e..4e7360d5 100644 --- a/module/Core/src/ErrorHandler/NotFoundRedirectHandler.php +++ b/module/Core/src/ErrorHandler/NotFoundRedirectHandler.php @@ -9,15 +9,15 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\UriInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use Shlinkio\Shlink\Core\Config; use Shlinkio\Shlink\Core\Config\NotFoundRedirectResolverInterface; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; -use Shlinkio\Shlink\Core\Options; -class NotFoundRedirectHandler implements MiddlewareInterface +readonly class NotFoundRedirectHandler implements MiddlewareInterface { public function __construct( - private Options\NotFoundRedirectOptions $redirectOptions, + private Config\Options\NotFoundRedirectOptions $redirectOptions, private NotFoundRedirectResolverInterface $redirectResolver, private DomainServiceInterface $domainService, ) { diff --git a/module/Core/src/EventDispatcher/Helper/EnabledListenerChecker.php b/module/Core/src/EventDispatcher/Helper/EnabledListenerChecker.php index ad4c8070..c348cbbd 100644 --- a/module/Core/src/EventDispatcher/Helper/EnabledListenerChecker.php +++ b/module/Core/src/EventDispatcher/Helper/EnabledListenerChecker.php @@ -5,9 +5,9 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\EventDispatcher\Helper; use Shlinkio\Shlink\Common\Mercure\MercureOptions; +use Shlinkio\Shlink\Core\Config\Options\RabbitMqOptions; use Shlinkio\Shlink\Core\EventDispatcher; use Shlinkio\Shlink\Core\Matomo\MatomoOptions; -use Shlinkio\Shlink\Core\Options\RabbitMqOptions; use Shlinkio\Shlink\EventDispatcher\Listener\EnabledListenerCheckerInterface; use Shlinkio\Shlink\IpGeolocation\GeoLite2\GeoLite2Options; diff --git a/module/Core/src/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMq.php b/module/Core/src/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMq.php index daa7cafb..b8c18fb6 100644 --- a/module/Core/src/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMq.php +++ b/module/Core/src/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMq.php @@ -7,10 +7,10 @@ namespace Shlinkio\Shlink\Core\EventDispatcher\RabbitMq; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface; +use Shlinkio\Shlink\Core\Config\Options\RabbitMqOptions; use Shlinkio\Shlink\Core\EventDispatcher\Async\AbstractNotifyNewShortUrlListener; use Shlinkio\Shlink\Core\EventDispatcher\Async\RemoteSystem; use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface; -use Shlinkio\Shlink\Core\Options\RabbitMqOptions; class NotifyNewShortUrlToRabbitMq extends AbstractNotifyNewShortUrlListener { diff --git a/module/Core/src/EventDispatcher/RabbitMq/NotifyVisitToRabbitMq.php b/module/Core/src/EventDispatcher/RabbitMq/NotifyVisitToRabbitMq.php index ddc4221c..bb55f169 100644 --- a/module/Core/src/EventDispatcher/RabbitMq/NotifyVisitToRabbitMq.php +++ b/module/Core/src/EventDispatcher/RabbitMq/NotifyVisitToRabbitMq.php @@ -7,10 +7,10 @@ namespace Shlinkio\Shlink\Core\EventDispatcher\RabbitMq; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface; +use Shlinkio\Shlink\Core\Config\Options\RabbitMqOptions; use Shlinkio\Shlink\Core\EventDispatcher\Async\AbstractNotifyVisitListener; use Shlinkio\Shlink\Core\EventDispatcher\Async\RemoteSystem; use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface; -use Shlinkio\Shlink\Core\Options\RabbitMqOptions; class NotifyVisitToRabbitMq extends AbstractNotifyVisitListener { diff --git a/module/Core/src/Matomo/MatomoOptions.php b/module/Core/src/Matomo/MatomoOptions.php index 23599321..af0ace92 100644 --- a/module/Core/src/Matomo/MatomoOptions.php +++ b/module/Core/src/Matomo/MatomoOptions.php @@ -4,17 +4,31 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\Matomo; -class MatomoOptions +use Shlinkio\Shlink\Core\Config\EnvVars; + +final readonly class MatomoOptions { + /** + * @param numeric-string|int|null $siteId + */ public function __construct( - public readonly bool $enabled = false, - public readonly ?string $baseUrl = null, - /** @var numeric-string|int|null */ - private readonly string|int|null $siteId = null, - public readonly ?string $apiToken = null, + public bool $enabled = false, + public ?string $baseUrl = null, + private string|int|null $siteId = null, + public ?string $apiToken = null, ) { } + public static function fromEnv(): self + { + return new self( + enabled: (bool) EnvVars::MATOMO_ENABLED->loadFromEnv(), + baseUrl: EnvVars::MATOMO_BASE_URL->loadFromEnv(), + siteId: EnvVars::MATOMO_SITE_ID->loadFromEnv(), + apiToken: EnvVars::MATOMO_API_TOKEN->loadFromEnv(), + ); + } + public function siteId(): ?int { if ($this->siteId === null) { diff --git a/module/Core/src/Options/AppOptions.php b/module/Core/src/Options/AppOptions.php deleted file mode 100644 index ec545352..00000000 --- a/module/Core/src/Options/AppOptions.php +++ /dev/null @@ -1,19 +0,0 @@ -name, $this->version); - } -} diff --git a/module/Core/src/Options/DeleteShortUrlsOptions.php b/module/Core/src/Options/DeleteShortUrlsOptions.php deleted file mode 100644 index a645181b..00000000 --- a/module/Core/src/Options/DeleteShortUrlsOptions.php +++ /dev/null @@ -1,16 +0,0 @@ -userAgents) > 0; - } -} diff --git a/module/Core/src/Options/TrackingOptions.php b/module/Core/src/Options/TrackingOptions.php deleted file mode 100644 index d4272374..00000000 --- a/module/Core/src/Options/TrackingOptions.php +++ /dev/null @@ -1,33 +0,0 @@ -disableTrackingFrom); - } - - public function queryHasDisableTrackParam(array $query): bool - { - return $this->disableTrackParam !== null && array_key_exists($this->disableTrackParam, $query); - } -} diff --git a/module/Core/src/Options/UrlShortenerOptions.php b/module/Core/src/Options/UrlShortenerOptions.php deleted file mode 100644 index 03091d75..00000000 --- a/module/Core/src/Options/UrlShortenerOptions.php +++ /dev/null @@ -1,36 +0,0 @@ - null, 'hostname' => null], - public readonly int $defaultShortCodesLength = DEFAULT_SHORT_CODES_LENGTH, - public readonly bool $autoResolveTitles = false, - public readonly bool $appendExtraPath = false, - public readonly bool $multiSegmentSlugsEnabled = false, - public readonly bool $trailingSlashEnabled = false, - public readonly ShortUrlMode $mode = ShortUrlMode::STRICT, - ) { - } - - public function isLooseMode(): bool - { - return $this->mode === ShortUrlMode::LOOSE; - } - - public function defaultDomain(): string - { - return $this->domain['hostname'] ?? ''; - } -} diff --git a/module/Core/src/ShortUrl/DeleteShortUrlService.php b/module/Core/src/ShortUrl/DeleteShortUrlService.php index b65381aa..aeb08c47 100644 --- a/module/Core/src/ShortUrl/DeleteShortUrlService.php +++ b/module/Core/src/ShortUrl/DeleteShortUrlService.php @@ -5,8 +5,8 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\ShortUrl; use Doctrine\ORM\EntityManagerInterface; +use Shlinkio\Shlink\Core\Config\Options\DeleteShortUrlsOptions; use Shlinkio\Shlink\Core\Exception; -use Shlinkio\Shlink\Core\Options\DeleteShortUrlsOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ExpiredShortUrlsConditions; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; diff --git a/module/Core/src/ShortUrl/Helper/ShortCodeUniquenessHelper.php b/module/Core/src/ShortUrl/Helper/ShortCodeUniquenessHelper.php index b428019e..7f863f6c 100644 --- a/module/Core/src/ShortUrl/Helper/ShortCodeUniquenessHelper.php +++ b/module/Core/src/ShortUrl/Helper/ShortCodeUniquenessHelper.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\ShortUrl\Helper; use Doctrine\ORM\EntityManagerInterface; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlRepository; diff --git a/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilder.php b/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilder.php index 4d801c6f..375d8837 100644 --- a/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilder.php +++ b/module/Core/src/ShortUrl/Helper/ShortUrlRedirectionBuilder.php @@ -8,7 +8,7 @@ use GuzzleHttp\Psr7\Query; use GuzzleHttp\Psr7\Uri; use Laminas\Stdlib\ArrayUtils; use Psr\Http\Message\ServerRequestInterface; -use Shlinkio\Shlink\Core\Options\TrackingOptions; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use Shlinkio\Shlink\Core\RedirectRule\ShortUrlRedirectionResolverInterface; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; diff --git a/module/Core/src/ShortUrl/Helper/ShortUrlStringifier.php b/module/Core/src/ShortUrl/Helper/ShortUrlStringifier.php index 886a4d25..6659bc0c 100644 --- a/module/Core/src/ShortUrl/Helper/ShortUrlStringifier.php +++ b/module/Core/src/ShortUrl/Helper/ShortUrlStringifier.php @@ -5,22 +5,22 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\ShortUrl\Helper; use Laminas\Diactoros\Uri; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use function sprintf; -class ShortUrlStringifier implements ShortUrlStringifierInterface +readonly class ShortUrlStringifier implements ShortUrlStringifierInterface { - /** - * @param array{schema?: string, hostname?: string} $domainConfig - */ - public function __construct(private readonly array $domainConfig, private readonly string $basePath = '') - { + public function __construct( + private UrlShortenerOptions $urlShortenerOptions = new UrlShortenerOptions(), + private string $basePath = '', + ) { } public function stringify(ShortUrl $shortUrl): string { - $uriWithoutShortCode = (new Uri())->withScheme($this->domainConfig['schema'] ?? 'http') + $uriWithoutShortCode = (new Uri())->withScheme($this->urlShortenerOptions->schema) ->withHost($this->resolveDomain($shortUrl)) ->withPath($this->basePath) ->__toString(); @@ -31,6 +31,6 @@ class ShortUrlStringifier implements ShortUrlStringifierInterface private function resolveDomain(ShortUrl $shortUrl): string { - return $shortUrl->getDomain()?->authority ?? $this->domainConfig['hostname'] ?? ''; + return $shortUrl->getDomain()?->authority ?? $this->urlShortenerOptions->defaultDomain; } } diff --git a/module/Core/src/ShortUrl/Helper/ShortUrlTitleResolutionHelper.php b/module/Core/src/ShortUrl/Helper/ShortUrlTitleResolutionHelper.php index 3f9b6225..0950e042 100644 --- a/module/Core/src/ShortUrl/Helper/ShortUrlTitleResolutionHelper.php +++ b/module/Core/src/ShortUrl/Helper/ShortUrlTitleResolutionHelper.php @@ -8,7 +8,7 @@ use Fig\Http\Message\RequestMethodInterface; use GuzzleHttp\ClientInterface; use GuzzleHttp\RequestOptions; use Psr\Http\Message\ResponseInterface; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Throwable; use function html_entity_decode; diff --git a/module/Core/src/ShortUrl/Middleware/ExtraPathRedirectMiddleware.php b/module/Core/src/ShortUrl/Middleware/ExtraPathRedirectMiddleware.php index 7780f91b..b164ffd6 100644 --- a/module/Core/src/ShortUrl/Middleware/ExtraPathRedirectMiddleware.php +++ b/module/Core/src/ShortUrl/Middleware/ExtraPathRedirectMiddleware.php @@ -9,9 +9,9 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\UriInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlRedirectionBuilderInterface; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface; diff --git a/module/Core/src/ShortUrl/Middleware/TrimTrailingSlashMiddleware.php b/module/Core/src/ShortUrl/Middleware/TrimTrailingSlashMiddleware.php index d3823b27..0b70c3ae 100644 --- a/module/Core/src/ShortUrl/Middleware/TrimTrailingSlashMiddleware.php +++ b/module/Core/src/ShortUrl/Middleware/TrimTrailingSlashMiddleware.php @@ -8,7 +8,7 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use function rtrim; diff --git a/module/Core/src/ShortUrl/Model/ShortUrlCreation.php b/module/Core/src/ShortUrl/Model/ShortUrlCreation.php index f5336075..c9c85e1b 100644 --- a/module/Core/src/ShortUrl/Model/ShortUrlCreation.php +++ b/module/Core/src/ShortUrl/Model/ShortUrlCreation.php @@ -5,8 +5,8 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\ShortUrl\Model; use Cake\Chronos\Chronos; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Exception\ValidationException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Helper\TitleResolutionModelInterface; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter; use Shlinkio\Shlink\Rest\Entity\ApiKey; diff --git a/module/Core/src/ShortUrl/Model/Validation/CustomSlugFilter.php b/module/Core/src/ShortUrl/Model/Validation/CustomSlugFilter.php index 2512fc44..ba4e3959 100644 --- a/module/Core/src/ShortUrl/Model/Validation/CustomSlugFilter.php +++ b/module/Core/src/ShortUrl/Model/Validation/CustomSlugFilter.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\ShortUrl\Model\Validation; use Laminas\Filter\FilterInterface; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use function is_string; use function str_replace; diff --git a/module/Core/src/ShortUrl/Model/Validation/CustomSlugValidator.php b/module/Core/src/ShortUrl/Model/Validation/CustomSlugValidator.php index 24afc72e..2bc417b4 100644 --- a/module/Core/src/ShortUrl/Model/Validation/CustomSlugValidator.php +++ b/module/Core/src/ShortUrl/Model/Validation/CustomSlugValidator.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\ShortUrl\Model\Validation; use Laminas\Validator\AbstractValidator; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use function is_string; use function strpbrk; diff --git a/module/Core/src/ShortUrl/Model/Validation/ShortUrlInputFilter.php b/module/Core/src/ShortUrl/Model/Validation/ShortUrlInputFilter.php index f4a35969..3cd7744a 100644 --- a/module/Core/src/ShortUrl/Model/Validation/ShortUrlInputFilter.php +++ b/module/Core/src/ShortUrl/Model/Validation/ShortUrlInputFilter.php @@ -10,7 +10,7 @@ use Laminas\InputFilter\InputFilter; use Laminas\Validator; use Shlinkio\Shlink\Common\Validation\HostAndPortValidator; use Shlinkio\Shlink\Common\Validation\InputFactory; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Rest\Entity\ApiKey; use function is_string; diff --git a/module/Core/src/ShortUrl/Resolver/PersistenceShortUrlRelationResolver.php b/module/Core/src/ShortUrl/Resolver/PersistenceShortUrlRelationResolver.php index 3aa6c887..94fb314a 100644 --- a/module/Core/src/ShortUrl/Resolver/PersistenceShortUrlRelationResolver.php +++ b/module/Core/src/ShortUrl/Resolver/PersistenceShortUrlRelationResolver.php @@ -8,8 +8,8 @@ use Doctrine\Common\Collections; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Events; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Domain\Entity\Domain; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Tag\Entity\Tag; use Symfony\Component\Lock\Lock; use Symfony\Component\Lock\LockFactory; @@ -40,7 +40,7 @@ class PersistenceShortUrlRelationResolver implements ShortUrlRelationResolverInt public function resolveDomain(?string $domain): ?Domain { - if ($domain === null || $domain === $this->options->defaultDomain()) { + if ($domain === null || $domain === $this->options->defaultDomain) { return null; } diff --git a/module/Core/src/ShortUrl/ShortUrlListService.php b/module/Core/src/ShortUrl/ShortUrlListService.php index f8441454..853a40b9 100644 --- a/module/Core/src/ShortUrl/ShortUrlListService.php +++ b/module/Core/src/ShortUrl/ShortUrlListService.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\ShortUrl; use Shlinkio\Shlink\Common\Paginator\Paginator; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\Paginator\Adapter\ShortUrlRepositoryAdapter; use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlListRepositoryInterface; @@ -24,7 +24,7 @@ readonly class ShortUrlListService implements ShortUrlListServiceInterface */ public function listShortUrls(ShortUrlsParams $params, ?ApiKey $apiKey = null): Paginator { - $defaultDomain = $this->urlShortenerOptions->defaultDomain(); + $defaultDomain = $this->urlShortenerOptions->defaultDomain; $paginator = new Paginator(new ShortUrlRepositoryAdapter($this->repo, $params, $apiKey, $defaultDomain)); $paginator->setMaxPerPage($params->itemsPerPage) ->setCurrentPage($params->page); diff --git a/module/Core/src/ShortUrl/ShortUrlResolver.php b/module/Core/src/ShortUrl/ShortUrlResolver.php index 42d274c0..14727ff5 100644 --- a/module/Core/src/ShortUrl/ShortUrlResolver.php +++ b/module/Core/src/ShortUrl/ShortUrlResolver.php @@ -5,8 +5,8 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\ShortUrl; use Doctrine\ORM\EntityManagerInterface; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlRepository; diff --git a/module/Core/src/Util/RedirectResponseHelper.php b/module/Core/src/Util/RedirectResponseHelper.php index 01e581a7..edb04b8e 100644 --- a/module/Core/src/Util/RedirectResponseHelper.php +++ b/module/Core/src/Util/RedirectResponseHelper.php @@ -6,7 +6,7 @@ namespace Shlinkio\Shlink\Core\Util; use Laminas\Diactoros\Response\RedirectResponse; use Psr\Http\Message\ResponseInterface; -use Shlinkio\Shlink\Core\Options\RedirectOptions; +use Shlinkio\Shlink\Core\Config\Options\RedirectOptions; use function sprintf; diff --git a/module/Core/src/Visit/Model/Visitor.php b/module/Core/src/Visit/Model/Visitor.php index 9cf524bc..ca5d79b2 100644 --- a/module/Core/src/Visit/Model/Visitor.php +++ b/module/Core/src/Visit/Model/Visitor.php @@ -5,7 +5,7 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Core\Visit\Model; use Psr\Http\Message\ServerRequestInterface; -use Shlinkio\Shlink\Core\Options\TrackingOptions; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use function Shlinkio\Shlink\Core\ipAddressFromRequest; use function Shlinkio\Shlink\Core\isCrawler; diff --git a/module/Core/src/Visit/RequestTracker.php b/module/Core/src/Visit/RequestTracker.php index 824e7c24..986e221c 100644 --- a/module/Core/src/Visit/RequestTracker.php +++ b/module/Core/src/Visit/RequestTracker.php @@ -7,9 +7,9 @@ namespace Shlinkio\Shlink\Core\Visit; use Fig\Http\Message\RequestMethodInterface; use Mezzio\Router\Middleware\ImplicitHeadMiddleware; use Psr\Http\Message\ServerRequestInterface; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; use Shlinkio\Shlink\Core\Exception\InvalidIpFormatException; -use Shlinkio\Shlink\Core\Options\TrackingOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\Util\IpAddressUtils; use Shlinkio\Shlink\Core\Visit\Model\Visitor; diff --git a/module/Core/src/Visit/VisitsTracker.php b/module/Core/src/Visit/VisitsTracker.php index f2e26493..85085220 100644 --- a/module/Core/src/Visit/VisitsTracker.php +++ b/module/Core/src/Visit/VisitsTracker.php @@ -6,8 +6,8 @@ namespace Shlinkio\Shlink\Core\Visit; use Doctrine\ORM; use Psr\EventDispatcher\EventDispatcherInterface; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use Shlinkio\Shlink\Core\EventDispatcher\Event\UrlVisited; -use Shlinkio\Shlink\Core\Options\TrackingOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\Visit\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Model\Visitor; diff --git a/module/Core/test/Action/QrCodeActionTest.php b/module/Core/test/Action/QrCodeActionTest.php index 08564bf9..5e499403 100644 --- a/module/Core/test/Action/QrCodeActionTest.php +++ b/module/Core/test/Action/QrCodeActionTest.php @@ -16,8 +16,8 @@ use Psr\Http\Server\RequestHandlerInterface; use Psr\Log\NullLogger; use Shlinkio\Shlink\Common\Response\QrCodeResponse; use Shlinkio\Shlink\Core\Action\QrCodeAction; +use Shlinkio\Shlink\Core\Config\Options\QrCodeOptions; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; -use Shlinkio\Shlink\Core\Options\QrCodeOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; @@ -324,7 +324,7 @@ class QrCodeActionTest extends TestCase { return new QrCodeAction( $this->urlResolver, - new ShortUrlStringifier(['domain' => 's.test']), + new ShortUrlStringifier(), new NullLogger(), $options ?? new QrCodeOptions(enabledForDisabledShortUrls: false), ); diff --git a/module/Core/test/Action/RobotsActionTest.php b/module/Core/test/Action/RobotsActionTest.php index 1d83fb8c..38d80de3 100644 --- a/module/Core/test/Action/RobotsActionTest.php +++ b/module/Core/test/Action/RobotsActionTest.php @@ -10,8 +10,8 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Core\Action\RobotsAction; +use Shlinkio\Shlink\Core\Config\Options\RobotsOptions; use Shlinkio\Shlink\Core\Crawling\CrawlingHelperInterface; -use Shlinkio\Shlink\Core\Options\RobotsOptions; class RobotsActionTest extends TestCase { diff --git a/module/Core/test/Config/NotFoundRedirectResolverTest.php b/module/Core/test/Config/NotFoundRedirectResolverTest.php index 5ef5db2b..75df0948 100644 --- a/module/Core/test/Config/NotFoundRedirectResolverTest.php +++ b/module/Core/test/Config/NotFoundRedirectResolverTest.php @@ -18,8 +18,8 @@ use Psr\Http\Message\UriInterface; use Psr\Log\NullLogger; use Shlinkio\Shlink\Core\Action\RedirectAction; use Shlinkio\Shlink\Core\Config\NotFoundRedirectResolver; +use Shlinkio\Shlink\Core\Config\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; -use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface; use function Laminas\Stratigility\middleware; diff --git a/module/Core/test/Config/PostProcessor/MultiSegmentSlugProcessorTest.php b/module/Core/test/Config/PostProcessor/MultiSegmentSlugProcessorTest.php index d811a2e2..487228ec 100644 --- a/module/Core/test/Config/PostProcessor/MultiSegmentSlugProcessorTest.php +++ b/module/Core/test/Config/PostProcessor/MultiSegmentSlugProcessorTest.php @@ -7,8 +7,11 @@ namespace ShlinkioTest\Shlink\Core\Config\PostProcessor; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; +use Shlinkio\Shlink\Core\Config\EnvVars; use Shlinkio\Shlink\Core\Config\PostProcessor\MultiSegmentSlugProcessor; +use function putenv; + class MultiSegmentSlugProcessorTest extends TestCase { private MultiSegmentSlugProcessor $processor; @@ -18,36 +21,35 @@ class MultiSegmentSlugProcessorTest extends TestCase $this->processor = new MultiSegmentSlugProcessor(); } - #[Test, DataProvider('provideConfigs')] - public function parsesRoutesAsExpected(array $config, array $expectedRoutes): void + protected function tearDown(): void { - self::assertEquals($expectedRoutes, ($this->processor)($config)['routes'] ?? []); + putenv(EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->value); + } + + #[Test, DataProvider('provideConfigs')] + public function parsesRoutesAsExpected(bool $multiSegmentEnabled, array $routes, array $expectedRoutes): void + { + putenv(EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->value . '=' . ($multiSegmentEnabled ? 'true' : 'false')); + self::assertEquals($expectedRoutes, ($this->processor)(['routes' => $routes])['routes'] ?? []); } public static function provideConfigs(): iterable { - yield [[], []]; - yield [['url_shortener' => []], []]; - yield [['url_shortener' => ['multi_segment_slugs_enabled' => false]], []]; yield [ - [ - 'url_shortener' => ['multi_segment_slugs_enabled' => false], - 'routes' => $routes = [ - ['path' => '/foo'], - ['path' => '/bar/{shortCode}'], - ['path' => '/baz/{shortCode}/foo'], - ], + false, + $routes = [ + ['path' => '/foo'], + ['path' => '/bar/{shortCode}'], + ['path' => '/baz/{shortCode}/foo'], ], $routes, ]; yield [ + true, [ - 'url_shortener' => ['multi_segment_slugs_enabled' => true], - 'routes' => [ - ['path' => '/foo'], - ['path' => '/bar/{shortCode}'], - ['path' => '/baz/{shortCode}/foo'], - ], + ['path' => '/foo'], + ['path' => '/bar/{shortCode}'], + ['path' => '/baz/{shortCode}/foo'], ], [ ['path' => '/foo'], diff --git a/module/Core/test/Domain/DomainServiceTest.php b/module/Core/test/Domain/DomainServiceTest.php index c67597ec..7e2fea18 100644 --- a/module/Core/test/Domain/DomainServiceTest.php +++ b/module/Core/test/Domain/DomainServiceTest.php @@ -11,6 +11,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Core\Config\EmptyNotFoundRedirectConfig; use Shlinkio\Shlink\Core\Config\NotFoundRedirects; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Domain\DomainService; use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Model\DomainItem; @@ -28,7 +29,7 @@ class DomainServiceTest extends TestCase protected function setUp(): void { $this->em = $this->createMock(EntityManagerInterface::class); - $this->domainService = new DomainService($this->em, 'default.com'); + $this->domainService = new DomainService($this->em, new UrlShortenerOptions(defaultDomain: 'default.com')); } #[Test, DataProvider('provideExcludedDomains')] diff --git a/module/Core/test/ErrorHandler/NotFoundRedirectHandlerTest.php b/module/Core/test/ErrorHandler/NotFoundRedirectHandlerTest.php index 53642f3a..25d9952f 100644 --- a/module/Core/test/ErrorHandler/NotFoundRedirectHandlerTest.php +++ b/module/Core/test/ErrorHandler/NotFoundRedirectHandlerTest.php @@ -16,11 +16,11 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\UriInterface; use Psr\Http\Server\RequestHandlerInterface; use Shlinkio\Shlink\Core\Config\NotFoundRedirectResolverInterface; +use Shlinkio\Shlink\Core\Config\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; use Shlinkio\Shlink\Core\ErrorHandler\NotFoundRedirectHandler; -use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; class NotFoundRedirectHandlerTest extends TestCase { diff --git a/module/Core/test/EventDispatcher/Helper/EnabledListenerCheckerTest.php b/module/Core/test/EventDispatcher/Helper/EnabledListenerCheckerTest.php index cebde437..180ab48d 100644 --- a/module/Core/test/EventDispatcher/Helper/EnabledListenerCheckerTest.php +++ b/module/Core/test/EventDispatcher/Helper/EnabledListenerCheckerTest.php @@ -8,6 +8,7 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Common\Mercure\MercureOptions; +use Shlinkio\Shlink\Core\Config\Options\RabbitMqOptions; use Shlinkio\Shlink\Core\EventDispatcher\Helper\EnabledListenerChecker; use Shlinkio\Shlink\Core\EventDispatcher\Matomo\SendVisitToMatomo; use Shlinkio\Shlink\Core\EventDispatcher\Mercure\NotifyNewShortUrlToMercure; @@ -18,7 +19,6 @@ use Shlinkio\Shlink\Core\EventDispatcher\RedisPubSub\NotifyNewShortUrlToRedis; use Shlinkio\Shlink\Core\EventDispatcher\RedisPubSub\NotifyVisitToRedis; use Shlinkio\Shlink\Core\EventDispatcher\UpdateGeoLiteDb; use Shlinkio\Shlink\Core\Matomo\MatomoOptions; -use Shlinkio\Shlink\Core\Options\RabbitMqOptions; use Shlinkio\Shlink\IpGeolocation\GeoLite2\GeoLite2Options; class EnabledListenerCheckerTest extends TestCase diff --git a/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php b/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php index bd3c82c8..1ea76bf6 100644 --- a/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php +++ b/module/Core/test/EventDispatcher/PublishingUpdatesGeneratorTest.php @@ -31,7 +31,7 @@ class PublishingUpdatesGeneratorTest extends TestCase Chronos::setTestNow($this->now); $this->generator = new PublishingUpdatesGenerator( - new ShortUrlDataTransformer(new ShortUrlStringifier([])), + new ShortUrlDataTransformer(new ShortUrlStringifier()), ); } diff --git a/module/Core/test/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMqTest.php b/module/Core/test/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMqTest.php index fc44fd87..b0c5a0e0 100644 --- a/module/Core/test/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMqTest.php +++ b/module/Core/test/EventDispatcher/RabbitMq/NotifyNewShortUrlToRabbitMqTest.php @@ -15,11 +15,11 @@ use Psr\Log\LoggerInterface; use RuntimeException; use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface; use Shlinkio\Shlink\Common\UpdatePublishing\Update; +use Shlinkio\Shlink\Core\Config\Options\RabbitMqOptions; use Shlinkio\Shlink\Core\EventDispatcher\Event\ShortUrlCreated; use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface; use Shlinkio\Shlink\Core\EventDispatcher\RabbitMq\NotifyNewShortUrlToRabbitMq; use Shlinkio\Shlink\Core\EventDispatcher\Topic; -use Shlinkio\Shlink\Core\Options\RabbitMqOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Throwable; diff --git a/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php b/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php index 2251d301..ac744824 100644 --- a/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php +++ b/module/Core/test/EventDispatcher/RabbitMq/NotifyVisitToRabbitMqTest.php @@ -16,10 +16,10 @@ use Psr\Log\LoggerInterface; use RuntimeException; use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface; use Shlinkio\Shlink\Common\UpdatePublishing\Update; +use Shlinkio\Shlink\Core\Config\Options\RabbitMqOptions; use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated; use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface; use Shlinkio\Shlink\Core\EventDispatcher\RabbitMq\NotifyVisitToRabbitMq; -use Shlinkio\Shlink\Core\Options\RabbitMqOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\Visit\Entity\Visit; diff --git a/module/Core/test/Matomo/MatomoVisitSenderTest.php b/module/Core/test/Matomo/MatomoVisitSenderTest.php index 816c8eea..6a4659f1 100644 --- a/module/Core/test/Matomo/MatomoVisitSenderTest.php +++ b/module/Core/test/Matomo/MatomoVisitSenderTest.php @@ -11,6 +11,7 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Common\Util\DateRange; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Matomo\MatomoTrackerBuilderInterface; use Shlinkio\Shlink\Core\Matomo\MatomoVisitSender; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; @@ -36,7 +37,7 @@ class MatomoVisitSenderTest extends TestCase $this->visitSender = new MatomoVisitSender( $this->trackerBuilder, - new ShortUrlStringifier(['hostname' => 's2.test']), + new ShortUrlStringifier(new UrlShortenerOptions(defaultDomain: 's2.test')), $this->visitIterationRepository, ); } diff --git a/module/Core/test/ShortUrl/DeleteShortUrlServiceTest.php b/module/Core/test/ShortUrl/DeleteShortUrlServiceTest.php index 4788818e..faddafeb 100644 --- a/module/Core/test/ShortUrl/DeleteShortUrlServiceTest.php +++ b/module/Core/test/ShortUrl/DeleteShortUrlServiceTest.php @@ -9,8 +9,8 @@ use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use Shlinkio\Shlink\Core\Config\Options\DeleteShortUrlsOptions; use Shlinkio\Shlink\Core\Exception\DeleteShortUrlException; -use Shlinkio\Shlink\Core\Options\DeleteShortUrlsOptions; use Shlinkio\Shlink\Core\ShortUrl\DeleteShortUrlService; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ExpiredShortUrlsConditions; diff --git a/module/Core/test/ShortUrl/Entity/ShortUrlTest.php b/module/Core/test/ShortUrl/Entity/ShortUrlTest.php index be5b4101..b3720254 100644 --- a/module/Core/test/ShortUrl/Entity/ShortUrlTest.php +++ b/module/Core/test/ShortUrl/Entity/ShortUrlTest.php @@ -9,8 +9,8 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Exception\ShortCodeCannotBeRegeneratedException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlMode; diff --git a/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php b/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php index efbbde21..de1402f6 100644 --- a/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortCodeUniquenessHelperTest.php @@ -9,8 +9,8 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Domain\Entity\Domain; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortCodeUniquenessHelper; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; diff --git a/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php b/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php index afe83c8d..d1283a78 100644 --- a/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortUrlRedirectionBuilderTest.php @@ -12,7 +12,7 @@ use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; -use Shlinkio\Shlink\Core\Options\TrackingOptions; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use Shlinkio\Shlink\Core\RedirectRule\ShortUrlRedirectionResolverInterface; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlRedirectionBuilder; diff --git a/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php b/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php index e74d6182..d28fdf0e 100644 --- a/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortUrlStringifierTest.php @@ -7,20 +7,25 @@ namespace ShlinkioTest\Shlink\Core\ShortUrl\Helper; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; class ShortUrlStringifierTest extends TestCase { + /** + * @param 'http'|'https' $schema + */ #[Test, DataProvider('provideConfigAndShortUrls')] public function generatesExpectedOutputBasedOnConfigAndShortUrl( - array $config, + string $defaultDomain, + string $schema, string $basePath, ShortUrl $shortUrl, string $expected, ): void { - $stringifier = new ShortUrlStringifier($config, $basePath); + $stringifier = new ShortUrlStringifier(new UrlShortenerOptions($defaultDomain, $schema), $basePath); self::assertEquals($expected, $stringifier->stringify($shortUrl)); } @@ -35,45 +40,45 @@ class ShortUrlStringifierTest extends TestCase ]), ); - yield 'no config' => [[], '', $shortUrlWithShortCode('foo'), 'http:/foo']; - yield 'hostname in config' => [ - ['hostname' => 'example.com'], + yield 'no default domain' => ['', 'http', '', $shortUrlWithShortCode('foo'), 'http:/foo']; + yield 'default domain' => [ + 'example.com', + 'http', '', $shortUrlWithShortCode('bar'), 'http://example.com/bar', ]; yield 'special chars in short code' => [ - ['hostname' => 'example.com'], + 'example.com', + 'http', '', $shortUrlWithShortCode('グーグル'), 'http://example.com/グーグル', ]; yield 'emojis in short code' => [ - ['hostname' => 'example.com'], + 'example.com', + 'http', '', $shortUrlWithShortCode('🦣-🍅'), 'http://example.com/🦣-🍅', ]; - yield 'hostname with base path in config' => [ - ['hostname' => 'example.com/foo/bar'], + yield 'default domain with base path' => [ + 'example.com/foo/bar', + 'http', '', $shortUrlWithShortCode('abc'), 'http://example.com/foo/bar/abc', ]; - yield 'full config' => [ - ['schema' => 'https', 'hostname' => 'foo.com'], - '', - $shortUrlWithShortCode('baz'), - 'https://foo.com/baz', - ]; yield 'custom domain' => [ - ['schema' => 'https', 'hostname' => 'foo.com'], + 'foo.com', + 'https', '', $shortUrlWithShortCode('baz', 'mydom.es'), 'https://mydom.es/baz', ]; yield 'custom domain with base path' => [ - ['schema' => 'https', 'hostname' => 'foo.com'], + 'foo.com', + 'https', '/foo/bar', $shortUrlWithShortCode('baz', 'mydom.es'), 'https://mydom.es/foo/bar/baz', diff --git a/module/Core/test/ShortUrl/Helper/ShortUrlTitleResolutionHelperTest.php b/module/Core/test/ShortUrl/Helper/ShortUrlTitleResolutionHelperTest.php index 4e3056b3..b5b8e00c 100644 --- a/module/Core/test/ShortUrl/Helper/ShortUrlTitleResolutionHelperTest.php +++ b/module/Core/test/ShortUrl/Helper/ShortUrlTitleResolutionHelperTest.php @@ -16,7 +16,7 @@ use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\MockObject\Builder\InvocationMocker; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlTitleResolutionHelper; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; diff --git a/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php b/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php index 3965fe18..6815acb6 100644 --- a/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php +++ b/module/Core/test/ShortUrl/Middleware/ExtraPathRedirectMiddlewareTest.php @@ -16,9 +16,9 @@ use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; use Shlinkio\Shlink\Core\Action\RedirectAction; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlRedirectionBuilderInterface; use Shlinkio\Shlink\Core\ShortUrl\Middleware\ExtraPathRedirectMiddleware; diff --git a/module/Core/test/ShortUrl/Middleware/TrimTrailingSlashMiddlewareTest.php b/module/Core/test/ShortUrl/Middleware/TrimTrailingSlashMiddlewareTest.php index b05ab7d9..c37c81a5 100644 --- a/module/Core/test/ShortUrl/Middleware/TrimTrailingSlashMiddlewareTest.php +++ b/module/Core/test/ShortUrl/Middleware/TrimTrailingSlashMiddlewareTest.php @@ -13,7 +13,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Middleware\TrimTrailingSlashMiddleware; class TrimTrailingSlashMiddlewareTest extends TestCase diff --git a/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php b/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php index b84b5b27..e963923b 100644 --- a/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php +++ b/module/Core/test/ShortUrl/Model/ShortUrlCreationTest.php @@ -8,8 +8,8 @@ use Cake\Chronos\Chronos; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Exception\ValidationException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlMode; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter; diff --git a/module/Core/test/ShortUrl/Model/Validation/CustomSlugValidatorTest.php b/module/Core/test/ShortUrl/Model/Validation/CustomSlugValidatorTest.php index 290fe63d..86f695c7 100644 --- a/module/Core/test/ShortUrl/Model/Validation/CustomSlugValidatorTest.php +++ b/module/Core/test/ShortUrl/Model/Validation/CustomSlugValidatorTest.php @@ -7,7 +7,7 @@ namespace ShlinkioTest\Shlink\Core\ShortUrl\Model\Validation; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\CustomSlugValidator; use stdClass; diff --git a/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php b/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php index 43860909..722ac347 100644 --- a/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php +++ b/module/Core/test/ShortUrl/Resolver/PersistenceShortUrlRelationResolverTest.php @@ -10,9 +10,9 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Repository\DomainRepository; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Resolver\PersistenceShortUrlRelationResolver; use Shlinkio\Shlink\Core\Tag\Entity\Tag; use Shlinkio\Shlink\Core\Tag\Repository\TagRepository; @@ -29,9 +29,7 @@ class PersistenceShortUrlRelationResolverTest extends TestCase $this->em = $this->createMock(EntityManagerInterface::class); $this->em->method('getEventManager')->willReturn(new EventManager()); - $this->resolver = new PersistenceShortUrlRelationResolver($this->em, new UrlShortenerOptions( - domain: ['schema' => 'https', 'hostname' => 'default.com'], - )); + $this->resolver = new PersistenceShortUrlRelationResolver($this->em, new UrlShortenerOptions('default.com')); } #[Test, DataProvider('provideDomainsThatEmpty')] diff --git a/module/Core/test/ShortUrl/ShortUrlListServiceTest.php b/module/Core/test/ShortUrl/ShortUrlListServiceTest.php index a469ed60..d8663761 100644 --- a/module/Core/test/ShortUrl/ShortUrlListServiceTest.php +++ b/module/Core/test/ShortUrl/ShortUrlListServiceTest.php @@ -8,7 +8,7 @@ use PHPUnit\Framework\Attributes\DataProviderExternal; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlListRepositoryInterface; diff --git a/module/Core/test/ShortUrl/ShortUrlResolverTest.php b/module/Core/test/ShortUrl/ShortUrlResolverTest.php index 1b3aa564..e8443a13 100644 --- a/module/Core/test/ShortUrl/ShortUrlResolverTest.php +++ b/module/Core/test/ShortUrl/ShortUrlResolverTest.php @@ -12,8 +12,8 @@ use PHPUnit\Framework\Attributes\DataProviderExternal; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier; diff --git a/module/Core/test/ShortUrl/Transformer/ShortUrlDataTransformerTest.php b/module/Core/test/ShortUrl/Transformer/ShortUrlDataTransformerTest.php index 349392db..9ff01475 100644 --- a/module/Core/test/ShortUrl/Transformer/ShortUrlDataTransformerTest.php +++ b/module/Core/test/ShortUrl/Transformer/ShortUrlDataTransformerTest.php @@ -21,7 +21,7 @@ class ShortUrlDataTransformerTest extends TestCase protected function setUp(): void { - $this->transformer = new ShortUrlDataTransformer(new ShortUrlStringifier([])); + $this->transformer = new ShortUrlDataTransformer(new ShortUrlStringifier()); } #[Test, DataProvider('provideShortUrls')] diff --git a/module/Core/test/Util/RedirectResponseHelperTest.php b/module/Core/test/Util/RedirectResponseHelperTest.php index 63e55e2e..89d3fa5a 100644 --- a/module/Core/test/Util/RedirectResponseHelperTest.php +++ b/module/Core/test/Util/RedirectResponseHelperTest.php @@ -8,7 +8,7 @@ use Laminas\Diactoros\Response\RedirectResponse; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\Core\Options\RedirectOptions; +use Shlinkio\Shlink\Core\Config\Options\RedirectOptions; use Shlinkio\Shlink\Core\Util\RedirectResponseHelper; class RedirectResponseHelperTest extends TestCase diff --git a/module/Core/test/Visit/Model/VisitorTest.php b/module/Core/test/Visit/Model/VisitorTest.php index 74065d7d..04e57179 100644 --- a/module/Core/test/Visit/Model/VisitorTest.php +++ b/module/Core/test/Visit/Model/VisitorTest.php @@ -7,7 +7,7 @@ namespace ShlinkioTest\Shlink\Core\Visit\Model; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\Core\Options\TrackingOptions; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use Shlinkio\Shlink\Core\Visit\Model\Visitor; use function random_int; diff --git a/module/Core/test/Visit/RequestTrackerTest.php b/module/Core/test/Visit/RequestTrackerTest.php index c8746f91..ae0a74c4 100644 --- a/module/Core/test/Visit/RequestTrackerTest.php +++ b/module/Core/test/Visit/RequestTrackerTest.php @@ -13,8 +13,8 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; use Shlinkio\Shlink\Common\Middleware\IpAddressMiddlewareFactory; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; -use Shlinkio\Shlink\Core\Options\TrackingOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\Visit\Model\Visitor; use Shlinkio\Shlink\Core\Visit\RequestTracker; diff --git a/module/Core/test/Visit/VisitsTrackerTest.php b/module/Core/test/Visit/VisitsTrackerTest.php index d6cbf4bf..414f5254 100644 --- a/module/Core/test/Visit/VisitsTrackerTest.php +++ b/module/Core/test/Visit/VisitsTrackerTest.php @@ -10,8 +10,8 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\EventDispatcher\EventDispatcherInterface; +use Shlinkio\Shlink\Core\Config\Options\TrackingOptions; use Shlinkio\Shlink\Core\EventDispatcher\Event\UrlVisited; -use Shlinkio\Shlink\Core\Options\TrackingOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\Visit\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Model\Visitor; diff --git a/module/Rest/config/dependencies.config.php b/module/Rest/config/dependencies.config.php index d334d5b0..b69cf36d 100644 --- a/module/Rest/config/dependencies.config.php +++ b/module/Rest/config/dependencies.config.php @@ -10,8 +10,8 @@ use Mezzio\ProblemDetails\ProblemDetailsResponseFactory; use Mezzio\Router\Middleware\ImplicitOptionsMiddleware; use Psr\Log\LoggerInterface; use Shlinkio\Shlink\Common\Mercure\LcobucciJwtProvider; +use Shlinkio\Shlink\Core\Config; use Shlinkio\Shlink\Core\Domain\DomainService; -use Shlinkio\Shlink\Core\Options; use Shlinkio\Shlink\Core\RedirectRule; use Shlinkio\Shlink\Core\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformer; @@ -64,17 +64,17 @@ return [ ConfigAbstractFactory::class => [ ApiKeyService::class => ['em'], - Action\HealthAction::class => ['em', Options\AppOptions::class], + Action\HealthAction::class => ['em', Config\Options\AppOptions::class], Action\MercureInfoAction::class => [LcobucciJwtProvider::class, 'config.mercure'], Action\ShortUrl\CreateShortUrlAction::class => [ ShortUrl\UrlShortener::class, ShortUrlDataTransformer::class, - Options\UrlShortenerOptions::class, + Config\Options\UrlShortenerOptions::class, ], Action\ShortUrl\SingleStepCreateShortUrlAction::class => [ ShortUrl\UrlShortener::class, ShortUrlDataTransformer::class, - Options\UrlShortenerOptions::class, + Config\Options\UrlShortenerOptions::class, ], Action\ShortUrl\EditShortUrlAction::class => [ShortUrl\ShortUrlService::class, ShortUrlDataTransformer::class], Action\ShortUrl\DeleteShortUrlAction::class => [ShortUrl\DeleteShortUrlService::class], @@ -86,7 +86,7 @@ return [ Action\Visit\TagVisitsAction::class => [Visit\VisitsStatsHelper::class], Action\Visit\DomainVisitsAction::class => [ Visit\VisitsStatsHelper::class, - 'config.url_shortener.domain.hostname', + Config\Options\UrlShortenerOptions::class, ], Action\Visit\GlobalVisitsAction::class => [Visit\VisitsStatsHelper::class], Action\Visit\OrphanVisitsAction::class => [Visit\VisitsStatsHelper::class], @@ -101,7 +101,7 @@ return [ Action\Tag\TagsStatsAction::class => [TagService::class], Action\Tag\DeleteTagsAction::class => [TagService::class], Action\Tag\UpdateTagAction::class => [TagService::class], - Action\Domain\ListDomainsAction::class => [DomainService::class, Options\NotFoundRedirectOptions::class], + Action\Domain\ListDomainsAction::class => [DomainService::class, Config\Options\NotFoundRedirectOptions::class], Action\Domain\DomainRedirectsAction::class => [DomainService::class], Action\RedirectRule\ListRedirectRulesAction::class => [ ShortUrl\ShortUrlResolver::class, @@ -113,10 +113,10 @@ return [ ], Middleware\CrossDomainMiddleware::class => ['config.cors'], - Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class => ['config.url_shortener.domain.hostname'], - Middleware\ShortUrl\DefaultShortCodesLengthMiddleware::class => [ - 'config.url_shortener.default_short_codes_length', + Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class => [ + Config\Options\UrlShortenerOptions::class, ], + Middleware\ShortUrl\DefaultShortCodesLengthMiddleware::class => [Config\Options\UrlShortenerOptions::class], Middleware\ShortUrl\OverrideDomainMiddleware::class => [DomainService::class], Middleware\Mercure\NotConfiguredMercureErrorHandler::class => [ ProblemDetailsResponseFactory::class, diff --git a/module/Rest/src/Action/Domain/ListDomainsAction.php b/module/Rest/src/Action/Domain/ListDomainsAction.php index e50ada16..d156a720 100644 --- a/module/Rest/src/Action/Domain/ListDomainsAction.php +++ b/module/Rest/src/Action/Domain/ListDomainsAction.php @@ -8,8 +8,8 @@ use Laminas\Diactoros\Response\JsonResponse; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Shlinkio\Shlink\Core\Config\NotFoundRedirects; +use Shlinkio\Shlink\Core\Config\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; -use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Rest\Action\AbstractRestAction; use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware; diff --git a/module/Rest/src/Action/HealthAction.php b/module/Rest/src/Action/HealthAction.php index 809bf4d1..ce731330 100644 --- a/module/Rest/src/Action/HealthAction.php +++ b/module/Rest/src/Action/HealthAction.php @@ -8,7 +8,7 @@ use Doctrine\ORM\EntityManagerInterface; use Laminas\Diactoros\Response\JsonResponse; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; -use Shlinkio\Shlink\Core\Options\AppOptions; +use Shlinkio\Shlink\Core\Config\Options\AppOptions; use Throwable; class HealthAction extends AbstractRestAction diff --git a/module/Rest/src/Action/ShortUrl/AbstractCreateShortUrlAction.php b/module/Rest/src/Action/ShortUrl/AbstractCreateShortUrlAction.php index 65f47d95..75d5480b 100644 --- a/module/Rest/src/Action/ShortUrl/AbstractCreateShortUrlAction.php +++ b/module/Rest/src/Action/ShortUrl/AbstractCreateShortUrlAction.php @@ -7,8 +7,8 @@ namespace Shlinkio\Shlink\Rest\Action\ShortUrl; use Laminas\Diactoros\Response\JsonResponse; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Exception\ValidationException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformerInterface; use Shlinkio\Shlink\Core\ShortUrl\UrlShortenerInterface; diff --git a/module/Rest/src/Action/Visit/DomainVisitsAction.php b/module/Rest/src/Action/Visit/DomainVisitsAction.php index 91f071b5..4d534202 100644 --- a/module/Rest/src/Action/Visit/DomainVisitsAction.php +++ b/module/Rest/src/Action/Visit/DomainVisitsAction.php @@ -8,6 +8,7 @@ use Laminas\Diactoros\Response\JsonResponse; use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtils; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Visit\Model\VisitsParams; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Rest\Action\AbstractRestAction; @@ -20,7 +21,7 @@ class DomainVisitsAction extends AbstractRestAction public function __construct( private readonly VisitsStatsHelperInterface $visitsHelper, - private readonly string $defaultDomain, + private readonly UrlShortenerOptions $urlShortenerOptions, ) { } @@ -37,7 +38,7 @@ class DomainVisitsAction extends AbstractRestAction private function resolveDomainParam(Request $request): string { $domainParam = $request->getAttribute('domain', ''); - if ($domainParam === $this->defaultDomain) { + if ($domainParam === $this->urlShortenerOptions->defaultDomain) { return 'DEFAULT'; } diff --git a/module/Rest/src/Middleware/ShortUrl/DefaultShortCodesLengthMiddleware.php b/module/Rest/src/Middleware/ShortUrl/DefaultShortCodesLengthMiddleware.php index 4b7779c2..0d7d947e 100644 --- a/module/Rest/src/Middleware/ShortUrl/DefaultShortCodesLengthMiddleware.php +++ b/module/Rest/src/Middleware/ShortUrl/DefaultShortCodesLengthMiddleware.php @@ -8,11 +8,12 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter; -class DefaultShortCodesLengthMiddleware implements MiddlewareInterface +readonly class DefaultShortCodesLengthMiddleware implements MiddlewareInterface { - public function __construct(private int $defaultShortCodesLength) + public function __construct(private UrlShortenerOptions $urlShortenerOptions) { } @@ -21,7 +22,7 @@ class DefaultShortCodesLengthMiddleware implements MiddlewareInterface /** @var array $body */ $body = $request->getParsedBody(); if (! isset($body[ShortUrlInputFilter::SHORT_CODE_LENGTH])) { - $body[ShortUrlInputFilter::SHORT_CODE_LENGTH] = $this->defaultShortCodesLength; + $body[ShortUrlInputFilter::SHORT_CODE_LENGTH] = $this->urlShortenerOptions->defaultShortCodesLength; } return $handler->handle($request->withParsedBody($body)); diff --git a/module/Rest/src/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddleware.php b/module/Rest/src/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddleware.php index 73a6ac69..acf33603 100644 --- a/module/Rest/src/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddleware.php +++ b/module/Rest/src/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddleware.php @@ -8,10 +8,11 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; -class DropDefaultDomainFromRequestMiddleware implements MiddlewareInterface +readonly class DropDefaultDomainFromRequestMiddleware implements MiddlewareInterface { - public function __construct(private readonly string $defaultDomain) + public function __construct(private UrlShortenerOptions $urlShortenerOptions) { } @@ -27,7 +28,7 @@ class DropDefaultDomainFromRequestMiddleware implements MiddlewareInterface private function sanitizeDomainFromPayload(array $payload): array { - if (isset($payload['domain']) && $payload['domain'] === $this->defaultDomain) { + if (isset($payload['domain']) && $payload['domain'] === $this->urlShortenerOptions->defaultDomain) { unset($payload['domain']); } diff --git a/module/Rest/test/Action/Domain/ListDomainsActionTest.php b/module/Rest/test/Action/Domain/ListDomainsActionTest.php index 41906539..4864048c 100644 --- a/module/Rest/test/Action/Domain/ListDomainsActionTest.php +++ b/module/Rest/test/Action/Domain/ListDomainsActionTest.php @@ -10,10 +10,10 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Core\Config\NotFoundRedirects; +use Shlinkio\Shlink\Core\Config\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Core\Domain\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Model\DomainItem; -use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Rest\Action\Domain\ListDomainsAction; use Shlinkio\Shlink\Rest\Entity\ApiKey; diff --git a/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php b/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php index 89b93b80..292c1748 100644 --- a/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php +++ b/module/Rest/test/Action/Domain/Request/DomainRedirectsRequestTest.php @@ -8,8 +8,8 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Core\Config\NotFoundRedirectConfigInterface; +use Shlinkio\Shlink\Core\Config\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Exception\ValidationException; -use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Rest\Action\Domain\Request\DomainRedirectsRequest; class DomainRedirectsRequestTest extends TestCase diff --git a/module/Rest/test/Action/HealthActionTest.php b/module/Rest/test/Action/HealthActionTest.php index 59075646..aae90f49 100644 --- a/module/Rest/test/Action/HealthActionTest.php +++ b/module/Rest/test/Action/HealthActionTest.php @@ -14,7 +14,7 @@ use Laminas\Diactoros\ServerRequest; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\Core\Options\AppOptions; +use Shlinkio\Shlink\Core\Config\Options\AppOptions; use Shlinkio\Shlink\Rest\Action\HealthAction; class HealthActionTest extends TestCase diff --git a/module/Rest/test/Action/ShortUrl/CreateShortUrlActionTest.php b/module/Rest/test/Action/ShortUrl/CreateShortUrlActionTest.php index 7361df5c..06cd5554 100644 --- a/module/Rest/test/Action/ShortUrl/CreateShortUrlActionTest.php +++ b/module/Rest/test/Action/ShortUrl/CreateShortUrlActionTest.php @@ -12,8 +12,8 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Exception\ValidationException; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\UrlShorteningResult; diff --git a/module/Rest/test/Action/ShortUrl/EditShortUrlActionTest.php b/module/Rest/test/Action/ShortUrl/EditShortUrlActionTest.php index dd7a0e14..669037d1 100644 --- a/module/Rest/test/Action/ShortUrl/EditShortUrlActionTest.php +++ b/module/Rest/test/Action/ShortUrl/EditShortUrlActionTest.php @@ -25,7 +25,7 @@ class EditShortUrlActionTest extends TestCase { $this->shortUrlService = $this->createMock(ShortUrlServiceInterface::class); $this->action = new EditShortUrlAction($this->shortUrlService, new ShortUrlDataTransformer( - new ShortUrlStringifier([]), + new ShortUrlStringifier(), )); } diff --git a/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php b/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php index d372d692..a3beba1b 100644 --- a/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php +++ b/module/Rest/test/Action/ShortUrl/ListShortUrlsActionTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Common\Paginator\Paginator; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlListServiceInterface; @@ -30,10 +31,7 @@ class ListShortUrlsActionTest extends TestCase $this->service = $this->createMock(ShortUrlListServiceInterface::class); $this->action = new ListShortUrlsAction($this->service, new ShortUrlDataTransformer( - new ShortUrlStringifier([ - 'hostname' => 's.test', - 'schema' => 'https', - ]), + new ShortUrlStringifier(new UrlShortenerOptions('s.test')), )); } diff --git a/module/Rest/test/Action/ShortUrl/ResolveShortUrlActionTest.php b/module/Rest/test/Action/ShortUrl/ResolveShortUrlActionTest.php index 0576fd52..13b9e35d 100644 --- a/module/Rest/test/Action/ShortUrl/ResolveShortUrlActionTest.php +++ b/module/Rest/test/Action/ShortUrl/ResolveShortUrlActionTest.php @@ -25,7 +25,7 @@ class ResolveShortUrlActionTest extends TestCase { $this->urlResolver = $this->createMock(ShortUrlResolverInterface::class); $this->action = new ResolveShortUrlAction($this->urlResolver, new ShortUrlDataTransformer( - new ShortUrlStringifier([]), + new ShortUrlStringifier(), )); } diff --git a/module/Rest/test/Action/ShortUrl/SingleStepCreateShortUrlActionTest.php b/module/Rest/test/Action/ShortUrl/SingleStepCreateShortUrlActionTest.php index 69914f0e..d28c3b49 100644 --- a/module/Rest/test/Action/ShortUrl/SingleStepCreateShortUrlActionTest.php +++ b/module/Rest/test/Action/ShortUrl/SingleStepCreateShortUrlActionTest.php @@ -8,7 +8,7 @@ use Laminas\Diactoros\ServerRequest; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation; use Shlinkio\Shlink\Core\ShortUrl\Model\UrlShorteningResult; diff --git a/module/Rest/test/Action/Visit/DomainVisitsActionTest.php b/module/Rest/test/Action/Visit/DomainVisitsActionTest.php index a6d64bd2..d60dae2e 100644 --- a/module/Rest/test/Action/Visit/DomainVisitsActionTest.php +++ b/module/Rest/test/Action/Visit/DomainVisitsActionTest.php @@ -11,6 +11,7 @@ use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Shlinkio\Shlink\Common\Paginator\Paginator; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Visit\Model\VisitsParams; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Rest\Action\Visit\DomainVisitsAction; @@ -24,7 +25,7 @@ class DomainVisitsActionTest extends TestCase protected function setUp(): void { $this->visitsHelper = $this->createMock(VisitsStatsHelperInterface::class); - $this->action = new DomainVisitsAction($this->visitsHelper, 'the_default.com'); + $this->action = new DomainVisitsAction($this->visitsHelper, new UrlShortenerOptions('the_default.com')); } #[Test, DataProvider('provideDomainAuthorities')] diff --git a/module/Rest/test/Middleware/ShortUrl/DefaultShortCodesLengthMiddlewareTest.php b/module/Rest/test/Middleware/ShortUrl/DefaultShortCodesLengthMiddlewareTest.php index e6b0c6ec..db579451 100644 --- a/module/Rest/test/Middleware/ShortUrl/DefaultShortCodesLengthMiddlewareTest.php +++ b/module/Rest/test/Middleware/ShortUrl/DefaultShortCodesLengthMiddlewareTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter; use Shlinkio\Shlink\Rest\Middleware\ShortUrl\DefaultShortCodesLengthMiddleware; @@ -24,7 +25,7 @@ class DefaultShortCodesLengthMiddlewareTest extends TestCase protected function setUp(): void { $this->handler = $this->createMock(RequestHandlerInterface::class); - $this->middleware = new DefaultShortCodesLengthMiddleware(8); + $this->middleware = new DefaultShortCodesLengthMiddleware(new UrlShortenerOptions(defaultShortCodesLength: 8)); } #[Test, DataProvider('provideBodies')] diff --git a/module/Rest/test/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddlewareTest.php b/module/Rest/test/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddlewareTest.php index e9fceea5..b8235498 100644 --- a/module/Rest/test/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddlewareTest.php +++ b/module/Rest/test/Middleware/ShortUrl/DropDefaultDomainFromRequestMiddlewareTest.php @@ -13,6 +13,7 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; +use Shlinkio\Shlink\Core\Config\Options\UrlShortenerOptions; use Shlinkio\Shlink\Rest\Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware; class DropDefaultDomainFromRequestMiddlewareTest extends TestCase @@ -23,7 +24,7 @@ class DropDefaultDomainFromRequestMiddlewareTest extends TestCase protected function setUp(): void { $this->next = $this->createMock(RequestHandlerInterface::class); - $this->middleware = new DropDefaultDomainFromRequestMiddleware('s.test'); + $this->middleware = new DropDefaultDomainFromRequestMiddleware(new UrlShortenerOptions('s.test')); } #[Test, DataProvider('provideQueryParams')]