Completed
Pull Request — master (#148)
by Alejandro
03:04
created

AbstractCreateShortCodeAction::handle()   B

Complexity

Conditions 5
Paths 14

Size

Total Lines 60
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 47
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 49
c 0
b 0
f 0
nc 14
nop 1
dl 0
loc 60
ccs 47
cts 47
cp 1
crap 5
rs 8.6961

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\Rest\Action\ShortCode;
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\Exception\ValidationException;
13
use Shlinkio\Shlink\Core\Model\CreateShortCodeData;
14
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
15
use Shlinkio\Shlink\Rest\Action\AbstractRestAction;
16
use Shlinkio\Shlink\Rest\Util\RestUtils;
17
use Zend\Diactoros\Response\JsonResponse;
18
use Zend\Diactoros\Uri;
19
use Zend\I18n\Translator\TranslatorInterface;
20
21
abstract class AbstractCreateShortCodeAction extends AbstractRestAction
22
{
23
    /**
24
     * @var UrlShortenerInterface
25
     */
26
    private $urlShortener;
27
    /**
28
     * @var array
29
     */
30
    private $domainConfig;
31
    /**
32
     * @var TranslatorInterface
33
     */
34
    private $translator;
35
36 5
    public function __construct(
37
        UrlShortenerInterface $urlShortener,
38
        TranslatorInterface $translator,
39
        array $domainConfig,
40
        LoggerInterface $logger = null
41
    ) {
42 5
        parent::__construct($logger);
43 5
        $this->urlShortener = $urlShortener;
44 5
        $this->translator = $translator;
45 5
        $this->domainConfig = $domainConfig;
46 5
    }
47
48
    /**
49
     * @param Request $request
50
     * @return Response
51
     * @throws \InvalidArgumentException
52
     */
53 5
    public function handle(Request $request): Response
54
    {
55
        try {
56 5
            $shortCodeData = $this->buildUrlToShortCodeData($request);
57 4
            $shortCodeMeta = $shortCodeData->getMeta();
58 4
            $longUrl = $shortCodeData->getLongUrl();
59 4
            $customSlug = $shortCodeMeta->getCustomSlug();
60 1
        } catch (ValidationException | InvalidArgumentException $e) {
61 1
            $this->logger->warning('Provided data is invalid.' . PHP_EOL . $e);
62 1
            return new JsonResponse([
63 1
                'error' => RestUtils::INVALID_ARGUMENT_ERROR,
64 1
                'message' => $this->translator->translate('Provided data is invalid'),
65 1
            ], self::STATUS_BAD_REQUEST);
66
        }
67
68
        try {
69 4
            $shortCode = $this->urlShortener->urlToShortCode(
70 4
                $longUrl,
71 4
                $shortCodeData->getTags(),
72 4
                $shortCodeMeta->getValidSince(),
73 4
                $shortCodeMeta->getValidUntil(),
74 4
                $customSlug,
75 4
                $shortCodeMeta->getMaxVisits()
76
            );
77 1
            $shortUrl = (new Uri())->withPath($shortCode)
78 1
                                   ->withScheme($this->domainConfig['schema'])
79 1
                                   ->withHost($this->domainConfig['hostname']);
80
81
            // TODO Make response to be generated based on Accept header
82 1
            return new JsonResponse([
83 1
                'longUrl' => (string) $longUrl,
84 1
                'shortUrl' => (string) $shortUrl,
85 1
                'shortCode' => $shortCode,
86
            ]);
87 3
        } catch (InvalidUrlException $e) {
88 1
            $this->logger->warning('Provided Invalid URL.' . PHP_EOL . $e);
89 1
            return new JsonResponse([
90 1
                'error' => RestUtils::getRestErrorCodeFromException($e),
91 1
                'message' => \sprintf(
92 1
                    $this->translator->translate('Provided URL %s is invalid. Try with a different one.'),
93 1
                    $longUrl
94
                ),
95 1
            ], self::STATUS_BAD_REQUEST);
96 2
        } catch (NonUniqueSlugException $e) {
97 1
            $this->logger->warning('Provided non-unique slug.' . PHP_EOL . $e);
98 1
            return new JsonResponse([
99 1
                'error' => RestUtils::getRestErrorCodeFromException($e),
100 1
                'message' => \sprintf(
101 1
                    $this->translator->translate('Provided slug %s is already in use. Try with a different one.'),
102 1
                    $customSlug
103
                ),
104 1
            ], self::STATUS_BAD_REQUEST);
105 1
        } catch (\Throwable $e) {
106 1
            $this->logger->error('Unexpected error creating shortcode.' . PHP_EOL . $e);
107 1
            return new JsonResponse([
108 1
                'error' => RestUtils::UNKNOWN_ERROR,
109 1
                'message' => $this->translator->translate('Unexpected error occurred'),
110 1
            ], self::STATUS_INTERNAL_SERVER_ERROR);
111
        }
112
    }
113
114
    /**
115
     * @param Request $request
116
     * @return CreateShortCodeData
117
     * @throws ValidationException
118
     * @throws InvalidArgumentException
119
     */
120
    abstract protected function buildUrlToShortCodeData(Request $request): CreateShortCodeData;
121
}
122