Passed
Pull Request — master (#343)
by Alejandro
05:15
created

AbstractCreateShortUrlAction::handle()   A

Complexity

Conditions 5
Paths 11

Size

Total Lines 39
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 31
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 33
nc 11
nop 1
dl 0
loc 39
rs 9.0808
c 0
b 0
f 0
ccs 31
cts 31
cp 1
crap 5
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\Rest\Action\ShortUrl;
5
6
use Psr\Http\Message\ResponseInterface as Response;
7
use Psr\Http\Message\ServerRequestInterface as Request;
8
use Psr\Log\LoggerInterface;
9
use Shlinkio\Shlink\Core\Exception\InvalidArgumentException;
10
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
11
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
12
use Shlinkio\Shlink\Core\Model\CreateShortUrlData;
13
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
14
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
15
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
16
use Shlinkio\Shlink\Rest\Util\RestUtils;
17
use Throwable;
18
use Zend\Diactoros\Response\JsonResponse;
19
use function sprintf;
20
21
abstract class AbstractCreateShortUrlAction extends AbstractRestAction
22
{
23
    /** @var UrlShortenerInterface */
24
    private $urlShortener;
25
    /** @var array */
26
    private $domainConfig;
27
28 8
    public function __construct(
29
        UrlShortenerInterface $urlShortener,
30
        array $domainConfig,
31
        LoggerInterface $logger = null
32
    ) {
33 8
        parent::__construct($logger);
34 8
        $this->urlShortener = $urlShortener;
35 8
        $this->domainConfig = $domainConfig;
36
    }
37
38
    /**
39
     * @param Request $request
40
     * @return Response
41
     */
42 8
    public function handle(Request $request): Response
43
    {
44
        try {
45 8
            $shortUrlData = $this->buildShortUrlData($request);
46 3
        } catch (InvalidArgumentException $e) {
47 3
            $this->logger->warning('Provided data is invalid. {e}', ['e' => $e]);
48 3
            return new JsonResponse([
49 3
                'error' => RestUtils::INVALID_ARGUMENT_ERROR,
50 3
                'message' => $e->getMessage(),
51 3
            ], self::STATUS_BAD_REQUEST);
52
        }
53
54 5
        $longUrl = $shortUrlData->getLongUrl();
55 5
        $shortUrlMeta = $shortUrlData->getMeta();
56
57
        try {
58 5
            $shortUrl = $this->urlShortener->urlToShortCode($longUrl, $shortUrlData->getTags(), $shortUrlMeta);
59 2
            $transformer = new ShortUrlDataTransformer($this->domainConfig);
60
61 2
            return new JsonResponse($transformer->transform($shortUrl));
62 3
        } catch (InvalidUrlException $e) {
63 1
            $this->logger->warning('Provided Invalid URL. {e}', ['e' => $e]);
64 1
            return new JsonResponse([
65 1
                'error' => RestUtils::getRestErrorCodeFromException($e),
66 1
                'message' => sprintf('Provided URL %s is invalid. Try with a different one.', $longUrl),
67 1
            ], self::STATUS_BAD_REQUEST);
68 2
        } catch (NonUniqueSlugException $e) {
69 1
            $customSlug = $shortUrlMeta->getCustomSlug();
70 1
            $this->logger->warning('Provided non-unique slug. {e}', ['e' => $e]);
71 1
            return new JsonResponse([
72 1
                'error' => RestUtils::getRestErrorCodeFromException($e),
73 1
                'message' => sprintf('Provided slug %s is already in use. Try with a different one.', $customSlug),
74 1
            ], self::STATUS_BAD_REQUEST);
75 1
        } catch (Throwable $e) {
76 1
            $this->logger->error('Unexpected error creating short url. {e}', ['e' => $e]);
77 1
            return new JsonResponse([
78 1
                'error' => RestUtils::UNKNOWN_ERROR,
79
                'message' => 'Unexpected error occurred',
80 1
            ], self::STATUS_INTERNAL_SERVER_ERROR);
81
        }
82
    }
83
84
    /**
85
     * @param Request $request
86
     * @return CreateShortUrlData
87
     * @throws InvalidArgumentException
88
     */
89
    abstract protected function buildShortUrlData(Request $request): CreateShortUrlData;
90
}
91