Completed
Pull Request — master (#278)
by Alejandro
03:36 queued 01:25
created

GetVisitsCommand::configure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 15
nc 1
nop 0
dl 0
loc 18
ccs 15
cts 15
cp 1
crap 1
rs 9.7666
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
5
6
use Cake\Chronos\Chronos;
7
use Shlinkio\Shlink\Common\Util\DateRange;
8
use Shlinkio\Shlink\Core\Entity\Visit;
9
use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
10
use Symfony\Component\Console\Command\Command;
11
use Symfony\Component\Console\Input\InputArgument;
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\Style\SymfonyStyle;
16
use function array_map;
17
use function Functional\select_keys;
18
19
class GetVisitsCommand extends Command
20
{
21
    public const NAME = 'short-url:visits';
22
    private const ALIASES = ['shortcode:visits', 'short-code:visits'];
23
24
    /**
25
     * @var VisitsTrackerInterface
26
     */
27
    private $visitsTracker;
28
29 3
    public function __construct(VisitsTrackerInterface $visitsTracker)
30
    {
31 3
        $this->visitsTracker = $visitsTracker;
32 3
        parent::__construct();
33
    }
34
35 3
    protected function configure(): void
36
    {
37
        $this
38 3
            ->setName(self::NAME)
39 3
            ->setAliases(self::ALIASES)
40 3
            ->setDescription('Returns the detailed visits information for provided short code')
41 3
            ->addArgument('shortCode', InputArgument::REQUIRED, 'The short code which visits we want to get')
42 3
            ->addOption(
43 3
                'startDate',
44 3
                's',
45 3
                InputOption::VALUE_OPTIONAL,
46 3
                'Allows to filter visits, returning only those older than start date'
47
            )
48 3
            ->addOption(
49 3
                'endDate',
50 3
                'e',
51 3
                InputOption::VALUE_OPTIONAL,
52 3
                'Allows to filter visits, returning only those newer than end date'
53
            );
54
    }
55
56 3
    protected function interact(InputInterface $input, OutputInterface $output): void
57
    {
58 3
        $shortCode = $input->getArgument('shortCode');
59 3
        if (! empty($shortCode)) {
60 3
            return;
61
        }
62
63
        $io = new SymfonyStyle($input, $output);
64
        $shortCode = $io->ask('A short code was not provided. Which short code do you want to use?');
65
        if (! empty($shortCode)) {
66
            $input->setArgument('shortCode', $shortCode);
67
        }
68
    }
69
70 3
    protected function execute(InputInterface $input, OutputInterface $output): void
71
    {
72 3
        $io = new SymfonyStyle($input, $output);
73 3
        $shortCode = $input->getArgument('shortCode');
74 3
        $startDate = $this->getDateOption($input, 'startDate');
75 3
        $endDate = $this->getDateOption($input, 'endDate');
76
77 3
        $visits = $this->visitsTracker->info($shortCode, new DateRange($startDate, $endDate));
0 ignored issues
show
Bug introduced by
It seems like $shortCode can also be of type null and string[]; however, parameter $shortCode of Shlinkio\Shlink\Core\Ser...rackerInterface::info() 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

77
        $visits = $this->visitsTracker->info(/** @scrutinizer ignore-type */ $shortCode, new DateRange($startDate, $endDate));
Loading history...
78
        $rows = array_map(function (Visit $visit) {
79 1
            $rowData = $visit->jsonSerialize();
80 1
            $rowData['country'] = $visit->getVisitLocation()->getCountryName();
81 1
            return select_keys($rowData, ['referer', 'date', 'userAgent', 'country']);
82 3
        }, $visits);
83 3
        $io->table(['Referer', 'Date', 'User agent', 'Country'], $rows);
84
    }
85
86 3
    private function getDateOption(InputInterface $input, $key)
87
    {
88 3
        $value = $input->getOption($key);
89 3
        return ! empty($value) ? Chronos::parse($value) : $value;
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type string[]; however, parameter $time of Cake\Chronos\Chronos::parse() 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

89
        return ! empty($value) ? Chronos::parse(/** @scrutinizer ignore-type */ $value) : $value;
Loading history...
90
    }
91
}
92