Update to latest shlink-common

This commit is contained in:
Alejandro Celaya 2024-02-21 17:57:45 +01:00
parent 0e78deb8f2
commit 467dbdd183
5 changed files with 40 additions and 41 deletions

View File

@ -42,7 +42,7 @@
"pugx/shortid-php": "^1.1", "pugx/shortid-php": "^1.1",
"ramsey/uuid": "^4.7", "ramsey/uuid": "^4.7",
"shlinkio/doctrine-specification": "^2.1.1", "shlinkio/doctrine-specification": "^2.1.1",
"shlinkio/shlink-common": "dev-main#b9a6bd5 as 6.0", "shlinkio/shlink-common": "dev-main#3e5bf59 as 6.0",
"shlinkio/shlink-config": "dev-main#a43b380 as 3.0", "shlinkio/shlink-config": "dev-main#a43b380 as 3.0",
"shlinkio/shlink-event-dispatcher": "dev-main#aa9023c as 4.0", "shlinkio/shlink-event-dispatcher": "dev-main#aa9023c as 4.0",
"shlinkio/shlink-importer": "dev-main#65a9a30 as 5.3", "shlinkio/shlink-importer": "dev-main#65a9a30 as 5.3",

View File

@ -4,6 +4,7 @@ declare(strict_types=1);
use GuzzleHttp\Client; use GuzzleHttp\Client;
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory; use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
use Laminas\ServiceManager\Factory\InvokableFactory;
use Mezzio\Application; use Mezzio\Application;
use Mezzio\Container; use Mezzio\Container;
use Psr\Http\Client\ClientInterface; use Psr\Http\Client\ClientInterface;
@ -12,12 +13,14 @@ use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileFactoryInterface; use Psr\Http\Message\UploadedFileFactoryInterface;
use Spiral\RoadRunner\Http\PSR7Worker; use Spiral\RoadRunner\Http\PSR7Worker;
use Spiral\RoadRunner\WorkerInterface; use Spiral\RoadRunner\WorkerInterface;
use Symfony\Component\Filesystem\Filesystem;
return [ return [
'dependencies' => [ 'dependencies' => [
'factories' => [ 'factories' => [
PSR7Worker::class => ConfigAbstractFactory::class, PSR7Worker::class => ConfigAbstractFactory::class,
Filesystem::class => InvokableFactory::class,
], ],
'delegators' => [ 'delegators' => [

View File

@ -5,12 +5,11 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Domain\Validation; namespace Shlinkio\Shlink\Core\Domain\Validation;
use Laminas\InputFilter\InputFilter; use Laminas\InputFilter\InputFilter;
use Shlinkio\Shlink\Common\Validation; use Shlinkio\Shlink\Common\Validation\HostAndPortValidator;
use Shlinkio\Shlink\Common\Validation\InputFactory;
class DomainRedirectsInputFilter extends InputFilter class DomainRedirectsInputFilter extends InputFilter
{ {
use Validation\InputFactoryTrait;
public const DOMAIN = 'domain'; public const DOMAIN = 'domain';
public const BASE_URL_REDIRECT = 'baseUrlRedirect'; public const BASE_URL_REDIRECT = 'baseUrlRedirect';
public const REGULAR_404_REDIRECT = 'regular404Redirect'; public const REGULAR_404_REDIRECT = 'regular404Redirect';
@ -32,12 +31,12 @@ class DomainRedirectsInputFilter extends InputFilter
private function initializeInputs(): void private function initializeInputs(): void
{ {
$domain = $this->createInput(self::DOMAIN); $domain = InputFactory::basic(self::DOMAIN, required: true);
$domain->getValidatorChain()->attach(new Validation\HostAndPortValidator()); $domain->getValidatorChain()->attach(new HostAndPortValidator());
$this->add($domain); $this->add($domain);
$this->add($this->createInput(self::BASE_URL_REDIRECT, false)); $this->add(InputFactory::basic(self::BASE_URL_REDIRECT));
$this->add($this->createInput(self::REGULAR_404_REDIRECT, false)); $this->add(InputFactory::basic(self::REGULAR_404_REDIRECT));
$this->add($this->createInput(self::INVALID_SHORT_URL_REDIRECT, false)); $this->add(InputFactory::basic(self::INVALID_SHORT_URL_REDIRECT));
} }
} }

View File

@ -8,7 +8,8 @@ use DateTimeInterface;
use Laminas\Filter; use Laminas\Filter;
use Laminas\InputFilter\InputFilter; use Laminas\InputFilter\InputFilter;
use Laminas\Validator; use Laminas\Validator;
use Shlinkio\Shlink\Common\Validation; use Shlinkio\Shlink\Common\Validation\HostAndPortValidator;
use Shlinkio\Shlink\Common\Validation\InputFactory;
use Shlinkio\Shlink\Core\Options\UrlShortenerOptions; use Shlinkio\Shlink\Core\Options\UrlShortenerOptions;
use Shlinkio\Shlink\Rest\Entity\ApiKey; use Shlinkio\Shlink\Rest\Entity\ApiKey;
@ -21,8 +22,6 @@ use const Shlinkio\Shlink\MIN_SHORT_CODES_LENGTH;
class ShortUrlInputFilter extends InputFilter class ShortUrlInputFilter extends InputFilter
{ {
use Validation\InputFactoryTrait;
// Fields for creation only // Fields for creation only
public const SHORT_CODE_LENGTH = 'shortCodeLength'; public const SHORT_CODE_LENGTH = 'shortCodeLength';
public const CUSTOM_SLUG = 'customSlug'; public const CUSTOM_SLUG = 'customSlug';
@ -64,7 +63,7 @@ class ShortUrlInputFilter extends InputFilter
{ {
// The only way to enforce the NotEmpty validator to be evaluated when the key is present with an empty value // The only way to enforce the NotEmpty validator to be evaluated when the key is present with an empty value
// is with setContinueIfEmpty(true) // is with setContinueIfEmpty(true)
$customSlug = $this->createInput(self::CUSTOM_SLUG, required: false)->setContinueIfEmpty(true); $customSlug = InputFactory::basic(self::CUSTOM_SLUG)->setContinueIfEmpty(true);
$customSlug->getFilterChain()->attach(new CustomSlugFilter($options)); $customSlug->getFilterChain()->attach(new CustomSlugFilter($options));
$customSlug->getValidatorChain() $customSlug->getValidatorChain()
->attach(new Validator\NotEmpty([ ->attach(new Validator\NotEmpty([
@ -77,16 +76,16 @@ class ShortUrlInputFilter extends InputFilter
// The path prefix is subject to the same filtering and validation logic as the custom slug, which takes into // The path prefix is subject to the same filtering and validation logic as the custom slug, which takes into
// consideration if multi-segment slugs are enabled or not. // consideration if multi-segment slugs are enabled or not.
// The only difference is that empty values are allowed here. // The only difference is that empty values are allowed here.
$pathPrefix = $this->createInput(self::PATH_PREFIX, required: false); $pathPrefix = InputFactory::basic(self::PATH_PREFIX);
$pathPrefix->getFilterChain()->attach(new CustomSlugFilter($options)); $pathPrefix->getFilterChain()->attach(new CustomSlugFilter($options));
$pathPrefix->getValidatorChain()->attach(CustomSlugValidator::forUrlShortenerOptions($options)); $pathPrefix->getValidatorChain()->attach(CustomSlugValidator::forUrlShortenerOptions($options));
$this->add($pathPrefix); $this->add($pathPrefix);
$this->add($this->createNumericInput(self::SHORT_CODE_LENGTH, required: false, min: MIN_SHORT_CODES_LENGTH)); $this->add(InputFactory::numeric(self::SHORT_CODE_LENGTH, min: MIN_SHORT_CODES_LENGTH));
$this->add($this->createBooleanInput(self::FIND_IF_EXISTS, required: false)); $this->add(InputFactory::boolean(self::FIND_IF_EXISTS));
$domain = $this->createInput(self::DOMAIN, required: false); $domain = InputFactory::basic(self::DOMAIN);
$domain->getValidatorChain()->attach(new Validation\HostAndPortValidator()); $domain->getValidatorChain()->attach(new HostAndPortValidator());
$this->add($domain); $this->add($domain);
$this->initializeForEdition(requireLongUrl: true); $this->initializeForEdition(requireLongUrl: true);
@ -94,40 +93,40 @@ class ShortUrlInputFilter extends InputFilter
private function initializeForEdition(bool $requireLongUrl = false): void private function initializeForEdition(bool $requireLongUrl = false): void
{ {
$longUrlInput = $this->createInput(self::LONG_URL, $requireLongUrl); $longUrlInput = InputFactory::basic(self::LONG_URL, required: $requireLongUrl);
$longUrlInput->getValidatorChain()->merge($this->longUrlValidators()); $longUrlInput->getValidatorChain()->merge($this->longUrlValidators());
$this->add($longUrlInput); $this->add($longUrlInput);
$deviceLongUrlsInput = $this->createInput(self::DEVICE_LONG_URLS, required: false); $deviceLongUrlsInput = InputFactory::basic(self::DEVICE_LONG_URLS);
$deviceLongUrlsInput->getValidatorChain()->attach( $deviceLongUrlsInput->getValidatorChain()->attach(
new DeviceLongUrlsValidator($this->longUrlValidators(allowNull: ! $requireLongUrl)), new DeviceLongUrlsValidator($this->longUrlValidators(allowNull: ! $requireLongUrl)),
); );
$this->add($deviceLongUrlsInput); $this->add($deviceLongUrlsInput);
$validSince = $this->createInput(self::VALID_SINCE, required: false); $validSince = InputFactory::basic(self::VALID_SINCE);
$validSince->getValidatorChain()->attach(new Validator\Date(['format' => DateTimeInterface::ATOM])); $validSince->getValidatorChain()->attach(new Validator\Date(['format' => DateTimeInterface::ATOM]));
$this->add($validSince); $this->add($validSince);
$validUntil = $this->createInput(self::VALID_UNTIL, required: false); $validUntil = InputFactory::basic(self::VALID_UNTIL);
$validUntil->getValidatorChain()->attach(new Validator\Date(['format' => DateTimeInterface::ATOM])); $validUntil->getValidatorChain()->attach(new Validator\Date(['format' => DateTimeInterface::ATOM]));
$this->add($validUntil); $this->add($validUntil);
$this->add($this->createNumericInput(self::MAX_VISITS, required: false)); $this->add(InputFactory::numeric(self::MAX_VISITS));
$title = $this->createInput(self::TITLE, required: false); $title = InputFactory::basic(self::TITLE);
$title->getFilterChain()->attach(new Filter\Callback( $title->getFilterChain()->attach(new Filter\Callback(
static fn (?string $value) => $value === null ? $value : substr($value, 0, 512), static fn (?string $value) => $value === null ? $value : substr($value, 0, 512),
)); ));
$this->add($title); $this->add($title);
$this->add($this->createTagsInput(self::TAGS, required: false)); $this->add(InputFactory::tags(self::TAGS));
$this->add($this->createBooleanInput(self::CRAWLABLE, required: false)); $this->add(InputFactory::boolean(self::CRAWLABLE));
// This cannot be defined as a boolean inputs, because it can actually have 3 values: true, false and null. // This cannot be defined as a boolean inputs, because it can actually have 3 values: true, false and null.
// Defining them as boolean will make null fall back to false, which is not the desired behavior. // Defining them as boolean will make null fall back to false, which is not the desired behavior.
$this->add($this->createInput(self::FORWARD_QUERY, required: false)); $this->add(InputFactory::basic(self::FORWARD_QUERY));
$apiKeyInput = $this->createInput(self::API_KEY, required: false); $apiKeyInput = InputFactory::basic(self::API_KEY);
$apiKeyInput->getValidatorChain()->attach(new Validator\IsInstanceOf(['className' => ApiKey::class])); $apiKeyInput->getValidatorChain()->attach(new Validator\IsInstanceOf(['className' => ApiKey::class]));
$this->add($apiKeyInput); $this->add($apiKeyInput);
} }

View File

@ -7,7 +7,7 @@ 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\InputFactory;
use Shlinkio\Shlink\Core\ShortUrl\Model\OrderableField; use Shlinkio\Shlink\Core\ShortUrl\Model\OrderableField;
use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode; use Shlinkio\Shlink\Core\ShortUrl\Model\TagsMode;
@ -15,8 +15,6 @@ use function Shlinkio\Shlink\Core\enumValues;
class ShortUrlsParamsInputFilter extends InputFilter class ShortUrlsParamsInputFilter extends InputFilter
{ {
use Validation\InputFactoryTrait;
public const PAGE = 'page'; public const PAGE = 'page';
public const SEARCH_TERM = 'searchTerm'; public const SEARCH_TERM = 'searchTerm';
public const TAGS = 'tags'; public const TAGS = 'tags';
@ -36,26 +34,26 @@ class ShortUrlsParamsInputFilter extends InputFilter
private function initialize(): void private function initialize(): void
{ {
$this->add($this->createDateInput(self::START_DATE, false)); $this->add(InputFactory::date(self::START_DATE));
$this->add($this->createDateInput(self::END_DATE, false)); $this->add(InputFactory::date(self::END_DATE));
$this->add($this->createInput(self::SEARCH_TERM, false)); $this->add(InputFactory::basic(self::SEARCH_TERM));
$this->add($this->createNumericInput(self::PAGE, false)); $this->add(InputFactory::numeric(self::PAGE));
$this->add($this->createNumericInput(self::ITEMS_PER_PAGE, false, Paginator::ALL_ITEMS)); $this->add(InputFactory::numeric(self::ITEMS_PER_PAGE, Paginator::ALL_ITEMS));
$this->add($this->createTagsInput(self::TAGS, false)); $this->add(InputFactory::tags(self::TAGS));
$tagsMode = $this->createInput(self::TAGS_MODE, false); $tagsMode = InputFactory::basic(self::TAGS_MODE);
$tagsMode->getValidatorChain()->attach(new InArray([ $tagsMode->getValidatorChain()->attach(new InArray([
'haystack' => enumValues(TagsMode::class), 'haystack' => enumValues(TagsMode::class),
'strict' => InArray::COMPARE_STRICT, 'strict' => InArray::COMPARE_STRICT,
])); ]));
$this->add($tagsMode); $this->add($tagsMode);
$this->add($this->createOrderByInput(self::ORDER_BY, enumValues(OrderableField::class))); $this->add(InputFactory::orderBy(self::ORDER_BY, enumValues(OrderableField::class)));
$this->add($this->createBooleanInput(self::EXCLUDE_MAX_VISITS_REACHED, false)); $this->add(InputFactory::boolean(self::EXCLUDE_MAX_VISITS_REACHED));
$this->add($this->createBooleanInput(self::EXCLUDE_PAST_VALID_UNTIL, false)); $this->add(InputFactory::boolean(self::EXCLUDE_PAST_VALID_UNTIL));
} }
} }