Completed
Push — master ( ccb9d5...d7e68d )
by Alejandro
09:04
created

ListShortcodesCommand::configure()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 43
Code Lines 33

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 33
nc 1
nop 0
dl 0
loc 43
ccs 34
cts 34
cp 1
crap 1
rs 8.8571
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\CLI\Command\Shortcode;
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 Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Helper\QuestionHelper;
11
use Symfony\Component\Console\Helper\Table;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15
use Symfony\Component\Console\Question\ConfirmationQuestion;
16
use Zend\I18n\Translator\TranslatorInterface;
17
18
class ListShortcodesCommand extends Command
19
{
20
    use PaginatorUtilsTrait;
21
22
    /**
23
     * @var ShortUrlServiceInterface
24
     */
25
    private $shortUrlService;
26
    /**
27
     * @var TranslatorInterface
28
     */
29
    private $translator;
30
31 5
    public function __construct(ShortUrlServiceInterface $shortUrlService, TranslatorInterface $translator)
32
    {
33 5
        $this->shortUrlService = $shortUrlService;
34 5
        $this->translator = $translator;
35 5
        parent::__construct(null);
36 5
    }
37
38 5
    public function configure()
39
    {
40 5
        $this->setName('shortcode:list')
41 5
             ->setDescription($this->translator->translate('List all short URLs'))
42 5
             ->addOption(
43 5
                 'page',
44 5
                 'p',
45 5
                 InputOption::VALUE_OPTIONAL,
46 5
                 sprintf(
47 5
                     $this->translator->translate('The first page to list (%s items per page)'),
48 5
                     PaginableRepositoryAdapter::ITEMS_PER_PAGE
49
                 ),
50 5
                 1
51
             )
52 5
             ->addOption(
53 5
                 'searchTerm',
54 5
                 's',
55 5
                 InputOption::VALUE_OPTIONAL,
56 5
                 $this->translator->translate(
57 5
                     'A query used to filter results by searching for it on the longUrl and shortCode fields'
58
                 )
59
             )
60 5
             ->addOption(
61 5
                 'tags',
62 5
                 't',
63 5
                 InputOption::VALUE_OPTIONAL,
64 5
                 $this->translator->translate('A comma-separated list of tags to filter results')
65
             )
66 5
             ->addOption(
67 5
                 'orderBy',
68 5
                 'o',
69 5
                 InputOption::VALUE_OPTIONAL,
70 5
                 $this->translator->translate(
71 5
                     'The field from which we want to order by. Pass ASC or DESC separated by a comma'
72
                 )
73
             )
74 5
             ->addOption(
75 5
                 'showTags',
76 5
                 null,
77 5
                 InputOption::VALUE_NONE,
78 5
                 $this->translator->translate('Whether to display the tags or not')
79
             );
80 5
    }
81
82 5
    public function execute(InputInterface $input, OutputInterface $output)
83
    {
84 5
        $page = (int) $input->getOption('page');
85 5
        $searchTerm = $input->getOption('searchTerm');
86 5
        $tags = $input->getOption('tags');
87 5
        $tags = ! empty($tags) ? explode(',', $tags) : [];
88 5
        $showTags = $input->getOption('showTags');
89
90
        /** @var QuestionHelper $helper */
91 5
        $helper = $this->getHelper('question');
92
93
        do {
94 5
            $result = $this->shortUrlService->listShortUrls($page, $searchTerm, $tags, $this->processOrderBy($input));
95 5
            $page++;
96 5
            $table = new Table($output);
97
98
            $headers = [
99 5
                $this->translator->translate('Short code'),
100 5
                $this->translator->translate('Original URL'),
101 5
                $this->translator->translate('Date created'),
102 5
                $this->translator->translate('Visits count'),
103
            ];
104 5
            if ($showTags) {
105 1
                $headers[] = $this->translator->translate('Tags');
106
            }
107 5
            $table->setHeaders($headers);
108
109 5
            foreach ($result as $row) {
110 2
                $shortUrl = $row->jsonSerialize();
111 2
                if ($showTags) {
112
                    $shortUrl['tags'] = [];
113
                    foreach ($row->getTags() as $tag) {
114
                        $shortUrl['tags'][] = $tag->getName();
115
                    }
116
                    $shortUrl['tags'] = implode(', ', $shortUrl['tags']);
117
                } else {
118 2
                    unset($shortUrl['tags']);
119
                }
120
121 2
                $table->addRow(array_values($shortUrl));
122
            }
123 5
            $table->render();
124
125 5
            if ($this->isLastPage($result)) {
0 ignored issues
show
Bug introduced by
It seems like $result defined by $this->shortUrlService->...processOrderBy($input)) on line 94 can also be of type array<integer,object<Shl...\Core\Entity\ShortUrl>>; however, Shlinkio\Shlink\Common\P...tilsTrait::isLastPage() does only seem to accept object<Zend\Paginator\Paginator>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
126 4
                $continue = false;
127 4
                $output->writeln(
128 4
                    sprintf('<info>%s</info>', $this->translator->translate('You have reached last page'))
129
                );
130
            } else {
131 2
                $continue = $helper->ask($input, $output, new ConfirmationQuestion(
132 2
                    sprintf('<question>' . $this->translator->translate(
133 2
                        'Continue with page'
134 2
                    ) . ' <bg=cyan;options=bold>%s</>? (y/N)</question> ', $page),
135 2
                    false
136
                ));
137
            }
138 5
        } while ($continue);
139 5
    }
140
141 5
    protected function processOrderBy(InputInterface $input)
142
    {
143 5
        $orderBy = $input->getOption('orderBy');
144 5
        if (empty($orderBy)) {
145 5
            return null;
146
        }
147
148
        $orderBy = explode(',', $orderBy);
149
        return count($orderBy) === 1 ? $orderBy[0] : [$orderBy[0] => $orderBy[1]];
150
    }
151
}
152