Merge pull request #1559 from shlinkio/develop

Release 3.3.1
This commit is contained in:
Alejandro Celaya
2022-09-30 17:37:29 +02:00
committed by GitHub
236 changed files with 1006 additions and 840 deletions

View File

@@ -41,7 +41,10 @@ runs:
extensions: ${{ inputs.php-extensions }} extensions: ${{ inputs.php-extensions }}
coverage: pcov coverage: pcov
ini-values: pcov.directory=module ini-values: pcov.directory=module
- run: echo "::set-output name=composerArgs::${{ inputs.php-version == '8.2' && '--ignore-platform-req=php' || '' }}"
id: composer_args
shell: bash
- name: Install dependencies - name: Install dependencies
if: ${{ inputs.install-deps == 'yes' }} if: ${{ inputs.install-deps == 'yes' }}
run: composer install --no-interaction --prefer-dist run: composer install --no-interaction --prefer-dist ${{ steps.composer_args.outputs.composerArgs }}
shell: bash shell: bash

View File

@@ -13,7 +13,8 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
php-version: [ '8.1' ] php-version: ['8.1', '8.2']
continue-on-error: ${{ matrix.php-version == '8.2' }}
env: env:
LC_ALL: C LC_ALL: C
steps: steps:

View File

@@ -13,7 +13,8 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
php-version: [ '8.1' ] php-version: ['8.1', '8.2']
continue-on-error: ${{ matrix.php-version == '8.2' }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: './.github/actions/ci-setup' - uses: './.github/actions/ci-setup'

View File

@@ -13,7 +13,8 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
php-version: ['8.1'] php-version: ['8.1', '8.2']
continue-on-error: ${{ matrix.php-version == '8.2' }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- name: Start postgres database server - name: Start postgres database server

View File

@@ -43,7 +43,8 @@ jobs:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
strategy: strategy:
matrix: matrix:
php-version: [ '8.1' ] php-version: ['8.1', '8.2']
continue-on-error: ${{ matrix.php-version == '8.2' }}
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_postgres - run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_postgres
@@ -51,7 +52,10 @@ jobs:
with: with:
php-version: ${{ matrix.php-version }} php-version: ${{ matrix.php-version }}
tools: composer tools: composer
- run: composer install --no-interaction --prefer-dist - run: echo "::set-output name=composerArgs::${{ matrix.php-version == '8.2' && '--ignore-platform-req=php' || '' }}"
id: composer_args
shell: bash
- run: composer install --no-interaction --prefer-dist ${{ steps.composer_args.outputs.composerArgs }}
- run: ./vendor/bin/rr get --no-interaction --location bin/ && chmod +x bin/rr - run: ./vendor/bin/rr get --no-interaction --location bin/ && chmod +x bin/rr
- run: composer test:api:rr - run: composer test:api:rr

View File

@@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org). The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org).
## [3.3.1] - 2022-09-30
### Added
* *Nothing*
### Changed
* [#1474](https://github.com/shlinkio/shlink/issues/1474) Added preliminary support for PHP 8.2 during CI workflow.
* [#1551](https://github.com/shlinkio/shlink/issues/1551) Moved services related to geolocating visits to the `Visit\Geolocation` namespace.
* [#1550](https://github.com/shlinkio/shlink/issues/1550) Reorganized main namespaces from Core module.
### Deprecated
* *Nothing*
### Removed
* *Nothing*
### Fixed
* [#1556](https://github.com/shlinkio/shlink/issues/1556) Fixed trailing slash not working when enabling multi-segment slashes.
## [3.3.0] - 2022-09-18 ## [3.3.0] - 2022-09-18
### Added ### Added
* [#1221](https://github.com/shlinkio/shlink/issues/1221) Added experimental support to run Shlink with [RoadRunner](https://roadrunner.dev) instead of openswoole. * [#1221](https://github.com/shlinkio/shlink/issues/1221) Added experimental support to run Shlink with [RoadRunner](https://roadrunner.dev) instead of openswoole.

View File

@@ -133,9 +133,9 @@
"test:cli:pretty": "GENERATE_COVERAGE=pretty composer test:cli", "test:cli:pretty": "GENERATE_COVERAGE=pretty composer test:cli",
"infect:ci:base": "infection --threads=max --only-covered --only-covering-test-cases --skip-initial-tests", "infect:ci:base": "infection --threads=max --only-covered --only-covering-test-cases --skip-initial-tests",
"infect:ci:unit": "@infect:ci:base --coverage=build/coverage-unit --min-msi=84", "infect:ci:unit": "@infect:ci:base --coverage=build/coverage-unit --min-msi=84",
"infect:ci:db": "@infect:ci:base --coverage=build/coverage-db --min-msi=95 --configuration=infection-db.json", "infect:ci:db": "@infect:ci:base --coverage=build/coverage-db --min-msi=95 --configuration=infection-db.json5",
"infect:ci:api": "@infect:ci:base --coverage=build/coverage-api --min-msi=80 --configuration=infection-api.json", "infect:ci:api": "@infect:ci:base --coverage=build/coverage-api --min-msi=80 --configuration=infection-api.json5",
"infect:ci:cli": "@infect:ci:base --coverage=build/coverage-cli --min-msi=80 --configuration=infection-cli.json", "infect:ci:cli": "@infect:ci:base --coverage=build/coverage-cli --min-msi=80 --configuration=infection-cli.json5",
"infect:ci": "@parallel infect:ci:unit infect:ci:db infect:ci:api infect:ci:cli", "infect:ci": "@parallel infect:ci:unit infect:ci:db infect:ci:api infect:ci:cli",
"infect:test": [ "infect:test": [
"@parallel test:unit:ci test:db:sqlite:ci test:api:ci", "@parallel test:unit:ci test:db:sqlite:ci test:api:ci",

View File

@@ -8,6 +8,7 @@ use Fig\Http\Message\RequestMethodInterface;
use RKA\Middleware\IpAddress; use RKA\Middleware\IpAddress;
use Shlinkio\Shlink\Core\Action as CoreAction; use Shlinkio\Shlink\Core\Action as CoreAction;
use Shlinkio\Shlink\Core\Config\EnvVars; use Shlinkio\Shlink\Core\Config\EnvVars;
use Shlinkio\Shlink\Core\ShortUrl\Middleware\TrimTrailingSlashMiddleware;
use Shlinkio\Shlink\Rest\Action; use Shlinkio\Shlink\Rest\Action;
use Shlinkio\Shlink\Rest\ConfigProvider; use Shlinkio\Shlink\Rest\ConfigProvider;
use Shlinkio\Shlink\Rest\Middleware; use Shlinkio\Shlink\Rest\Middleware;
@@ -19,6 +20,8 @@ return (static function (): array {
$contentNegotiationMiddleware = Middleware\ShortUrl\CreateShortUrlContentNegotiationMiddleware::class; $contentNegotiationMiddleware = Middleware\ShortUrl\CreateShortUrlContentNegotiationMiddleware::class;
$dropDomainMiddleware = Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class; $dropDomainMiddleware = Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class;
$overrideDomainMiddleware = Middleware\ShortUrl\OverrideDomainMiddleware::class; $overrideDomainMiddleware = Middleware\ShortUrl\OverrideDomainMiddleware::class;
// TODO This should be based on config, not the env var
$shortUrlRouteSuffix = EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(false) ? '[/]' : ''; $shortUrlRouteSuffix = EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(false) ? '[/]' : '';
return [ return [
@@ -97,6 +100,7 @@ return (static function (): array {
'path' => sprintf('/{shortCode}%s', $shortUrlRouteSuffix), 'path' => sprintf('/{shortCode}%s', $shortUrlRouteSuffix),
'middleware' => [ 'middleware' => [
IpAddress::class, IpAddress::class,
TrimTrailingSlashMiddleware::class,
CoreAction\RedirectAction::class, CoreAction\RedirectAction::class,
], ],
'allowed_methods' => [RequestMethodInterface::METHOD_GET], 'allowed_methods' => [RequestMethodInterface::METHOD_GET],

View File

@@ -24,6 +24,7 @@ return (static function (): array {
'auto_resolve_titles' => (bool) EnvVars::AUTO_RESOLVE_TITLES->loadFromEnv(false), 'auto_resolve_titles' => (bool) EnvVars::AUTO_RESOLVE_TITLES->loadFromEnv(false),
'append_extra_path' => (bool) EnvVars::REDIRECT_APPEND_EXTRA_PATH->loadFromEnv(false), 'append_extra_path' => (bool) EnvVars::REDIRECT_APPEND_EXTRA_PATH->loadFromEnv(false),
'multi_segment_slugs_enabled' => (bool) EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->loadFromEnv(false), 'multi_segment_slugs_enabled' => (bool) EnvVars::MULTI_SEGMENT_SLUGS_ENABLED->loadFromEnv(false),
'trailing_slash_enabled' => (bool) EnvVars::SHORT_URL_TRAILING_SLASH->loadFromEnv(false),
], ],
]; ];

View File

@@ -18,6 +18,7 @@ return [
], ],
'auto_resolve_titles' => true, 'auto_resolve_titles' => true,
// 'multi_segment_slugs_enabled' => true, // 'multi_segment_slugs_enabled' => true,
// 'trailing_slash_enabled' => true,
], ],
]; ];

View File

@@ -8,7 +8,7 @@ use Doctrine\DBAL\Platforms\MySQLPlatform;
use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Types\Types; use Doctrine\DBAL\Types\Types;
use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\AbstractMigration;
use Shlinkio\Shlink\Core\Model\Visitor; use Shlinkio\Shlink\Core\Visit\Model\Visitor;
use Shlinkio\Shlink\Core\Visit\Model\VisitType; use Shlinkio\Shlink\Core\Visit\Model\VisitType;
final class Version20210207100807 extends AbstractMigration final class Version20210207100807 extends AbstractMigration

View File

@@ -1,24 +0,0 @@
{
"source": {
"directories": [
"module/*/src"
]
},
"timeout": 5,
"logs": {
"text": "build/infection-api/infection-log.txt",
"html": "build/infection-api/infection-log.html",
"summary": "build/infection-api/summary-log.txt",
"debug": "build/infection-api/debug-log.txt"
},
"tmpDir": "build/infection-api/temp",
"phpUnit": {
"configDir": "."
},
"testFrameworkOptions": "--configuration=phpunit-api.xml",
"mutators": {
"@default": true,
"IdenticalEqual": false,
"NotIdenticalNotEqual": false
}
}

24
infection-api.json5 Normal file
View File

@@ -0,0 +1,24 @@
{
source: {
directories: [
'module/*/src'
]
},
timeout: 5,
logs: {
text: 'build/infection-api/infection-log.txt',
html: 'build/infection-api/infection-log.html',
summary: 'build/infection-api/summary-log.txt',
debug: 'build/infection-api/debug-log.txt'
},
tmpDir: 'build/infection-api/temp',
phpUnit: {
configDir: '.'
},
testFrameworkOptions: '--configuration=phpunit-api.xml',
mutators: {
'@default': true,
IdenticalEqual: false,
NotIdenticalNotEqual: false
}
}

View File

@@ -1,24 +0,0 @@
{
"source": {
"directories": [
"module/*/src"
]
},
"timeout": 5,
"logs": {
"text": "build/infection-cli/infection-log.txt",
"html": "build/infection-cli/infection-log.html",
"summary": "build/infection-cli/summary-log.txt",
"debug": "build/infection-cli/debug-log.txt"
},
"tmpDir": "build/infection-cli/temp",
"phpUnit": {
"configDir": "."
},
"testFrameworkOptions": "--configuration=phpunit-cli.xml",
"mutators": {
"@default": true,
"IdenticalEqual": false,
"NotIdenticalNotEqual": false
}
}

24
infection-cli.json5 Normal file
View File

@@ -0,0 +1,24 @@
{
source: {
directories: [
'module/*/src'
]
},
timeout: 5,
logs: {
text: 'build/infection-cli/infection-log.txt',
html: 'build/infection-cli/infection-log.html',
summary: 'build/infection-cli/summary-log.txt',
debug: 'build/infection-cli/debug-log.txt'
},
tmpDir: 'build/infection-cli/temp',
phpUnit: {
configDir: '.'
},
testFrameworkOptions: '--configuration=phpunit-cli.xml',
mutators: {
'@default': true,
IdenticalEqual: false,
NotIdenticalNotEqual: false
}
}

View File

@@ -1,24 +0,0 @@
{
"source": {
"directories": [
"module/*/src"
]
},
"timeout": 5,
"logs": {
"text": "build/infection-db/infection-log.txt",
"html": "build/infection-db/infection-log.html",
"summary": "build/infection-db/summary-log.txt",
"debug": "build/infection-db/debug-log.txt"
},
"tmpDir": "build/infection-db/temp",
"phpUnit": {
"configDir": "."
},
"testFrameworkOptions": "--configuration=phpunit-db.xml",
"mutators": {
"@default": true,
"IdenticalEqual": false,
"NotIdenticalNotEqual": false
}
}

24
infection-db.json5 Normal file
View File

@@ -0,0 +1,24 @@
{
source: {
directories: [
'module/*/src'
]
},
timeout: 5,
logs: {
text: 'build/infection-db/infection-log.txt',
html: 'build/infection-db/infection-log.html',
summary: 'build/infection-db/summary-log.txt',
debug: 'build/infection-db/debug-log.txt'
},
tmpDir: 'build/infection-db/temp',
phpUnit: {
configDir: '.'
},
testFrameworkOptions: '--configuration=phpunit-db.xml',
mutators: {
'@default': true,
IdenticalEqual: false,
NotIdenticalNotEqual: false
}
}

View File

@@ -1,26 +0,0 @@
{
"source": {
"directories": [
"module/*/src"
]
},
"timeout": 5,
"logs": {
"text": "build/infection-unit/infection-log.txt",
"html": "build/infection-unit/infection-log.html",
"summary": "build/infection-unit/summary-log.txt",
"debug": "build/infection-unit/debug-log.txt",
"stryker": {
"report": "develop"
}
},
"tmpDir": "build/infection-unit/temp",
"phpUnit": {
"configDir": "."
},
"mutators": {
"@default": true,
"IdenticalEqual": false,
"NotIdenticalNotEqual": false
}
}

26
infection.json5 Normal file
View File

@@ -0,0 +1,26 @@
{
source: {
directories: [
'module/*/src'
]
},
timeout: 5,
logs: {
text: 'build/infection-unit/infection-log.txt',
html: 'build/infection-unit/infection-log.html',
summary: 'build/infection-unit/summary-log.txt',
debug: 'build/infection-unit/debug-log.txt',
stryker: {
report: 'develop'
}
},
tmpDir: 'build/infection-unit/temp',
phpUnit: {
configDir: '.'
},
mutators: {
'@default': true,
IdenticalEqual: false,
NotIdenticalNotEqual: false
}
}

View File

@@ -12,9 +12,8 @@ use Shlinkio\Shlink\Common\Doctrine\NoDbNameConnectionFactory;
use Shlinkio\Shlink\Core\Domain\DomainService; use Shlinkio\Shlink\Core\Domain\DomainService;
use Shlinkio\Shlink\Core\Options\TrackingOptions; use Shlinkio\Shlink\Core\Options\TrackingOptions;
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Core\Service; use Shlinkio\Shlink\Core\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformer;
use Shlinkio\Shlink\Core\Tag\TagService; use Shlinkio\Shlink\Core\Tag\TagService;
use Shlinkio\Shlink\Core\Visit; use Shlinkio\Shlink\Core\Visit;
use Shlinkio\Shlink\Installer\Factory\ProcessHelperFactory; use Shlinkio\Shlink\Installer\Factory\ProcessHelperFactory;
@@ -79,22 +78,22 @@ return [
ApiKey\RoleResolver::class => [DomainService::class, 'config.url_shortener.domain.hostname'], ApiKey\RoleResolver::class => [DomainService::class, 'config.url_shortener.domain.hostname'],
Command\ShortUrl\CreateShortUrlCommand::class => [ Command\ShortUrl\CreateShortUrlCommand::class => [
Service\UrlShortener::class, ShortUrl\UrlShortener::class,
ShortUrlStringifier::class, ShortUrlStringifier::class,
UrlShortenerOptions::class, UrlShortenerOptions::class,
], ],
Command\ShortUrl\ResolveUrlCommand::class => [Service\ShortUrl\ShortUrlResolver::class], Command\ShortUrl\ResolveUrlCommand::class => [ShortUrl\ShortUrlResolver::class],
Command\ShortUrl\ListShortUrlsCommand::class => [ Command\ShortUrl\ListShortUrlsCommand::class => [
Service\ShortUrlService::class, ShortUrl\ShortUrlService::class,
ShortUrlDataTransformer::class, ShortUrl\Transformer\ShortUrlDataTransformer::class,
], ],
Command\ShortUrl\GetShortUrlVisitsCommand::class => [Visit\VisitsStatsHelper::class], Command\ShortUrl\GetShortUrlVisitsCommand::class => [Visit\VisitsStatsHelper::class],
Command\ShortUrl\DeleteShortUrlCommand::class => [Service\ShortUrl\DeleteShortUrlService::class], Command\ShortUrl\DeleteShortUrlCommand::class => [ShortUrl\DeleteShortUrlService::class],
Command\Visit\DownloadGeoLiteDbCommand::class => [GeoLite\GeolocationDbUpdater::class], Command\Visit\DownloadGeoLiteDbCommand::class => [GeoLite\GeolocationDbUpdater::class],
Command\Visit\LocateVisitsCommand::class => [ Command\Visit\LocateVisitsCommand::class => [
Visit\VisitLocator::class, Visit\Geolocation\VisitLocator::class,
Visit\VisitToLocationHelper::class, Visit\Geolocation\VisitToLocationHelper::class,
LockFactory::class, LockFactory::class,
], ],
Command\Visit\GetOrphanVisitsCommand::class => [Visit\VisitsStatsHelper::class], Command\Visit\GetOrphanVisitsCommand::class => [Visit\VisitsStatsHelper::class],

View File

@@ -7,9 +7,9 @@ namespace Shlinkio\Shlink\CLI\Command\Domain;
use Shlinkio\Shlink\CLI\Command\Visit\AbstractVisitsListCommand; use Shlinkio\Shlink\CLI\Command\Visit\AbstractVisitsListCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Model\VisitsParams;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;

View File

@@ -8,11 +8,11 @@ use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Core\Config\EnvVars; use Shlinkio\Shlink\Core\Config\EnvVars;
use Shlinkio\Shlink\Core\Exception\InvalidUrlException; use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException; use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\Validation\ShortUrlInputFilter; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter;
use Shlinkio\Shlink\Core\ShortUrl\UrlShortenerInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@@ -162,7 +162,7 @@ class CreateShortUrlCommand extends Command
$doValidateUrl = $input->getOption('validate-url'); $doValidateUrl = $input->getOption('validate-url');
try { try {
$shortUrl = $this->urlShortener->shorten(ShortUrlMeta::fromRawData([ $shortUrl = $this->urlShortener->shorten(ShortUrlCreation::fromRawData([
ShortUrlInputFilter::LONG_URL => $longUrl, ShortUrlInputFilter::LONG_URL => $longUrl,
ShortUrlInputFilter::VALID_SINCE => $input->getOption('valid-since'), ShortUrlInputFilter::VALID_SINCE => $input->getOption('valid-since'),
ShortUrlInputFilter::VALID_UNTIL => $input->getOption('valid-until'), ShortUrlInputFilter::VALID_UNTIL => $input->getOption('valid-until'),

View File

@@ -6,8 +6,8 @@ namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Core\Exception; use Shlinkio\Shlink\Core\Exception;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\DeleteShortUrlServiceInterface;
use Shlinkio\Shlink\Core\Service\ShortUrl\DeleteShortUrlServiceInterface; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@@ -21,7 +21,7 @@ class DeleteShortUrlCommand extends Command
{ {
public const NAME = 'short-url:delete'; public const NAME = 'short-url:delete';
public function __construct(private DeleteShortUrlServiceInterface $deleteShortUrlService) public function __construct(private readonly DeleteShortUrlServiceInterface $deleteShortUrlService)
{ {
parent::__construct(); parent::__construct();
} }

View File

@@ -7,9 +7,9 @@ namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
use Shlinkio\Shlink\CLI\Command\Visit\AbstractVisitsListCommand; use Shlinkio\Shlink\CLI\Command\Visit\AbstractVisitsListCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Model\VisitsParams; use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;

View File

@@ -10,11 +10,11 @@ use Shlinkio\Shlink\CLI\Util\ShlinkTable;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait; use Shlinkio\Shlink\Common\Paginator\Util\PagerfantaUtilsTrait;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface; use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode;
use Shlinkio\Shlink\Core\Validation\ShortUrlsParamsInputFilter; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlsParamsInputFilter;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlServiceInterface;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;

View File

@@ -6,8 +6,8 @@ namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface; use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface;
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
@@ -21,7 +21,7 @@ class ResolveUrlCommand extends Command
{ {
public const NAME = 'short-url:parse'; public const NAME = 'short-url:parse';
public function __construct(private ShortUrlResolverInterface $urlResolver) public function __construct(private readonly ShortUrlResolverInterface $urlResolver)
{ {
parent::__construct(); parent::__construct();
} }

View File

@@ -7,9 +7,9 @@ namespace Shlinkio\Shlink\CLI\Command\Tag;
use Shlinkio\Shlink\CLI\Command\Visit\AbstractVisitsListCommand; use Shlinkio\Shlink\CLI\Command\Visit\AbstractVisitsListCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Model\VisitsParams;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;

View File

@@ -9,7 +9,7 @@ use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\CLI\Util\ShlinkTable; use Shlinkio\Shlink\CLI\Util\ShlinkTable;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;

View File

@@ -6,9 +6,9 @@ namespace Shlinkio\Shlink\CLI\Command\Visit;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Model\VisitsParams;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;

View File

@@ -6,8 +6,8 @@ namespace Shlinkio\Shlink\CLI\Command\Visit;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Model\VisitsParams; use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
class GetOrphanVisitsCommand extends AbstractVisitsListCommand class GetOrphanVisitsCommand extends AbstractVisitsListCommand

View File

@@ -8,13 +8,13 @@ use Shlinkio\Shlink\CLI\Command\Util\AbstractLockedCommand;
use Shlinkio\Shlink\CLI\Command\Util\LockedCommandConfig; use Shlinkio\Shlink\CLI\Command\Util\LockedCommandConfig;
use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Common\Util\IpAddress; use Shlinkio\Shlink\Common\Util\IpAddress;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Exception\IpCannotBeLocatedException; use Shlinkio\Shlink\Core\Exception\IpCannotBeLocatedException;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Visit\Geolocation\VisitGeolocationHelperInterface;
use Shlinkio\Shlink\Core\Visit\Geolocation\VisitLocatorInterface;
use Shlinkio\Shlink\Core\Visit\Geolocation\VisitToLocationHelperInterface;
use Shlinkio\Shlink\Core\Visit\Model\UnlocatableIpType; use Shlinkio\Shlink\Core\Visit\Model\UnlocatableIpType;
use Shlinkio\Shlink\Core\Visit\VisitGeolocationHelperInterface;
use Shlinkio\Shlink\Core\Visit\VisitLocatorInterface;
use Shlinkio\Shlink\Core\Visit\VisitToLocationHelperInterface;
use Shlinkio\Shlink\IpGeolocation\Model\Location; use Shlinkio\Shlink\IpGeolocation\Model\Location;
use Symfony\Component\Console\Exception\RuntimeException; use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Input\ArrayInput;

View File

@@ -10,7 +10,7 @@ use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\ApiKey\RoleResolver; use Shlinkio\Shlink\CLI\ApiKey\RoleResolver;
use Shlinkio\Shlink\CLI\Exception\InvalidRoleConfigException; use Shlinkio\Shlink\CLI\Exception\InvalidRoleConfigException;
use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface;
use Shlinkio\Shlink\Core\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition; use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;

View File

@@ -8,7 +8,7 @@ use Cake\Chronos\Chronos;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Api\ListKeysCommand; use Shlinkio\Shlink\CLI\Command\Api\ListKeysCommand;
use Shlinkio\Shlink\Core\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta; use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta;
use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition; use Shlinkio\Shlink\Rest\ApiKey\Model\RoleDefinition;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;

View File

@@ -9,8 +9,8 @@ use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Domain\DomainRedirectsCommand; use Shlinkio\Shlink\CLI\Command\Domain\DomainRedirectsCommand;
use Shlinkio\Shlink\Core\Config\NotFoundRedirects; use Shlinkio\Shlink\Core\Config\NotFoundRedirects;
use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface;
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Core\Domain\Model\DomainItem; use Shlinkio\Shlink\Core\Domain\Model\DomainItem;
use Shlinkio\Shlink\Core\Entity\Domain;
use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;

View File

@@ -10,11 +10,11 @@ use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Domain\GetDomainVisitsCommand; use Shlinkio\Shlink\CLI\Command\Domain\GetDomainVisitsCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Model\Visitor;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\IpGeolocation\Model\Location; use Shlinkio\Shlink\IpGeolocation\Model\Location;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;

View File

@@ -10,8 +10,8 @@ use Shlinkio\Shlink\CLI\Command\Domain\ListDomainsCommand;
use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Core\Config\NotFoundRedirects; use Shlinkio\Shlink\Core\Config\NotFoundRedirects;
use Shlinkio\Shlink\Core\Domain\DomainServiceInterface; use Shlinkio\Shlink\Core\Domain\DomainServiceInterface;
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Core\Domain\Model\DomainItem; use Shlinkio\Shlink\Core\Domain\Model\DomainItem;
use Shlinkio\Shlink\Core\Entity\Domain;
use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions; use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;

View File

@@ -10,13 +10,13 @@ use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\ShortUrl\CreateShortUrlCommand; use Shlinkio\Shlink\CLI\Command\ShortUrl\CreateShortUrlCommand;
use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Exception\InvalidUrlException; use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException; use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Core\Service\UrlShortener; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
use Shlinkio\Shlink\Core\ShortUrl\UrlShortener;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;
@@ -97,7 +97,7 @@ class CreateShortUrlCommandTest extends TestCase
{ {
$shortUrl = ShortUrl::createEmpty(); $shortUrl = ShortUrl::createEmpty();
$urlToShortCode = $this->urlShortener->shorten( $urlToShortCode = $this->urlShortener->shorten(
Argument::that(function (ShortUrlMeta $meta) { Argument::that(function (ShortUrlCreation $meta) {
$tags = $meta->getTags(); $tags = $meta->getTags();
Assert::assertEquals(['foo', 'bar', 'baz', 'boo', 'zar'], $tags); Assert::assertEquals(['foo', 'bar', 'baz', 'boo', 'zar'], $tags);
return true; return true;
@@ -124,7 +124,7 @@ class CreateShortUrlCommandTest extends TestCase
public function properlyProcessesProvidedDomain(array $input, ?string $expectedDomain): void public function properlyProcessesProvidedDomain(array $input, ?string $expectedDomain): void
{ {
$shorten = $this->urlShortener->shorten( $shorten = $this->urlShortener->shorten(
Argument::that(function (ShortUrlMeta $meta) use ($expectedDomain) { Argument::that(function (ShortUrlCreation $meta) use ($expectedDomain) {
Assert::assertEquals($expectedDomain, $meta->getDomain()); Assert::assertEquals($expectedDomain, $meta->getDomain());
return true; return true;
}), }),
@@ -153,7 +153,7 @@ class CreateShortUrlCommandTest extends TestCase
{ {
$shortUrl = ShortUrl::createEmpty(); $shortUrl = ShortUrl::createEmpty();
$urlToShortCode = $this->urlShortener->shorten( $urlToShortCode = $this->urlShortener->shorten(
Argument::that(function (ShortUrlMeta $meta) use ($expectedValidateUrl) { Argument::that(function (ShortUrlCreation $meta) use ($expectedValidateUrl) {
Assert::assertEquals($expectedValidateUrl, $meta->doValidateUrl()); Assert::assertEquals($expectedValidateUrl, $meta->doValidateUrl());
return $meta; return $meta;
}), }),

View File

@@ -9,8 +9,8 @@ use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\ShortUrl\DeleteShortUrlCommand; use Shlinkio\Shlink\CLI\Command\ShortUrl\DeleteShortUrlCommand;
use Shlinkio\Shlink\Core\Exception; use Shlinkio\Shlink\Core\Exception;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\DeleteShortUrlServiceInterface;
use Shlinkio\Shlink\Core\Service\ShortUrl\DeleteShortUrlServiceInterface; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;

View File

@@ -12,12 +12,12 @@ use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\ShortUrl\GetShortUrlVisitsCommand; use Shlinkio\Shlink\CLI\Command\ShortUrl\GetShortUrlVisitsCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Entity\VisitLocation; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\Visit\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Model\Visitor; use Shlinkio\Shlink\Core\Visit\Model\Visitor;
use Shlinkio\Shlink\Core\Model\VisitsParams; use Shlinkio\Shlink\Core\Visit\Model\VisitsParams;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\IpGeolocation\Model\Location; use Shlinkio\Shlink\IpGeolocation\Model\Location;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;

View File

@@ -11,12 +11,12 @@ use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\ShortUrl\ListShortUrlsCommand; use Shlinkio\Shlink\CLI\Command\ShortUrl\ListShortUrlsCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifier;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlServiceInterface;
use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformer; use Shlinkio\Shlink\Core\ShortUrl\Transformer\ShortUrlDataTransformer;
use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta; use Shlinkio\Shlink\Rest\ApiKey\Model\ApiKeyMeta;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
@@ -115,7 +115,7 @@ class ListShortUrlsCommandTest extends TestCase
): void { ): void {
$this->shortUrlService->listShortUrls(ShortUrlsParams::emptyInstance()) $this->shortUrlService->listShortUrls(ShortUrlsParams::emptyInstance())
->willReturn(new Paginator(new ArrayAdapter([ ->willReturn(new Paginator(new ArrayAdapter([
ShortUrl::fromMeta(ShortUrlMeta::fromRawData([ ShortUrl::fromMeta(ShortUrlCreation::fromRawData([
'longUrl' => 'foo.com', 'longUrl' => 'foo.com',
'tags' => ['foo', 'bar', 'baz'], 'tags' => ['foo', 'bar', 'baz'],
'apiKey' => $apiKey, 'apiKey' => $apiKey,

View File

@@ -7,10 +7,10 @@ namespace ShlinkioTest\Shlink\CLI\Command\ShortUrl;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\ShortUrl\ResolveUrlCommand; use Shlinkio\Shlink\CLI\Command\ShortUrl\ResolveUrlCommand;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;
use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Console\Tester\CommandTester;

View File

@@ -10,11 +10,11 @@ use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Tag\GetTagVisitsCommand; use Shlinkio\Shlink\CLI\Command\Tag\GetTagVisitsCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Model\Visitor;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\IpGeolocation\Model\Location; use Shlinkio\Shlink\IpGeolocation\Model\Location;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;

View File

@@ -7,8 +7,8 @@ namespace ShlinkioTest\Shlink\CLI\Command\Tag;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Tag\RenameTagCommand; use Shlinkio\Shlink\CLI\Command\Tag\RenameTagCommand;
use Shlinkio\Shlink\Core\Entity\Tag;
use Shlinkio\Shlink\Core\Exception\TagNotFoundException; use Shlinkio\Shlink\Core\Exception\TagNotFoundException;
use Shlinkio\Shlink\Core\Tag\Entity\Tag;
use Shlinkio\Shlink\Core\Tag\Model\TagRenaming; use Shlinkio\Shlink\Core\Tag\Model\TagRenaming;
use Shlinkio\Shlink\Core\Tag\TagServiceInterface; use Shlinkio\Shlink\Core\Tag\TagServiceInterface;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;

View File

@@ -10,11 +10,11 @@ use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Visit\GetNonOrphanVisitsCommand; use Shlinkio\Shlink\CLI\Command\Visit\GetNonOrphanVisitsCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Model\Visitor;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\IpGeolocation\Model\Location; use Shlinkio\Shlink\IpGeolocation\Model\Location;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;

View File

@@ -10,9 +10,9 @@ use Prophecy\Argument;
use Prophecy\Prophecy\ObjectProphecy; use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Visit\GetOrphanVisitsCommand; use Shlinkio\Shlink\CLI\Command\Visit\GetOrphanVisitsCommand;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation; use Shlinkio\Shlink\Core\Visit\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Model\Visitor; use Shlinkio\Shlink\Core\Visit\Model\Visitor;
use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface; use Shlinkio\Shlink\Core\Visit\VisitsStatsHelperInterface;
use Shlinkio\Shlink\IpGeolocation\Model\Location; use Shlinkio\Shlink\IpGeolocation\Model\Location;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;

View File

@@ -10,14 +10,14 @@ use Prophecy\Prophecy\ObjectProphecy;
use Shlinkio\Shlink\CLI\Command\Visit\DownloadGeoLiteDbCommand; use Shlinkio\Shlink\CLI\Command\Visit\DownloadGeoLiteDbCommand;
use Shlinkio\Shlink\CLI\Command\Visit\LocateVisitsCommand; use Shlinkio\Shlink\CLI\Command\Visit\LocateVisitsCommand;
use Shlinkio\Shlink\CLI\Util\ExitCodes; use Shlinkio\Shlink\CLI\Util\ExitCodes;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Exception\IpCannotBeLocatedException; use Shlinkio\Shlink\Core\Exception\IpCannotBeLocatedException;
use Shlinkio\Shlink\Core\Model\Visitor; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Visit\VisitGeolocationHelperInterface; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\VisitLocator; use Shlinkio\Shlink\Core\Visit\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Visit\VisitToLocationHelperInterface; use Shlinkio\Shlink\Core\Visit\Geolocation\VisitGeolocationHelperInterface;
use Shlinkio\Shlink\Core\Visit\Geolocation\VisitLocator;
use Shlinkio\Shlink\Core\Visit\Geolocation\VisitToLocationHelperInterface;
use Shlinkio\Shlink\Core\Visit\Model\Visitor;
use Shlinkio\Shlink\IpGeolocation\Exception\WrongIpException; use Shlinkio\Shlink\IpGeolocation\Exception\WrongIpException;
use Shlinkio\Shlink\IpGeolocation\Model\Location; use Shlinkio\Shlink\IpGeolocation\Model\Location;
use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait; use ShlinkioTest\Shlink\CLI\CliTestUtilsTrait;

View File

@@ -32,11 +32,18 @@ return [
Options\RabbitMqOptions::class => [ValinorConfigFactory::class, 'config.rabbitmq'], Options\RabbitMqOptions::class => [ValinorConfigFactory::class, 'config.rabbitmq'],
Options\WebhookOptions::class => ConfigAbstractFactory::class, Options\WebhookOptions::class => ConfigAbstractFactory::class,
Service\UrlShortener::class => ConfigAbstractFactory::class, ShortUrl\UrlShortener::class => ConfigAbstractFactory::class,
Service\ShortUrlService::class => ConfigAbstractFactory::class, ShortUrl\ShortUrlService::class => ConfigAbstractFactory::class,
Service\ShortUrl\DeleteShortUrlService::class => ConfigAbstractFactory::class, ShortUrl\DeleteShortUrlService::class => ConfigAbstractFactory::class,
Service\ShortUrl\ShortUrlResolver::class => ConfigAbstractFactory::class, ShortUrl\ShortUrlResolver::class => ConfigAbstractFactory::class,
Service\ShortUrl\ShortCodeUniquenessHelper::class => ConfigAbstractFactory::class, ShortUrl\Helper\ShortCodeUniquenessHelper::class => ConfigAbstractFactory::class,
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class => ConfigAbstractFactory::class,
ShortUrl\Helper\ShortUrlStringifier::class => ConfigAbstractFactory::class,
ShortUrl\Helper\ShortUrlTitleResolutionHelper::class => ConfigAbstractFactory::class,
ShortUrl\Helper\ShortUrlRedirectionBuilder::class => ConfigAbstractFactory::class,
ShortUrl\Transformer\ShortUrlDataTransformer::class => ConfigAbstractFactory::class,
ShortUrl\Middleware\ExtraPathRedirectMiddleware::class => ConfigAbstractFactory::class,
ShortUrl\Middleware\TrimTrailingSlashMiddleware::class => ConfigAbstractFactory::class,
Tag\TagService::class => ConfigAbstractFactory::class, Tag\TagService::class => ConfigAbstractFactory::class,
@@ -44,8 +51,8 @@ return [
Visit\VisitsTracker::class => ConfigAbstractFactory::class, Visit\VisitsTracker::class => ConfigAbstractFactory::class,
Visit\RequestTracker::class => ConfigAbstractFactory::class, Visit\RequestTracker::class => ConfigAbstractFactory::class,
Visit\VisitLocator::class => ConfigAbstractFactory::class, Visit\Geolocation\VisitLocator::class => ConfigAbstractFactory::class,
Visit\VisitToLocationHelper::class => ConfigAbstractFactory::class, Visit\Geolocation\VisitToLocationHelper::class => ConfigAbstractFactory::class,
Visit\VisitsStatsHelper::class => ConfigAbstractFactory::class, Visit\VisitsStatsHelper::class => ConfigAbstractFactory::class,
Visit\Transformer\OrphanVisitDataTransformer::class => InvokableFactory::class, Visit\Transformer\OrphanVisitDataTransformer::class => InvokableFactory::class,
@@ -60,13 +67,6 @@ return [
Action\QrCodeAction::class => ConfigAbstractFactory::class, Action\QrCodeAction::class => ConfigAbstractFactory::class,
Action\RobotsAction::class => ConfigAbstractFactory::class, Action\RobotsAction::class => ConfigAbstractFactory::class,
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class => ConfigAbstractFactory::class,
ShortUrl\Helper\ShortUrlStringifier::class => ConfigAbstractFactory::class,
ShortUrl\Helper\ShortUrlTitleResolutionHelper::class => ConfigAbstractFactory::class,
ShortUrl\Helper\ShortUrlRedirectionBuilder::class => ConfigAbstractFactory::class,
ShortUrl\Transformer\ShortUrlDataTransformer::class => ConfigAbstractFactory::class,
ShortUrl\Middleware\ExtraPathRedirectMiddleware::class => ConfigAbstractFactory::class,
EventDispatcher\PublishingUpdatesGenerator::class => ConfigAbstractFactory::class, EventDispatcher\PublishingUpdatesGenerator::class => ConfigAbstractFactory::class,
Importer\ImportedLinksProcessor::class => ConfigAbstractFactory::class, Importer\ImportedLinksProcessor::class => ConfigAbstractFactory::class,
@@ -90,11 +90,11 @@ return [
Options\WebhookOptions::class => ['config.visits_webhooks'], Options\WebhookOptions::class => ['config.visits_webhooks'],
Service\UrlShortener::class => [ ShortUrl\UrlShortener::class => [
ShortUrl\Helper\ShortUrlTitleResolutionHelper::class, ShortUrl\Helper\ShortUrlTitleResolutionHelper::class,
'em', 'em',
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class, ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class,
Service\ShortUrl\ShortCodeUniquenessHelper::class, ShortUrl\Helper\ShortCodeUniquenessHelper::class,
EventDispatcherInterface::class, EventDispatcherInterface::class,
], ],
Visit\VisitsTracker::class => [ Visit\VisitsTracker::class => [
@@ -103,23 +103,23 @@ return [
Options\TrackingOptions::class, Options\TrackingOptions::class,
], ],
Visit\RequestTracker::class => [Visit\VisitsTracker::class, Options\TrackingOptions::class], Visit\RequestTracker::class => [Visit\VisitsTracker::class, Options\TrackingOptions::class],
Service\ShortUrlService::class => [ ShortUrl\ShortUrlService::class => [
'em', 'em',
Service\ShortUrl\ShortUrlResolver::class, ShortUrl\ShortUrlResolver::class,
ShortUrl\Helper\ShortUrlTitleResolutionHelper::class, ShortUrl\Helper\ShortUrlTitleResolutionHelper::class,
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class, ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class,
], ],
Visit\VisitLocator::class => ['em'], Visit\Geolocation\VisitLocator::class => ['em'],
Visit\VisitToLocationHelper::class => [IpLocationResolverInterface::class], Visit\Geolocation\VisitToLocationHelper::class => [IpLocationResolverInterface::class],
Visit\VisitsStatsHelper::class => ['em'], Visit\VisitsStatsHelper::class => ['em'],
Tag\TagService::class => ['em'], Tag\TagService::class => ['em'],
Service\ShortUrl\DeleteShortUrlService::class => [ ShortUrl\DeleteShortUrlService::class => [
'em', 'em',
Options\DeleteShortUrlsOptions::class, Options\DeleteShortUrlsOptions::class,
Service\ShortUrl\ShortUrlResolver::class, ShortUrl\ShortUrlResolver::class,
], ],
Service\ShortUrl\ShortUrlResolver::class => ['em'], ShortUrl\ShortUrlResolver::class => ['em'],
Service\ShortUrl\ShortCodeUniquenessHelper::class => ['em'], ShortUrl\Helper\ShortCodeUniquenessHelper::class => ['em'],
Domain\DomainService::class => ['em', 'config.url_shortener.domain.hostname'], Domain\DomainService::class => ['em', 'config.url_shortener.domain.hostname'],
Util\UrlValidator::class => ['httpClient', Options\UrlShortenerOptions::class], Util\UrlValidator::class => ['httpClient', Options\UrlShortenerOptions::class],
@@ -129,14 +129,14 @@ return [
Config\NotFoundRedirectResolver::class => [Util\RedirectResponseHelper::class, 'Logger_Shlink'], Config\NotFoundRedirectResolver::class => [Util\RedirectResponseHelper::class, 'Logger_Shlink'],
Action\RedirectAction::class => [ Action\RedirectAction::class => [
Service\ShortUrl\ShortUrlResolver::class, ShortUrl\ShortUrlResolver::class,
Visit\RequestTracker::class, Visit\RequestTracker::class,
ShortUrl\Helper\ShortUrlRedirectionBuilder::class, ShortUrl\Helper\ShortUrlRedirectionBuilder::class,
Util\RedirectResponseHelper::class, Util\RedirectResponseHelper::class,
], ],
Action\PixelAction::class => [Service\ShortUrl\ShortUrlResolver::class, Visit\RequestTracker::class], Action\PixelAction::class => [ShortUrl\ShortUrlResolver::class, Visit\RequestTracker::class],
Action\QrCodeAction::class => [ Action\QrCodeAction::class => [
Service\ShortUrl\ShortUrlResolver::class, ShortUrl\ShortUrlResolver::class,
ShortUrl\Helper\ShortUrlStringifier::class, ShortUrl\Helper\ShortUrlStringifier::class,
'Logger_Shlink', 'Logger_Shlink',
Options\QrCodeOptions::class, Options\QrCodeOptions::class,
@@ -149,12 +149,13 @@ return [
ShortUrl\Helper\ShortUrlRedirectionBuilder::class => [Options\TrackingOptions::class], ShortUrl\Helper\ShortUrlRedirectionBuilder::class => [Options\TrackingOptions::class],
ShortUrl\Transformer\ShortUrlDataTransformer::class => [ShortUrl\Helper\ShortUrlStringifier::class], ShortUrl\Transformer\ShortUrlDataTransformer::class => [ShortUrl\Helper\ShortUrlStringifier::class],
ShortUrl\Middleware\ExtraPathRedirectMiddleware::class => [ ShortUrl\Middleware\ExtraPathRedirectMiddleware::class => [
Service\ShortUrl\ShortUrlResolver::class, ShortUrl\ShortUrlResolver::class,
Visit\RequestTracker::class, Visit\RequestTracker::class,
ShortUrl\Helper\ShortUrlRedirectionBuilder::class, ShortUrl\Helper\ShortUrlRedirectionBuilder::class,
Util\RedirectResponseHelper::class, Util\RedirectResponseHelper::class,
Options\UrlShortenerOptions::class, Options\UrlShortenerOptions::class,
], ],
ShortUrl\Middleware\TrimTrailingSlashMiddleware::class => [Options\UrlShortenerOptions::class],
EventDispatcher\PublishingUpdatesGenerator::class => [ EventDispatcher\PublishingUpdatesGenerator::class => [
ShortUrl\Transformer\ShortUrlDataTransformer::class, ShortUrl\Transformer\ShortUrlDataTransformer::class,
@@ -164,7 +165,7 @@ return [
Importer\ImportedLinksProcessor::class => [ Importer\ImportedLinksProcessor::class => [
'em', 'em',
ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class, ShortUrl\Resolver\PersistenceShortUrlRelationResolver::class,
Service\ShortUrl\ShortCodeUniquenessHelper::class, ShortUrl\Helper\ShortCodeUniquenessHelper::class,
Util\DoctrineBatchHelper::class, Util\DoctrineBatchHelper::class,
], ],

View File

@@ -14,7 +14,7 @@ return static function (ClassMetadata $metadata, array $emConfig): void {
$builder = new ClassMetadataBuilder($metadata); $builder = new ClassMetadataBuilder($metadata);
$builder->setTable(determineTableName('short_urls', $emConfig)) $builder->setTable(determineTableName('short_urls', $emConfig))
->setCustomRepositoryClass(Repository\ShortUrlRepository::class); ->setCustomRepositoryClass(ShortUrl\Repository\ShortUrlRepository::class);
$builder->createField('id', Types::BIGINT) $builder->createField('id', Types::BIGINT)
->columnName('id') ->columnName('id')
@@ -62,19 +62,19 @@ return static function (ClassMetadata $metadata, array $emConfig): void {
->nullable() ->nullable()
->build(); ->build();
$builder->createOneToMany('visits', Entity\Visit::class) $builder->createOneToMany('visits', Visit\Entity\Visit::class)
->mappedBy('shortUrl') ->mappedBy('shortUrl')
->fetchExtraLazy() ->fetchExtraLazy()
->build(); ->build();
$builder->createManyToMany('tags', Entity\Tag::class) $builder->createManyToMany('tags', Tag\Entity\Tag::class)
->setJoinTable(determineTableName('short_urls_in_tags', $emConfig)) ->setJoinTable(determineTableName('short_urls_in_tags', $emConfig))
->addInverseJoinColumn('tag_id', 'id', true, false, 'CASCADE') ->addInverseJoinColumn('tag_id', 'id', true, false, 'CASCADE')
->addJoinColumn('short_url_id', 'id', true, false, 'CASCADE') ->addJoinColumn('short_url_id', 'id', true, false, 'CASCADE')
->setOrderBy(['name' => 'ASC']) ->setOrderBy(['name' => 'ASC'])
->build(); ->build();
$builder->createManyToOne('domain', Entity\Domain::class) $builder->createManyToOne('domain', Domain\Entity\Domain::class)
->addJoinColumn('domain_id', 'id', true, false, 'RESTRICT') ->addJoinColumn('domain_id', 'id', true, false, 'RESTRICT')
->cascadePersist() ->cascadePersist()
->build(); ->build();

View File

@@ -12,7 +12,7 @@ return static function (ClassMetadata $metadata, array $emConfig): void {
$builder = new ClassMetadataBuilder($metadata); $builder = new ClassMetadataBuilder($metadata);
$builder->setTable(determineTableName('tags', $emConfig)) $builder->setTable(determineTableName('tags', $emConfig))
->setCustomRepositoryClass(Repository\TagRepository::class); ->setCustomRepositoryClass(Tag\Repository\TagRepository::class);
$builder->createField('id', Types::BIGINT) $builder->createField('id', Types::BIGINT)
->columnName('id') ->columnName('id')
@@ -25,5 +25,5 @@ return static function (ClassMetadata $metadata, array $emConfig): void {
->unique() ->unique()
->build(); ->build();
$builder->addInverseManyToMany('shortUrls', Entity\ShortUrl::class, 'tags'); $builder->addInverseManyToMany('shortUrls', ShortUrl\Entity\ShortUrl::class, 'tags');
}; };

View File

@@ -9,14 +9,14 @@ use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
use Doctrine\ORM\Mapping\Builder\FieldBuilder; use Doctrine\ORM\Mapping\Builder\FieldBuilder;
use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadata;
use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType; use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType;
use Shlinkio\Shlink\Core\Model\Visitor; use Shlinkio\Shlink\Core\Visit\Model\Visitor;
use Shlinkio\Shlink\Core\Visit\Model\VisitType; use Shlinkio\Shlink\Core\Visit\Model\VisitType;
return static function (ClassMetadata $metadata, array $emConfig): void { return static function (ClassMetadata $metadata, array $emConfig): void {
$builder = new ClassMetadataBuilder($metadata); $builder = new ClassMetadataBuilder($metadata);
$builder->setTable(determineTableName('visits', $emConfig)) $builder->setTable(determineTableName('visits', $emConfig))
->setCustomRepositoryClass(Repository\VisitRepository::class); ->setCustomRepositoryClass(Visit\Repository\VisitRepository::class);
$builder->createField('id', Types::BIGINT) $builder->createField('id', Types::BIGINT)
->columnName('id') ->columnName('id')
@@ -48,11 +48,11 @@ return static function (ClassMetadata $metadata, array $emConfig): void {
->nullable() ->nullable()
->build(); ->build();
$builder->createManyToOne('shortUrl', Entity\ShortUrl::class) $builder->createManyToOne('shortUrl', ShortUrl\Entity\ShortUrl::class)
->addJoinColumn('short_url_id', 'id', true, false, 'CASCADE') ->addJoinColumn('short_url_id', 'id', true, false, 'CASCADE')
->build(); ->build();
$builder->createManyToOne('visitLocation', Entity\VisitLocation::class) $builder->createManyToOne('visitLocation', Visit\Entity\VisitLocation::class)
->addJoinColumn('visit_location_id', 'id', true, false, 'Set NULL') ->addJoinColumn('visit_location_id', 'id', true, false, 'Set NULL')
->cascadePersist() ->cascadePersist()
->build(); ->build();

View File

@@ -10,8 +10,8 @@ use Shlinkio\Shlink\CLI\GeoLite\GeolocationDbUpdater;
use Shlinkio\Shlink\Common\Cache\RedisPublishingHelper; use Shlinkio\Shlink\Common\Cache\RedisPublishingHelper;
use Shlinkio\Shlink\Common\Mercure\MercureHubPublishingHelper; use Shlinkio\Shlink\Common\Mercure\MercureHubPublishingHelper;
use Shlinkio\Shlink\Common\RabbitMq\RabbitMqPublishingHelper; use Shlinkio\Shlink\Common\RabbitMq\RabbitMqPublishingHelper;
use Shlinkio\Shlink\Core\Visit\VisitLocator; use Shlinkio\Shlink\Core\Visit\Geolocation\VisitLocator;
use Shlinkio\Shlink\Core\Visit\VisitToLocationHelper; use Shlinkio\Shlink\Core\Visit\Geolocation\VisitToLocationHelper;
use Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater; use Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdater;
use Shlinkio\Shlink\IpGeolocation\Resolver\IpLocationResolverInterface; use Shlinkio\Shlink\IpGeolocation\Resolver\IpLocationResolverInterface;

View File

@@ -10,10 +10,10 @@ use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface;
use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface; use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface;
abstract class AbstractTrackingAction implements MiddlewareInterface, RequestMethodInterface abstract class AbstractTrackingAction implements MiddlewareInterface, RequestMethodInterface

View File

@@ -8,7 +8,7 @@ use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Common\Response\PixelResponse; use Shlinkio\Shlink\Common\Response\PixelResponse;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
class PixelAction extends AbstractTrackingAction class PixelAction extends AbstractTrackingAction
{ {

View File

@@ -13,10 +13,10 @@ use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Common\Response\QrCodeResponse; use Shlinkio\Shlink\Common\Response\QrCodeResponse;
use Shlinkio\Shlink\Core\Action\Model\QrCodeParams; use Shlinkio\Shlink\Core\Action\Model\QrCodeParams;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Options\QrCodeOptions; use Shlinkio\Shlink\Core\Options\QrCodeOptions;
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface;
class QrCodeAction implements MiddlewareInterface class QrCodeAction implements MiddlewareInterface
{ {

View File

@@ -7,9 +7,9 @@ namespace Shlinkio\Shlink\Core\Action;
use Fig\Http\Message\StatusCodeInterface; use Fig\Http\Message\StatusCodeInterface;
use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlRedirectionBuilderInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlRedirectionBuilderInterface;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface;
use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface; use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface;
use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface; use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface;

View File

@@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Crawling; namespace Shlinkio\Shlink\Core\Crawling;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface; use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlRepositoryInterface;
class CrawlingHelper implements CrawlingHelperInterface class CrawlingHelper implements CrawlingHelperInterface
{ {

View File

@@ -7,9 +7,9 @@ namespace Shlinkio\Shlink\Core\Domain;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Config\EmptyNotFoundRedirectConfig; use Shlinkio\Shlink\Core\Config\EmptyNotFoundRedirectConfig;
use Shlinkio\Shlink\Core\Config\NotFoundRedirects; use Shlinkio\Shlink\Core\Config\NotFoundRedirects;
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Core\Domain\Model\DomainItem; use Shlinkio\Shlink\Core\Domain\Model\DomainItem;
use Shlinkio\Shlink\Core\Domain\Repository\DomainRepositoryInterface; use Shlinkio\Shlink\Core\Domain\Repository\DomainRepositoryInterface;
use Shlinkio\Shlink\Core\Entity\Domain;
use Shlinkio\Shlink\Core\Exception\DomainNotFoundException; use Shlinkio\Shlink\Core\Exception\DomainNotFoundException;
use Shlinkio\Shlink\Rest\ApiKey\Role; use Shlinkio\Shlink\Rest\ApiKey\Role;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
@@ -20,7 +20,7 @@ use function Functional\map;
class DomainService implements DomainServiceInterface class DomainService implements DomainServiceInterface
{ {
public function __construct(private EntityManagerInterface $em, private string $defaultDomain) public function __construct(private readonly EntityManagerInterface $em, private readonly string $defaultDomain)
{ {
} }

View File

@@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Domain; namespace Shlinkio\Shlink\Core\Domain;
use Shlinkio\Shlink\Core\Config\NotFoundRedirects; use Shlinkio\Shlink\Core\Config\NotFoundRedirects;
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Core\Domain\Model\DomainItem; use Shlinkio\Shlink\Core\Domain\Model\DomainItem;
use Shlinkio\Shlink\Core\Entity\Domain;
use Shlinkio\Shlink\Core\Exception\DomainNotFoundException; use Shlinkio\Shlink\Core\Exception\DomainNotFoundException;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Entity; namespace Shlinkio\Shlink\Core\Domain\Entity;
use JsonSerializable; use JsonSerializable;
use Shlinkio\Shlink\Common\Entity\AbstractEntity; use Shlinkio\Shlink\Common\Entity\AbstractEntity;

View File

@@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Core\Domain\Model;
use JsonSerializable; use JsonSerializable;
use Shlinkio\Shlink\Core\Config\NotFoundRedirectConfigInterface; use Shlinkio\Shlink\Core\Config\NotFoundRedirectConfigInterface;
use Shlinkio\Shlink\Core\Config\NotFoundRedirects; use Shlinkio\Shlink\Core\Config\NotFoundRedirects;
use Shlinkio\Shlink\Core\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Entity\Domain;
final class DomainItem implements JsonSerializable final class DomainItem implements JsonSerializable
{ {

View File

@@ -7,9 +7,9 @@ namespace Shlinkio\Shlink\Core\Domain\Repository;
use Doctrine\ORM\Query\Expr\Join; use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository; use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Core\Domain\Spec\IsDomain; use Shlinkio\Shlink\Core\Domain\Spec\IsDomain;
use Shlinkio\Shlink\Core\Entity\Domain; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Spec\BelongsToApiKey; use Shlinkio\Shlink\Core\ShortUrl\Spec\BelongsToApiKey;
use Shlinkio\Shlink\Rest\ApiKey\Role; use Shlinkio\Shlink\Rest\ApiKey\Role;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;

View File

@@ -6,7 +6,7 @@ namespace Shlinkio\Shlink\Core\Domain\Repository;
use Doctrine\Persistence\ObjectRepository; use Doctrine\Persistence\ObjectRepository;
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface; use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface;
use Shlinkio\Shlink\Core\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
interface DomainRepositoryInterface extends ObjectRepository, EntitySpecificationRepositoryInterface interface DomainRepositoryInterface extends ObjectRepository, EntitySpecificationRepositoryInterface

View File

@@ -7,9 +7,9 @@ namespace Shlinkio\Shlink\Core\EventDispatcher\Async;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface; use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\EventDispatcher\Event\ShortUrlCreated; use Shlinkio\Shlink\Core\EventDispatcher\Event\ShortUrlCreated;
use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface; use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Throwable; use Throwable;
abstract class AbstractNotifyNewShortUrlListener extends AbstractAsyncListener abstract class AbstractNotifyNewShortUrlListener extends AbstractAsyncListener

View File

@@ -8,9 +8,9 @@ use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface; use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface;
use Shlinkio\Shlink\Common\UpdatePublishing\Update; use Shlinkio\Shlink\Common\UpdatePublishing\Update;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated; use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated;
use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface; use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Throwable; use Throwable;
use function Functional\each; use function Functional\each;

View File

@@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\EventDispatcher; namespace Shlinkio\Shlink\Core\EventDispatcher;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\EventDispatcher\Event\GeoLiteDbCreated; use Shlinkio\Shlink\Core\EventDispatcher\Event\GeoLiteDbCreated;
use Shlinkio\Shlink\Core\Exception\IpCannotBeLocatedException; use Shlinkio\Shlink\Core\Exception\IpCannotBeLocatedException;
use Shlinkio\Shlink\Core\Visit\VisitGeolocationHelperInterface; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\VisitLocatorInterface; use Shlinkio\Shlink\Core\Visit\Entity\VisitLocation;
use Shlinkio\Shlink\Core\Visit\VisitToLocationHelperInterface; use Shlinkio\Shlink\Core\Visit\Geolocation\VisitGeolocationHelperInterface;
use Shlinkio\Shlink\Core\Visit\Geolocation\VisitLocatorInterface;
use Shlinkio\Shlink\Core\Visit\Geolocation\VisitToLocationHelperInterface;
use Shlinkio\Shlink\IpGeolocation\Model\Location; use Shlinkio\Shlink\IpGeolocation\Model\Location;
class LocateUnlocatedVisits implements VisitGeolocationHelperInterface class LocateUnlocatedVisits implements VisitGeolocationHelperInterface

View File

@@ -7,10 +7,10 @@ namespace Shlinkio\Shlink\Core\EventDispatcher;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Psr\EventDispatcher\EventDispatcherInterface; use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\Entity\VisitLocation;
use Shlinkio\Shlink\Core\EventDispatcher\Event\UrlVisited; use Shlinkio\Shlink\Core\EventDispatcher\Event\UrlVisited;
use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated; use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Entity\VisitLocation;
use Shlinkio\Shlink\IpGeolocation\Exception\WrongIpException; use Shlinkio\Shlink\IpGeolocation\Exception\WrongIpException;
use Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdaterInterface; use Shlinkio\Shlink\IpGeolocation\GeoLite2\DbUpdaterInterface;
use Shlinkio\Shlink\IpGeolocation\Model\Location; use Shlinkio\Shlink\IpGeolocation\Model\Location;

View File

@@ -13,10 +13,10 @@ use GuzzleHttp\Promise\Utils;
use GuzzleHttp\RequestOptions; use GuzzleHttp\RequestOptions;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface; use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated; use Shlinkio\Shlink\Core\EventDispatcher\Event\VisitLocated;
use Shlinkio\Shlink\Core\Options\AppOptions; use Shlinkio\Shlink\Core\Options\AppOptions;
use Shlinkio\Shlink\Core\Options\WebhookOptions; use Shlinkio\Shlink\Core\Options\WebhookOptions;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Throwable; use Throwable;
use function Functional\map; use function Functional\map;

View File

@@ -6,8 +6,8 @@ namespace Shlinkio\Shlink\Core\EventDispatcher;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface; use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Common\UpdatePublishing\Update; use Shlinkio\Shlink\Common\UpdatePublishing\Update;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
final class PublishingUpdatesGenerator implements PublishingUpdatesGeneratorInterface final class PublishingUpdatesGenerator implements PublishingUpdatesGeneratorInterface
{ {

View File

@@ -5,8 +5,8 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\EventDispatcher; namespace Shlinkio\Shlink\Core\EventDispatcher;
use Shlinkio\Shlink\Common\UpdatePublishing\Update; use Shlinkio\Shlink\Common\UpdatePublishing\Update;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
interface PublishingUpdatesGeneratorInterface interface PublishingUpdatesGeneratorInterface
{ {

View File

@@ -9,12 +9,12 @@ use Psr\Log\LoggerInterface;
use Shlinkio\Shlink\Common\Rest\DataTransformerInterface; use Shlinkio\Shlink\Common\Rest\DataTransformerInterface;
use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface; use Shlinkio\Shlink\Common\UpdatePublishing\PublishingHelperInterface;
use Shlinkio\Shlink\Common\UpdatePublishing\Update; use Shlinkio\Shlink\Common\UpdatePublishing\Update;
use Shlinkio\Shlink\Core\Entity\Visit;
use Shlinkio\Shlink\Core\EventDispatcher\Async\AbstractNotifyVisitListener; use Shlinkio\Shlink\Core\EventDispatcher\Async\AbstractNotifyVisitListener;
use Shlinkio\Shlink\Core\EventDispatcher\Async\RemoteSystem; use Shlinkio\Shlink\Core\EventDispatcher\Async\RemoteSystem;
use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface; use Shlinkio\Shlink\Core\EventDispatcher\PublishingUpdatesGeneratorInterface;
use Shlinkio\Shlink\Core\EventDispatcher\Topic; use Shlinkio\Shlink\Core\EventDispatcher\Topic;
use Shlinkio\Shlink\Core\Options\RabbitMqOptions; use Shlinkio\Shlink\Core\Options\RabbitMqOptions;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
class NotifyVisitToRabbitMq extends AbstractNotifyVisitListener class NotifyVisitToRabbitMq extends AbstractNotifyVisitListener
{ {

View File

@@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Core\Exception;
use Fig\Http\Message\StatusCodeInterface; use Fig\Http\Message\StatusCodeInterface;
use Mezzio\ProblemDetails\Exception\CommonProblemDetailsExceptionTrait; use Mezzio\ProblemDetails\Exception\CommonProblemDetailsExceptionTrait;
use Mezzio\ProblemDetails\Exception\ProblemDetailsExceptionInterface; use Mezzio\ProblemDetails\Exception\ProblemDetailsExceptionInterface;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use function Shlinkio\Shlink\Core\toProblemDetailsType; use function Shlinkio\Shlink\Core\toProblemDetailsType;
use function sprintf; use function sprintf;

View File

@@ -7,7 +7,7 @@ namespace Shlinkio\Shlink\Core\Exception;
use Fig\Http\Message\StatusCodeInterface; use Fig\Http\Message\StatusCodeInterface;
use Mezzio\ProblemDetails\Exception\CommonProblemDetailsExceptionTrait; use Mezzio\ProblemDetails\Exception\CommonProblemDetailsExceptionTrait;
use Mezzio\ProblemDetails\Exception\ProblemDetailsExceptionInterface; use Mezzio\ProblemDetails\Exception\ProblemDetailsExceptionInterface;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use function Shlinkio\Shlink\Core\toProblemDetailsType; use function Shlinkio\Shlink\Core\toProblemDetailsType;
use function sprintf; use function sprintf;

View File

@@ -5,10 +5,10 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Importer; namespace Shlinkio\Shlink\Core\Importer;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException; use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortCodeUniquenessHelperInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortCodeUniquenessHelperInterface;
use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlRepositoryInterface;
use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface; use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface;
use Shlinkio\Shlink\Core\Util\DoctrineBatchHelperInterface; use Shlinkio\Shlink\Core\Util\DoctrineBatchHelperInterface;
use Shlinkio\Shlink\Importer\ImportedLinksProcessorInterface; use Shlinkio\Shlink\Importer\ImportedLinksProcessorInterface;

View File

@@ -6,8 +6,8 @@ namespace Shlinkio\Shlink\Core\Importer;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Entity\Visit; use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Importer\Model\ImportedShlinkVisit; use Shlinkio\Shlink\Importer\Model\ImportedShlinkVisit;
use function sprintf; use function sprintf;

View File

@@ -15,6 +15,7 @@ final class UrlShortenerOptions
public readonly bool $autoResolveTitles = false, public readonly bool $autoResolveTitles = false,
public readonly bool $appendExtraPath = false, public readonly bool $appendExtraPath = false,
public readonly bool $multiSegmentSlugsEnabled = false, public readonly bool $multiSegmentSlugsEnabled = false,
public readonly bool $trailingSlashEnabled = false,
) { ) {
} }
} }

View File

@@ -2,21 +2,21 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Service\ShortUrl; namespace Shlinkio\Shlink\Core\ShortUrl;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Exception; use Shlinkio\Shlink\Core\Exception;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Options\DeleteShortUrlsOptions; use Shlinkio\Shlink\Core\Options\DeleteShortUrlsOptions;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
class DeleteShortUrlService implements DeleteShortUrlServiceInterface class DeleteShortUrlService implements DeleteShortUrlServiceInterface
{ {
public function __construct( public function __construct(
private EntityManagerInterface $em, private readonly EntityManagerInterface $em,
private DeleteShortUrlsOptions $deleteShortUrlsOptions, private readonly DeleteShortUrlsOptions $deleteShortUrlsOptions,
private ShortUrlResolverInterface $urlResolver, private readonly ShortUrlResolverInterface $urlResolver,
) { ) {
} }

View File

@@ -2,10 +2,10 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Service\ShortUrl; namespace Shlinkio\Shlink\Core\ShortUrl;
use Shlinkio\Shlink\Core\Exception; use Shlinkio\Shlink\Core\Exception;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
interface DeleteShortUrlServiceInterface interface DeleteShortUrlServiceInterface

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Entity; namespace Shlinkio\Shlink\Core\ShortUrl\Entity;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
@@ -10,12 +10,15 @@ use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\Criteria; use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Selectable; use Doctrine\Common\Collections\Selectable;
use Shlinkio\Shlink\Common\Entity\AbstractEntity; use Shlinkio\Shlink\Common\Entity\AbstractEntity;
use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Core\Exception\ShortCodeCannotBeRegeneratedException; use Shlinkio\Shlink\Core\Exception\ShortCodeCannotBeRegeneratedException;
use Shlinkio\Shlink\Core\Model\ShortUrlEdit; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlEdition;
use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter;
use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface; use Shlinkio\Shlink\Core\ShortUrl\Resolver\ShortUrlRelationResolverInterface;
use Shlinkio\Shlink\Core\ShortUrl\Resolver\SimpleShortUrlRelationResolver; use Shlinkio\Shlink\Core\ShortUrl\Resolver\SimpleShortUrlRelationResolver;
use Shlinkio\Shlink\Core\Validation\ShortUrlInputFilter; use Shlinkio\Shlink\Core\Tag\Entity\Tag;
use Shlinkio\Shlink\Core\Visit\Entity\Visit;
use Shlinkio\Shlink\Core\Visit\Model\VisitType; use Shlinkio\Shlink\Core\Visit\Model\VisitType;
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl; use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
@@ -52,16 +55,16 @@ class ShortUrl extends AbstractEntity
public static function createEmpty(): self public static function createEmpty(): self
{ {
return self::fromMeta(ShortUrlMeta::createEmpty()); return self::fromMeta(ShortUrlCreation::createEmpty());
} }
public static function withLongUrl(string $longUrl): self public static function withLongUrl(string $longUrl): self
{ {
return self::fromMeta(ShortUrlMeta::fromRawData([ShortUrlInputFilter::LONG_URL => $longUrl])); return self::fromMeta(ShortUrlCreation::fromRawData([ShortUrlInputFilter::LONG_URL => $longUrl]));
} }
public static function fromMeta( public static function fromMeta(
ShortUrlMeta $meta, ShortUrlCreation $meta,
?ShortUrlRelationResolverInterface $relationResolver = null, ?ShortUrlRelationResolverInterface $relationResolver = null,
): self { ): self {
$instance = new self(); $instance = new self();
@@ -104,7 +107,7 @@ class ShortUrl extends AbstractEntity
$meta[ShortUrlInputFilter::CUSTOM_SLUG] = $url->shortCode; $meta[ShortUrlInputFilter::CUSTOM_SLUG] = $url->shortCode;
} }
$instance = self::fromMeta(ShortUrlMeta::fromRawData($meta), $relationResolver); $instance = self::fromMeta(ShortUrlCreation::fromRawData($meta), $relationResolver);
$validSince = $url->meta->validSince; $validSince = $url->meta->validSince;
if ($validSince !== null) { if ($validSince !== null) {
@@ -216,7 +219,7 @@ class ShortUrl extends AbstractEntity
} }
public function update( public function update(
ShortUrlEdit $shortUrlEdit, ShortUrlEdition $shortUrlEdit,
?ShortUrlRelationResolverInterface $relationResolver = null, ?ShortUrlRelationResolverInterface $relationResolver = null,
): void { ): void {
if ($shortUrlEdit->validSinceWasProvided()) { if ($shortUrlEdit->validSinceWasProvided()) {

View File

@@ -2,16 +2,16 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Service\ShortUrl; namespace Shlinkio\Shlink\Core\ShortUrl\Helper;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepository; use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlRepository;
class ShortCodeUniquenessHelper implements ShortCodeUniquenessHelperInterface class ShortCodeUniquenessHelper implements ShortCodeUniquenessHelperInterface
{ {
public function __construct(private EntityManagerInterface $em) public function __construct(private readonly EntityManagerInterface $em)
{ {
} }

View File

@@ -2,9 +2,9 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Service\ShortUrl; namespace Shlinkio\Shlink\Core\ShortUrl\Helper;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
interface ShortCodeUniquenessHelperInterface interface ShortCodeUniquenessHelperInterface
{ {

View File

@@ -7,8 +7,8 @@ namespace Shlinkio\Shlink\Core\ShortUrl\Helper;
use GuzzleHttp\Psr7\Query; use GuzzleHttp\Psr7\Query;
use Laminas\Stdlib\ArrayUtils; use Laminas\Stdlib\ArrayUtils;
use League\Uri\Uri; use League\Uri\Uri;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Options\TrackingOptions; use Shlinkio\Shlink\Core\Options\TrackingOptions;
use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use function sprintf; use function sprintf;

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Helper; namespace Shlinkio\Shlink\Core\ShortUrl\Helper;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
interface ShortUrlRedirectionBuilderInterface interface ShortUrlRedirectionBuilderInterface
{ {

View File

@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Helper; namespace Shlinkio\Shlink\Core\ShortUrl\Helper;
use Laminas\Diactoros\Uri; use Laminas\Diactoros\Uri;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use function sprintf; use function sprintf;

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Helper; namespace Shlinkio\Shlink\Core\ShortUrl\Helper;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
interface ShortUrlStringifierInterface interface ShortUrlStringifierInterface
{ {

View File

@@ -11,10 +11,10 @@ use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType; use Shlinkio\Shlink\Core\ErrorHandler\Model\NotFoundType;
use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException; use Shlinkio\Shlink\Core\Exception\ShortUrlNotFoundException;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlRedirectionBuilderInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlRedirectionBuilderInterface;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\ShortUrl\ShortUrlResolverInterface;
use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface; use Shlinkio\Shlink\Core\Util\RedirectResponseHelperInterface;
use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface; use Shlinkio\Shlink\Core\Visit\RequestTrackerInterface;

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Middleware;
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 function rtrim;
class TrimTrailingSlashMiddleware implements MiddlewareInterface
{
private const SHORT_CODE_ATTR = 'shortCode';
public function __construct(private readonly UrlShortenerOptions $options)
{
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
return $handler->handle($this->resolveRequest($request));
}
private function resolveRequest(ServerRequestInterface $request): ServerRequestInterface
{
// If multi-segment slugs are enabled together with trailing slashes, the "shortCode" attribute will include
// ending slashes that we need to trim for a proper short code matching
/** @var string|null $shortCode */
$shortCode = $request->getAttribute(self::SHORT_CODE_ATTR);
$shouldTrimSlash = $shortCode !== null && $this->options->trailingSlashEnabled;
return $shouldTrimSlash ? $request->withAttribute(self::SHORT_CODE_ATTR, rtrim($shortCode, '/')) : $request;
}
}

View File

@@ -2,12 +2,12 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Model; namespace Shlinkio\Shlink\Core\ShortUrl\Model;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Shlinkio\Shlink\Core\Exception\ValidationException; use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\ShortUrl\Helper\TitleResolutionModelInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\TitleResolutionModelInterface;
use Shlinkio\Shlink\Core\Validation\ShortUrlInputFilter; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
use function Shlinkio\Shlink\Core\getOptionalBoolFromInputFilter; use function Shlinkio\Shlink\Core\getOptionalBoolFromInputFilter;
@@ -16,8 +16,7 @@ use function Shlinkio\Shlink\Core\normalizeDate;
use const Shlinkio\Shlink\DEFAULT_SHORT_CODES_LENGTH; use const Shlinkio\Shlink\DEFAULT_SHORT_CODES_LENGTH;
// TODO Rename to ShortUrlCreation final class ShortUrlCreation implements TitleResolutionModelInterface
final class ShortUrlMeta implements TitleResolutionModelInterface
{ {
private string $longUrl; private string $longUrl;
private ?Chronos $validSince = null; private ?Chronos $validSince = null;

View File

@@ -2,20 +2,19 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Model; namespace Shlinkio\Shlink\Core\ShortUrl\Model;
use Cake\Chronos\Chronos; use Cake\Chronos\Chronos;
use Shlinkio\Shlink\Core\Exception\ValidationException; use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\ShortUrl\Helper\TitleResolutionModelInterface; use Shlinkio\Shlink\Core\ShortUrl\Helper\TitleResolutionModelInterface;
use Shlinkio\Shlink\Core\Validation\ShortUrlInputFilter; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlInputFilter;
use function array_key_exists; use function array_key_exists;
use function Shlinkio\Shlink\Core\getOptionalBoolFromInputFilter; use function Shlinkio\Shlink\Core\getOptionalBoolFromInputFilter;
use function Shlinkio\Shlink\Core\getOptionalIntFromInputFilter; use function Shlinkio\Shlink\Core\getOptionalIntFromInputFilter;
use function Shlinkio\Shlink\Core\normalizeDate; use function Shlinkio\Shlink\Core\normalizeDate;
// TODO Rename to ShortUrlEdition final class ShortUrlEdition implements TitleResolutionModelInterface
final class ShortUrlEdit implements TitleResolutionModelInterface
{ {
private bool $longUrlPropWasProvided = false; private bool $longUrlPropWasProvided = false;
private ?string $longUrl = null; private ?string $longUrl = null;

View File

@@ -2,10 +2,10 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Model; namespace Shlinkio\Shlink\Core\ShortUrl\Model;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
final class ShortUrlIdentifier final class ShortUrlIdentifier

View File

@@ -2,12 +2,12 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Model; namespace Shlinkio\Shlink\Core\ShortUrl\Model;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Exception\ValidationException; use Shlinkio\Shlink\Core\Exception\ValidationException;
use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\Model\Ordering;
use Shlinkio\Shlink\Core\Validation\ShortUrlsParamsInputFilter; use Shlinkio\Shlink\Core\ShortUrl\Model\Validation\ShortUrlsParamsInputFilter;
use function Shlinkio\Shlink\Common\buildDateRange; use function Shlinkio\Shlink\Common\buildDateRange;
use function Shlinkio\Shlink\Core\normalizeDate; use function Shlinkio\Shlink\Core\normalizeDate;

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Validation; namespace Shlinkio\Shlink\Core\ShortUrl\Model\Validation;
use DateTime; use DateTime;
use Laminas\Filter; use Laminas\Filter;

View File

@@ -2,13 +2,13 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Validation; namespace Shlinkio\Shlink\Core\ShortUrl\Model\Validation;
use Laminas\InputFilter\InputFilter; use Laminas\InputFilter\InputFilter;
use Laminas\Validator\InArray; use Laminas\Validator\InArray;
use Shlinkio\Shlink\Common\Paginator\Paginator; use Shlinkio\Shlink\Common\Paginator\Paginator;
use Shlinkio\Shlink\Common\Validation; use Shlinkio\Shlink\Common\Validation;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode;
class ShortUrlsParamsInputFilter extends InputFilter class ShortUrlsParamsInputFilter extends InputFilter

View File

@@ -5,10 +5,10 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Paginator\Adapter; namespace Shlinkio\Shlink\Core\ShortUrl\Paginator\Adapter;
use Pagerfanta\Adapter\AdapterInterface; use Pagerfanta\Adapter\AdapterInterface;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\Repository\ShortUrlRepositoryInterface;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Repository\ShortUrlRepositoryInterface;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
class ShortUrlRepositoryAdapter implements AdapterInterface class ShortUrlRepositoryAdapter implements AdapterInterface

View File

@@ -5,7 +5,7 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ShortUrl\Persistence; namespace Shlinkio\Shlink\Core\ShortUrl\Persistence;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;

View File

@@ -6,7 +6,7 @@ namespace Shlinkio\Shlink\Core\ShortUrl\Persistence;
use Shlinkio\Shlink\Common\Util\DateRange; use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Model\Ordering; use Shlinkio\Shlink\Core\Model\Ordering;
use Shlinkio\Shlink\Core\Model\ShortUrlsParams; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlsParams;
use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;

View File

@@ -2,7 +2,7 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Repository; namespace Shlinkio\Shlink\Core\ShortUrl\Repository;
use Doctrine\DBAL\LockMode; use Doctrine\DBAL\LockMode;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform; use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
@@ -11,10 +11,10 @@ use Doctrine\ORM\QueryBuilder;
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository; use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository;
use Happyr\DoctrineSpecification\Specification\Specification; use Happyr\DoctrineSpecification\Specification\Specification;
use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType; use Shlinkio\Shlink\Common\Doctrine\Type\ChronosDateTimeType;
use Shlinkio\Shlink\Core\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\Ordering; use Shlinkio\Shlink\Core\Model\Ordering;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering;
@@ -143,7 +143,7 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
$dql = <<<DQL $dql = <<<DQL
SELECT s SELECT s
FROM Shlinkio\Shlink\Core\Entity\ShortUrl AS s FROM Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl AS s
LEFT JOIN s.domain AS d LEFT JOIN s.domain AS d
WHERE s.shortCode = :shortCode WHERE s.shortCode = :shortCode
AND (s.domain IS NULL OR d.authority = :domain) AND (s.domain IS NULL OR d.authority = :domain)
@@ -215,7 +215,7 @@ class ShortUrlRepository extends EntitySpecificationRepository implements ShortU
return $qb; return $qb;
} }
public function findOneMatching(ShortUrlMeta $meta): ?ShortUrl public function findOneMatching(ShortUrlCreation $meta): ?ShortUrl
{ {
$qb = $this->getEntityManager()->createQueryBuilder(); $qb = $this->getEntityManager()->createQueryBuilder();

View File

@@ -2,14 +2,14 @@
declare(strict_types=1); declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Repository; namespace Shlinkio\Shlink\Core\ShortUrl\Repository;
use Doctrine\Persistence\ObjectRepository; use Doctrine\Persistence\ObjectRepository;
use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface; use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepositoryInterface;
use Happyr\DoctrineSpecification\Specification\Specification; use Happyr\DoctrineSpecification\Specification\Specification;
use Shlinkio\Shlink\Core\Entity\ShortUrl; use Shlinkio\Shlink\Core\ShortUrl\Entity\ShortUrl;
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlCreation;
use Shlinkio\Shlink\Core\Model\ShortUrlMeta; use Shlinkio\Shlink\Core\ShortUrl\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsCountFiltering;
use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering; use Shlinkio\Shlink\Core\ShortUrl\Persistence\ShortUrlsListFiltering;
use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl; use Shlinkio\Shlink\Importer\Model\ImportedShlinkUrl;
@@ -28,7 +28,7 @@ interface ShortUrlRepositoryInterface extends ObjectRepository, EntitySpecificat
public function shortCodeIsInUseWithLock(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool; public function shortCodeIsInUseWithLock(ShortUrlIdentifier $identifier, ?Specification $spec = null): bool;
public function findOneMatching(ShortUrlMeta $meta): ?ShortUrl; public function findOneMatching(ShortUrlCreation $meta): ?ShortUrl;
public function findOneByImportedUrl(ImportedShlinkUrl $url): ?ShortUrl; public function findOneByImportedUrl(ImportedShlinkUrl $url): ?ShortUrl;

View File

@@ -8,8 +8,8 @@ use Doctrine\Common\Collections;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Events; use Doctrine\ORM\Events;
use Shlinkio\Shlink\Core\Entity\Domain; use Shlinkio\Shlink\Core\Domain\Entity\Domain;
use Shlinkio\Shlink\Core\Entity\Tag; use Shlinkio\Shlink\Core\Tag\Entity\Tag;
use function Functional\map; use function Functional\map;
use function Functional\unique; use function Functional\unique;

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