Completed
Pull Request — master (#278)
by Alejandro
02:43
created

ListShortUrlsCommand::execute()   B

Complexity

Conditions 7
Paths 24

Size

Total Lines 38
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 25
CRAP Score 7.0027

Importance

Changes 0
Metric Value
cc 7
eloc 29
nc 24
nop 2
dl 0
loc 38
ccs 25
cts 26
cp 0.9615
crap 7.0027
rs 8.5226
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
5
6
use Shlinkio\Shlink\Common\Paginator\Adapter\PaginableRepositoryAdapter;
7
use Shlinkio\Shlink\Common\Paginator\Util\PaginatorUtilsTrait;
8
use Shlinkio\Shlink\Core\Service\ShortUrlServiceInterface;
9
use Shlinkio\Shlink\Core\Transformer\ShortUrlDataTransformer;
10
use Symfony\Component\Console\Command\Command;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\Console\Input\InputOption;
13
use Symfony\Component\Console\Output\OutputInterface;
14
use Symfony\Component\Console\Style\SymfonyStyle;
15
use function array_values;
16
use function count;
17
use function explode;
18
use function implode;
19
use function sprintf;
20
21
class ListShortUrlsCommand extends Command
22
{
23
    use PaginatorUtilsTrait;
24
25
    public const NAME = 'short-url:list';
26
    private const ALIASES = ['shortcode:list', 'short-code:list'];
27
28
    /**
29
     * @var ShortUrlServiceInterface
30
     */
31
    private $shortUrlService;
32
    /**
33
     * @var array
34
     */
35
    private $domainConfig;
36
37 5
    public function __construct(ShortUrlServiceInterface $shortUrlService, array $domainConfig)
38
    {
39 5
        parent::__construct();
40 5
        $this->shortUrlService = $shortUrlService;
41 5
        $this->domainConfig = $domainConfig;
42
    }
43
44 5
    protected function configure(): void
45
    {
46
        $this
47 5
            ->setName(self::NAME)
48 5
            ->setAliases(self::ALIASES)
49 5
            ->setDescription('List all short URLs')
50 5
            ->addOption(
51 5
                'page',
52 5
                'p',
53 5
                InputOption::VALUE_OPTIONAL,
54 5
                sprintf('The first page to list (%s items per page)', PaginableRepositoryAdapter::ITEMS_PER_PAGE),
55 5
                '1'
56
            )
57 5
            ->addOption(
58 5
                'searchTerm',
59 5
                's',
60 5
                InputOption::VALUE_OPTIONAL,
61 5
                'A query used to filter results by searching for it on the longUrl and shortCode fields'
62
            )
63 5
            ->addOption(
64 5
                'tags',
65 5
                't',
66 5
                InputOption::VALUE_OPTIONAL,
67 5
                'A comma-separated list of tags to filter results'
68
            )
69 5
            ->addOption(
70 5
                'orderBy',
71 5
                'o',
72 5
                InputOption::VALUE_OPTIONAL,
73 5
                'The field from which we want to order by. Pass ASC or DESC separated by a comma'
74
            )
75 5
            ->addOption('showTags', null, InputOption::VALUE_NONE, 'Whether to display the tags or not');
76
    }
77
78 5
    protected function execute(InputInterface $input, OutputInterface $output): void
79
    {
80 5
        $io = new SymfonyStyle($input, $output);
81 5
        $page = (int) $input->getOption('page');
82 5
        $searchTerm = $input->getOption('searchTerm');
83 5
        $tags = $input->getOption('tags');
84 5
        $tags = ! empty($tags) ? explode(',', $tags) : [];
0 ignored issues
show
Bug introduced by
It seems like $tags can also be of type string[]; however, parameter $string of explode() 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

84
        $tags = ! empty($tags) ? explode(',', /** @scrutinizer ignore-type */ $tags) : [];
Loading history...
85 5
        $showTags = $input->getOption('showTags');
86 5
        $transformer = new ShortUrlDataTransformer($this->domainConfig);
87
88
        do {
89 5
            $result = $this->shortUrlService->listShortUrls($page, $searchTerm, $tags, $this->processOrderBy($input));
90 5
            $page++;
91
92 5
            $headers = ['Short code', 'Short URL', 'Long URL', 'Date created', 'Visits count'];
93 5
            if ($showTags) {
94 1
                $headers[] = 'Tags';
95
            }
96
97 5
            $rows = [];
98 5
            foreach ($result as $row) {
99 2
                $shortUrl = $transformer->transform($row);
100 2
                if ($showTags) {
101
                    $shortUrl['tags'] = implode(', ', $shortUrl['tags']);
102
                } else {
103 2
                    unset($shortUrl['tags']);
104
                }
105
106 2
                unset($shortUrl['originalUrl']);
107 2
                $rows[] = array_values($shortUrl);
108
            }
109 5
            $io->table($headers, $rows);
110
111 5
            if ($this->isLastPage($result)) {
112 3
                $continue = false;
113 3
                $io->success('Short URLs properly listed');
114
            } else {
115 2
                $continue = $io->confirm(sprintf('Continue with page <options=bold>%s</>?', $page), false);
116
            }
117 5
        } while ($continue);
118
    }
119
120 5
    private function processOrderBy(InputInterface $input)
121
    {
122 5
        $orderBy = $input->getOption('orderBy');
123 5
        if (empty($orderBy)) {
124 5
            return null;
125
        }
126
127
        $orderBy = explode(',', $orderBy);
0 ignored issues
show
Bug introduced by
It seems like $orderBy can also be of type string[]; however, parameter $string of explode() 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

127
        $orderBy = explode(',', /** @scrutinizer ignore-type */ $orderBy);
Loading history...
128
        return count($orderBy) === 1 ? $orderBy[0] : [$orderBy[0] => $orderBy[1]];
129
    }
130
}
131