mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-27 16:26:37 +03:00
Created action which allows short URLs to be created on a single API request
This commit is contained in:
parent
28650aee2b
commit
e5ef8d7f8c
8 changed files with 84 additions and 23 deletions
|
@ -8,6 +8,7 @@ return [
|
|||
'auth' => [
|
||||
'routes_whitelist' => [
|
||||
Action\AuthenticateAction::class,
|
||||
Action\ShortCode\SingleStepCreateShortCodeAction::class,
|
||||
],
|
||||
],
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ return [
|
|||
|
||||
Action\AuthenticateAction::class => ConfigAbstractFactory::class,
|
||||
Action\CreateShortCodeAction::class => ConfigAbstractFactory::class,
|
||||
Action\ShortCode\SingleStepCreateShortCodeAction::class => ConfigAbstractFactory::class,
|
||||
Action\EditShortCodeAction::class => ConfigAbstractFactory::class,
|
||||
Action\ResolveUrlAction::class => ConfigAbstractFactory::class,
|
||||
Action\GetVisitsAction::class => ConfigAbstractFactory::class,
|
||||
|
@ -49,6 +50,13 @@ return [
|
|||
'config.url_shortener.domain',
|
||||
'Logger_Shlink',
|
||||
],
|
||||
Action\ShortCode\SingleStepCreateShortCodeAction::class => [
|
||||
Service\UrlShortener::class,
|
||||
'translator',
|
||||
ApiKeyService::class,
|
||||
'config.url_shortener.domain',
|
||||
'Logger_Shlink',
|
||||
],
|
||||
Action\EditShortCodeAction::class => [Service\ShortUrlService::class, 'translator', 'Logger_Shlink',],
|
||||
Action\ResolveUrlAction::class => [Service\UrlShortener::class, 'translator'],
|
||||
Action\GetVisitsAction::class => [Service\VisitsTracker::class, 'translator', 'Logger_Shlink'],
|
||||
|
|
|
@ -10,12 +10,7 @@ return [
|
|||
|
||||
// Short codes
|
||||
Action\CreateShortCodeAction::getRouteDef(),
|
||||
// [
|
||||
// 'name' => Action\CreateShortCodeAction::class,
|
||||
// 'path' => '/short-codes',
|
||||
// 'middleware' => Action\CreateShortCodeAction::class,
|
||||
// 'allowed_methods' => [RequestMethod::METHOD_GET],
|
||||
// ],
|
||||
Action\ShortCode\SingleStepCreateShortCodeAction::getRouteDef(),
|
||||
Action\EditShortCodeAction::getRouteDef(),
|
||||
Action\ResolveUrlAction::getRouteDef(),
|
||||
Action\ListShortCodesAction::getRouteDef(),
|
||||
|
|
|
@ -5,7 +5,6 @@ namespace Shlinkio\Shlink\Rest\Action;
|
|||
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Core\Exception\ValidationException;
|
||||
use Shlinkio\Shlink\Core\Model\CreateShortCodeData;
|
||||
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
|
||||
use Shlinkio\Shlink\Rest\Action\ShortCode\AbstractCreateShortCodeAction;
|
||||
|
@ -19,7 +18,6 @@ class CreateShortCodeAction extends AbstractCreateShortCodeAction
|
|||
/**
|
||||
* @param Request $request
|
||||
* @return CreateShortCodeData
|
||||
* @throws ValidationException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
|
@ -27,7 +25,7 @@ class CreateShortCodeAction extends AbstractCreateShortCodeAction
|
|||
{
|
||||
$postData = (array) $request->getParsedBody();
|
||||
if (! isset($postData['longUrl'])) {
|
||||
throw new InvalidArgumentException('A URL was not provided');
|
||||
throw new InvalidArgumentException($this->translator->translate('A URL was not provided'));
|
||||
}
|
||||
|
||||
return new CreateShortCodeData(
|
||||
|
|
|
@ -9,7 +9,6 @@ use Psr\Log\LoggerInterface;
|
|||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
|
||||
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
|
||||
use Shlinkio\Shlink\Core\Exception\ValidationException;
|
||||
use Shlinkio\Shlink\Core\Model\CreateShortCodeData;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
|
||||
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
|
||||
|
@ -31,7 +30,7 @@ abstract class AbstractCreateShortCodeAction extends AbstractRestAction
|
|||
/**
|
||||
* @var TranslatorInterface
|
||||
*/
|
||||
private $translator;
|
||||
protected $translator;
|
||||
|
||||
public function __construct(
|
||||
UrlShortenerInterface $urlShortener,
|
||||
|
@ -57,11 +56,11 @@ abstract class AbstractCreateShortCodeAction extends AbstractRestAction
|
|||
$shortCodeMeta = $shortCodeData->getMeta();
|
||||
$longUrl = $shortCodeData->getLongUrl();
|
||||
$customSlug = $shortCodeMeta->getCustomSlug();
|
||||
} catch (ValidationException | InvalidArgumentException $e) {
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$this->logger->warning('Provided data is invalid.' . PHP_EOL . $e);
|
||||
return new JsonResponse([
|
||||
'error' => RestUtils::INVALID_ARGUMENT_ERROR,
|
||||
'message' => $this->translator->translate('Provided data is invalid'),
|
||||
'message' => $e->getMessage(),
|
||||
], self::STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
|
@ -114,7 +113,6 @@ abstract class AbstractCreateShortCodeAction extends AbstractRestAction
|
|||
/**
|
||||
* @param Request $request
|
||||
* @return CreateShortCodeData
|
||||
* @throws ValidationException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
abstract protected function buildUrlToShortCodeData(Request $request): CreateShortCodeData;
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Rest\Action\ShortCode;
|
||||
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
|
||||
use Shlinkio\Shlink\Core\Exception\ValidationException;
|
||||
use Shlinkio\Shlink\Core\Model\CreateShortCodeData;
|
||||
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
|
||||
use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface;
|
||||
use Zend\Diactoros\Uri;
|
||||
use Zend\I18n\Translator\TranslatorInterface;
|
||||
|
||||
class SingleStepCreateShortCodeAction extends AbstractCreateShortCodeAction
|
||||
{
|
||||
protected const ROUTE_PATH = '/short-codes/shorten';
|
||||
protected const ROUTE_ALLOWED_METHODS = [self::METHOD_GET];
|
||||
|
||||
/**
|
||||
* @var ApiKeyServiceInterface
|
||||
*/
|
||||
private $apiKeyService;
|
||||
|
||||
public function __construct(
|
||||
UrlShortenerInterface $urlShortener,
|
||||
TranslatorInterface $translator,
|
||||
ApiKeyServiceInterface $apiKeyService,
|
||||
array $domainConfig,
|
||||
LoggerInterface $logger = null
|
||||
) {
|
||||
parent::__construct($urlShortener, $translator, $domainConfig, $logger);
|
||||
$this->apiKeyService = $apiKeyService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @return CreateShortCodeData
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
protected function buildUrlToShortCodeData(Request $request): CreateShortCodeData
|
||||
{
|
||||
$query = $request->getQueryParams();
|
||||
|
||||
// Check provided API key
|
||||
$apiKey = $this->apiKeyService->getByKey($query['apiKey'] ?? '');
|
||||
if ($apiKey === null || ! $apiKey->isValid()) {
|
||||
throw new InvalidArgumentException(
|
||||
$this->translator->translate('No API key was provided or it is not valid')
|
||||
);
|
||||
}
|
||||
|
||||
if (! isset($query['longUrl'])) {
|
||||
throw new InvalidArgumentException($this->translator->translate('A URL was not provided'));
|
||||
}
|
||||
|
||||
return new CreateShortCodeData(new Uri($query['longUrl']));
|
||||
}
|
||||
}
|
|
@ -28,7 +28,7 @@ class ApiKeyService implements ApiKeyServiceInterface
|
|||
public function create(\DateTime $expirationDate = null)
|
||||
{
|
||||
$key = new ApiKey();
|
||||
if (isset($expirationDate)) {
|
||||
if ($expirationDate !== null) {
|
||||
$key->setExpirationDate($expirationDate);
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ class ApiKeyService implements ApiKeyServiceInterface
|
|||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function check($key)
|
||||
public function check(string $key)
|
||||
{
|
||||
/** @var ApiKey|null $apiKey */
|
||||
$apiKey = $this->getByKey($key);
|
||||
|
@ -58,7 +58,7 @@ class ApiKeyService implements ApiKeyServiceInterface
|
|||
* @return ApiKey
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function disable($key)
|
||||
public function disable(string $key)
|
||||
{
|
||||
/** @var ApiKey|null $apiKey */
|
||||
$apiKey = $this->getByKey($key);
|
||||
|
@ -77,7 +77,7 @@ class ApiKeyService implements ApiKeyServiceInterface
|
|||
* @param bool $enabledOnly Tells if only enabled keys should be returned
|
||||
* @return ApiKey[]
|
||||
*/
|
||||
public function listKeys($enabledOnly = false)
|
||||
public function listKeys(bool $enabledOnly = false)
|
||||
{
|
||||
$conditions = $enabledOnly ? ['enabled' => true] : [];
|
||||
return $this->em->getRepository(ApiKey::class)->findBy($conditions);
|
||||
|
@ -89,7 +89,7 @@ class ApiKeyService implements ApiKeyServiceInterface
|
|||
* @param string $key
|
||||
* @return ApiKey|null
|
||||
*/
|
||||
public function getByKey($key)
|
||||
public function getByKey(string $key)
|
||||
{
|
||||
/** @var ApiKey|null $apiKey */
|
||||
$apiKey = $this->em->getRepository(ApiKey::class)->findOneBy([
|
||||
|
|
|
@ -22,7 +22,7 @@ interface ApiKeyServiceInterface
|
|||
* @param string $key
|
||||
* @return bool
|
||||
*/
|
||||
public function check($key);
|
||||
public function check(string $key);
|
||||
|
||||
/**
|
||||
* Disables provided api key
|
||||
|
@ -31,7 +31,7 @@ interface ApiKeyServiceInterface
|
|||
* @return ApiKey
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function disable($key);
|
||||
public function disable(string $key);
|
||||
|
||||
/**
|
||||
* Lists all existing api keys
|
||||
|
@ -39,7 +39,7 @@ interface ApiKeyServiceInterface
|
|||
* @param bool $enabledOnly Tells if only enabled keys should be returned
|
||||
* @return ApiKey[]
|
||||
*/
|
||||
public function listKeys($enabledOnly = false);
|
||||
public function listKeys(bool $enabledOnly = false);
|
||||
|
||||
/**
|
||||
* Tries to find one API key by its key string
|
||||
|
@ -47,5 +47,5 @@ interface ApiKeyServiceInterface
|
|||
* @param string $key
|
||||
* @return ApiKey|null
|
||||
*/
|
||||
public function getByKey($key);
|
||||
public function getByKey(string $key);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue