Completed
Push — develop ( 8162da...f53fa5 )
by Alejandro
31s queued 13s
created

GenerateShortUrlCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 55
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 46
nc 1
nop 0
dl 0
loc 55
ccs 44
cts 44
cp 1
crap 1
rs 9.1781
c 0
b 0
f 0

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
3
declare(strict_types=1);
4
5
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
6
7
use Laminas\Diactoros\Uri;
8
use Shlinkio\Shlink\CLI\Util\ExitCodes;
9
use Shlinkio\Shlink\Core\Exception\InvalidUrlException;
10
use Shlinkio\Shlink\Core\Exception\NonUniqueSlugException;
11
use Shlinkio\Shlink\Core\Model\ShortUrlMeta;
12
use Shlinkio\Shlink\Core\Service\UrlShortenerInterface;
13
use Shlinkio\Shlink\Core\Validation\ShortUrlMetaInputFilter;
14
use Symfony\Component\Console\Command\Command;
15
use Symfony\Component\Console\Input\InputArgument;
16
use Symfony\Component\Console\Input\InputInterface;
17
use Symfony\Component\Console\Input\InputOption;
18
use Symfony\Component\Console\Output\OutputInterface;
19
use Symfony\Component\Console\Style\SymfonyStyle;
20
21
use function array_map;
22
use function Functional\curry;
23
use function Functional\flatten;
24
use function Functional\unique;
25
use function sprintf;
26
27
class GenerateShortUrlCommand extends Command
28
{
29
    public const NAME = 'short-url:generate';
30
31
    private UrlShortenerInterface $urlShortener;
32
    private array $domainConfig;
33
    private int $defaultShortCodeLength;
34
35 4
    public function __construct(UrlShortenerInterface $urlShortener, array $domainConfig, int $defaultShortCodeLength)
36
    {
37 4
        parent::__construct();
38 4
        $this->urlShortener = $urlShortener;
39 4
        $this->domainConfig = $domainConfig;
40 4
        $this->defaultShortCodeLength = $defaultShortCodeLength;
41
    }
42
43 4
    protected function configure(): void
44
    {
45
        $this
46 4
            ->setName(self::NAME)
47 4
            ->setDescription('Generates a short URL for provided long URL and returns it')
48 4
            ->addArgument('longUrl', InputArgument::REQUIRED, 'The long URL to parse')
49 4
            ->addOption(
50 4
                'tags',
51 4
                't',
52 4
                InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED,
53 4
                'Tags to apply to the new short URL',
54
            )
55 4
            ->addOption(
56 4
                'validSince',
57 4
                's',
58 4
                InputOption::VALUE_REQUIRED,
59
                'The date from which this short URL will be valid. '
60 4
                . 'If someone tries to access it before this date, it will not be found.',
61
            )
62 4
            ->addOption(
63 4
                'validUntil',
64 4
                'u',
65 4
                InputOption::VALUE_REQUIRED,
66
                'The date until which this short URL will be valid. '
67 4
                . 'If someone tries to access it after this date, it will not be found.',
68
            )
69 4
            ->addOption(
70 4
                'customSlug',
71 4
                'c',
72 4
                InputOption::VALUE_REQUIRED,
73 4
                'If provided, this slug will be used instead of generating a short code',
74
            )
75 4
            ->addOption(
76 4
                'maxVisits',
77 4
                'm',
78 4
                InputOption::VALUE_REQUIRED,
79 4
                'This will limit the number of visits for this short URL.',
80
            )
81 4
            ->addOption(
82 4
                'findIfExists',
83 4
                'f',
84 4
                InputOption::VALUE_NONE,
85 4
                'This will force existing matching URL to be returned if found, instead of creating a new one.',
86
            )
87 4
            ->addOption(
88 4
                'domain',
89 4
                'd',
90 4
                InputOption::VALUE_REQUIRED,
91 4
                'The domain to which this short URL will be attached.',
92
            )
93 4
            ->addOption(
94 4
                'shortCodeLength',
95 4
                'l',
96 4
                InputOption::VALUE_REQUIRED,
97 4
                'The length for generated short code (it will be ignored if --customSlug was provided).',
98
            );
99
    }
100
101 4
    protected function interact(InputInterface $input, OutputInterface $output): void
102
    {
103 4
        $io = new SymfonyStyle($input, $output);
104 4
        $longUrl = $input->getArgument('longUrl');
105 4
        if (! empty($longUrl)) {
106 4
            return;
107
        }
108
109
        $longUrl = $io->ask('Which URL do you want to shorten?');
110
        if (! empty($longUrl)) {
111
            $input->setArgument('longUrl', $longUrl);
112
        }
113
    }
114
115 4
    protected function execute(InputInterface $input, OutputInterface $output): ?int
116
    {
117 4
        $io = new SymfonyStyle($input, $output);
118 4
        $longUrl = $input->getArgument('longUrl');
119 4
        if (empty($longUrl)) {
120
            $io->error('A URL was not provided!');
121
            return ExitCodes::EXIT_FAILURE;
122
        }
123
124 4
        $explodeWithComma = curry('explode')(',');
125 4
        $tags = unique(flatten(array_map($explodeWithComma, $input->getOption('tags'))));
0 ignored issues
show
Bug introduced by
It seems like $input->getOption('tags') can also be of type boolean and null and string; however, parameter $arr1 of array_map() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

125
        $tags = unique(flatten(array_map($explodeWithComma, /** @scrutinizer ignore-type */ $input->getOption('tags'))));
Loading history...
126 4
        $customSlug = $input->getOption('customSlug');
127 4
        $maxVisits = $input->getOption('maxVisits');
128 4
        $shortCodeLength = $input->getOption('shortCodeLength') ?? $this->defaultShortCodeLength;
129
130
        try {
131 4
            $shortUrl = $this->urlShortener->urlToShortCode(
132 4
                new Uri($longUrl),
0 ignored issues
show
Bug introduced by
It seems like $longUrl can also be of type string[]; however, parameter $uri of Laminas\Diactoros\Uri::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

132
                new Uri(/** @scrutinizer ignore-type */ $longUrl),
Loading history...
133
                $tags,
134 4
                ShortUrlMeta::fromRawData([
135 4
                    ShortUrlMetaInputFilter::VALID_SINCE => $input->getOption('validSince'),
136 4
                    ShortUrlMetaInputFilter::VALID_UNTIL => $input->getOption('validUntil'),
137 4
                    ShortUrlMetaInputFilter::CUSTOM_SLUG => $customSlug,
138 1
                    ShortUrlMetaInputFilter::MAX_VISITS => $maxVisits !== null ? (int) $maxVisits : null,
139 4
                    ShortUrlMetaInputFilter::FIND_IF_EXISTS => $input->getOption('findIfExists'),
140 4
                    ShortUrlMetaInputFilter::DOMAIN => $input->getOption('domain'),
141 4
                    ShortUrlMetaInputFilter::SHORT_CODE_LENGTH => $shortCodeLength,
142
                ]),
143
            );
144
145 2
            $io->writeln([
146 2
                sprintf('Processed long URL: <info>%s</info>', $longUrl),
0 ignored issues
show
Bug introduced by
It seems like $longUrl can also be of type string[]; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

146
                sprintf('Processed long URL: <info>%s</info>', /** @scrutinizer ignore-type */ $longUrl),
Loading history...
147 2
                sprintf('Generated short URL: <info>%s</info>', $shortUrl->toString($this->domainConfig)),
148
            ]);
149 2
            return ExitCodes::EXIT_SUCCESS;
150 2
        } catch (InvalidUrlException | NonUniqueSlugException $e) {
151 2
            $io->error($e->getMessage());
152 2
            return ExitCodes::EXIT_FAILURE;
153
        }
154
    }
155
}
156