mirror of
https://github.com/shlinkio/shlink.git
synced 2025-02-20 11:48:27 -06:00
Created new action to set redirects for a domain
This commit is contained in:
parent
5a1a4f5594
commit
6a40bbdcb5
@ -66,6 +66,39 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Provided data is invalid.",
|
||||
"content": {
|
||||
"application/problem+json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "../definitions/Error.json"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": ["invalidElements"],
|
||||
"properties": {
|
||||
"invalidElements": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"domain",
|
||||
"baseUrlRedirect",
|
||||
"regular404Redirect",
|
||||
"invalidShortUrlRedirect"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Unexpected error.",
|
||||
"content": {
|
||||
|
@ -4,7 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\Config;
|
||||
|
||||
final class NotFoundRedirects
|
||||
use JsonSerializable;
|
||||
|
||||
final class NotFoundRedirects implements JsonSerializable
|
||||
{
|
||||
public function __construct(
|
||||
private ?string $baseUrlRedirect = null,
|
||||
@ -27,4 +29,13 @@ final class NotFoundRedirects
|
||||
{
|
||||
return $this->invalidShortUrlRedirect;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): array
|
||||
{
|
||||
return [
|
||||
'baseUrlRedirect' => $this->baseUrlRedirect,
|
||||
'regular404Redirect' => $this->regular404Redirect,
|
||||
'invalidShortUrlRedirect' => $this->invalidShortUrlRedirect,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ return [
|
||||
Action\Tag\CreateTagsAction::class => ConfigAbstractFactory::class,
|
||||
Action\Tag\UpdateTagAction::class => ConfigAbstractFactory::class,
|
||||
Action\Domain\ListDomainsAction::class => ConfigAbstractFactory::class,
|
||||
Action\Domain\DomainRedirectsAction::class => ConfigAbstractFactory::class,
|
||||
|
||||
ImplicitOptionsMiddleware::class => Middleware\EmptyResponseImplicitOptionsMiddlewareFactory::class,
|
||||
Middleware\BodyParserMiddleware::class => InvokableFactory::class,
|
||||
@ -81,6 +82,7 @@ return [
|
||||
Action\Tag\CreateTagsAction::class => [TagService::class],
|
||||
Action\Tag\UpdateTagAction::class => [TagService::class],
|
||||
Action\Domain\ListDomainsAction::class => [DomainService::class],
|
||||
Action\Domain\DomainRedirectsAction::class => [DomainService::class],
|
||||
|
||||
Middleware\CrossDomainMiddleware::class => ['config.cors'],
|
||||
Middleware\ShortUrl\DropDefaultDomainFromRequestMiddleware::class => ['config.url_shortener.domain.hostname'],
|
||||
|
@ -44,6 +44,7 @@ return [
|
||||
|
||||
// Domains
|
||||
Action\Domain\ListDomainsAction::getRouteDef(),
|
||||
Action\Domain\DomainRedirectsAction::getRouteDef(),
|
||||
|
||||
Action\MercureInfoAction::getRouteDef(),
|
||||
],
|
||||
|
41
module/Rest/src/Action/Domain/DomainRedirectsAction.php
Normal file
41
module/Rest/src/Action/Domain/DomainRedirectsAction.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Rest\Action\Domain;
|
||||
|
||||
use Laminas\Diactoros\Response\JsonResponse;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Shlinkio\Shlink\Core\Domain\DomainServiceInterface;
|
||||
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
|
||||
use Shlinkio\Shlink\Rest\Action\Domain\Request\DomainRedirectsRequest;
|
||||
use Shlinkio\Shlink\Rest\Middleware\AuthenticationMiddleware;
|
||||
|
||||
class DomainRedirectsAction extends AbstractRestAction
|
||||
{
|
||||
protected const ROUTE_PATH = '/domains/redirects';
|
||||
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_PATCH];
|
||||
|
||||
public function __construct(private DomainServiceInterface $domainService)
|
||||
{
|
||||
}
|
||||
|
||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
// TODO Do not allow to set redirects for default domain
|
||||
|
||||
/** @var array $body */
|
||||
$body = $request->getParsedBody();
|
||||
$requestData = DomainRedirectsRequest::fromRawData($body);
|
||||
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
|
||||
|
||||
$authority = $requestData->authority();
|
||||
$domain = $this->domainService->getOrCreate($authority);
|
||||
$notFoundRedirects = $requestData->toNotFoundRedirects($domain);
|
||||
|
||||
$this->domainService->configureNotFoundRedirects($authority, $notFoundRedirects, $apiKey);
|
||||
|
||||
return new JsonResponse($notFoundRedirects);
|
||||
}
|
||||
}
|
@ -25,6 +25,8 @@ class ListDomainsAction extends AbstractRestAction
|
||||
$apiKey = AuthenticationMiddleware::apiKeyFromRequest($request);
|
||||
$domainItems = $this->domainService->listDomains($apiKey);
|
||||
|
||||
// TODO Support including not found redirects if requested via query param
|
||||
|
||||
return new JsonResponse([
|
||||
'domains' => [
|
||||
'data' => $domainItems,
|
||||
|
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Rest\Action\Domain\Request;
|
||||
|
||||
use Shlinkio\Shlink\Core\Config\NotFoundRedirectConfigInterface;
|
||||
use Shlinkio\Shlink\Core\Config\NotFoundRedirects;
|
||||
use function array_key_exists;
|
||||
|
||||
class DomainRedirectsRequest
|
||||
{
|
||||
private string $authority;
|
||||
private ?string $baseUrlRedirect = null;
|
||||
private bool $baseUrlRedirectWasProvided = false;
|
||||
private ?string $regular404Redirect = null;
|
||||
private bool $regular404RedirectWasProvided = false;
|
||||
private ?string $invalidShortUrlRedirect = null;
|
||||
private bool $invalidShortUrlRedirectWasProvided = false;
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function fromRawData(array $payload): self
|
||||
{
|
||||
$instance = new self();
|
||||
$instance->validateAndInit($payload);
|
||||
return $instance;
|
||||
}
|
||||
|
||||
private function validateAndInit(array $payload): void
|
||||
{
|
||||
// TODO Validate data
|
||||
$this->baseUrlRedirectWasProvided = array_key_exists('baseUrlRedirect', $payload);
|
||||
$this->regular404RedirectWasProvided = array_key_exists('regular404Redirect', $payload);
|
||||
$this->invalidShortUrlRedirectWasProvided = array_key_exists('invalidShortUrlRedirect', $payload);
|
||||
|
||||
$this->authority = $payload['domain'];
|
||||
$this->baseUrlRedirect = $payload['baseUrlRedirect'] ?? null;
|
||||
$this->regular404Redirect = $payload['regular404Redirect'] ?? null;
|
||||
$this->invalidShortUrlRedirect = $payload['invalidShortUrlRedirect'] ?? null;
|
||||
}
|
||||
|
||||
public function authority(): string
|
||||
{
|
||||
return $this->authority;
|
||||
}
|
||||
|
||||
public function toNotFoundRedirects(?NotFoundRedirectConfigInterface $defaults = null): NotFoundRedirects
|
||||
{
|
||||
return new NotFoundRedirects(
|
||||
$this->baseUrlRedirectWasProvided ? $this->baseUrlRedirect : $defaults?->baseUrlRedirect(),
|
||||
$this->regular404RedirectWasProvided ? $this->regular404Redirect : $defaults?->regular404Redirect(),
|
||||
$this->invalidShortUrlRedirectWasProvided
|
||||
? $this->invalidShortUrlRedirect
|
||||
: $defaults?->invalidShortUrlRedirect(),
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user