GetVisitsCommand   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Test Coverage

Coverage 85.29%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 8
eloc 28
dl 0
loc 61
ccs 29
cts 34
cp 0.8529
rs 10
c 1
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A interact() 0 11 3
A __construct() 0 4 1
A getStartDateDesc() 0 3 1
A getEndDateDesc() 0 3 1
A execute() 0 16 1
A doConfigure() 0 7 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Shlinkio\Shlink\CLI\Command\ShortUrl;
6
7
use Shlinkio\Shlink\CLI\Command\Util\AbstractWithDateRangeCommand;
8
use Shlinkio\Shlink\CLI\Util\ExitCodes;
9
use Shlinkio\Shlink\CLI\Util\ShlinkTable;
10
use Shlinkio\Shlink\Common\Util\DateRange;
11
use Shlinkio\Shlink\Core\Entity\Visit;
12
use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
13
use Shlinkio\Shlink\Core\Model\VisitsParams;
14
use Shlinkio\Shlink\Core\Service\VisitsTrackerInterface;
15
use Shlinkio\Shlink\Core\Visit\Model\UnknownVisitLocation;
16
use Symfony\Component\Console\Input\InputArgument;
17
use Symfony\Component\Console\Input\InputInterface;
18
use Symfony\Component\Console\Input\InputOption;
19
use Symfony\Component\Console\Output\OutputInterface;
20
use Symfony\Component\Console\Style\SymfonyStyle;
21
22
use function Functional\map;
23
use function Functional\select_keys;
24
25
class GetVisitsCommand extends AbstractWithDateRangeCommand
26
{
27
    public const NAME = 'short-url:visits';
28
29
    private VisitsTrackerInterface $visitsTracker;
30
31 4
    public function __construct(VisitsTrackerInterface $visitsTracker)
32
    {
33 4
        $this->visitsTracker = $visitsTracker;
34 4
        parent::__construct();
35 4
    }
36
37 4
    protected function doConfigure(): void
38
    {
39
        $this
40 4
            ->setName(self::NAME)
41 4
            ->setDescription('Returns the detailed visits information for provided short code')
42 4
            ->addArgument('shortCode', InputArgument::REQUIRED, 'The short code which visits we want to get')
43 4
            ->addOption('domain', 'd', InputOption::VALUE_REQUIRED, 'The domain for the short code');
44 4
    }
45
46 4
    protected function getStartDateDesc(): string
47
    {
48 4
        return 'Allows to filter visits, returning only those older than start date';
49
    }
50
51 4
    protected function getEndDateDesc(): string
52
    {
53 4
        return 'Allows to filter visits, returning only those newer than end date';
54
    }
55
56 4
    protected function interact(InputInterface $input, OutputInterface $output): void
57
    {
58 4
        $shortCode = $input->getArgument('shortCode');
59 4
        if (! empty($shortCode)) {
60 4
            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 4
    protected function execute(InputInterface $input, OutputInterface $output): ?int
71
    {
72 4
        $identifier = ShortUrlIdentifier::fromCli($input);
73 4
        $startDate = $this->getDateOption($input, $output, 'startDate');
74 4
        $endDate = $this->getDateOption($input, $output, 'endDate');
75
76 4
        $paginator = $this->visitsTracker->info($identifier, new VisitsParams(new DateRange($startDate, $endDate)));
77
78
        $rows = map($paginator->getCurrentItems(), function (Visit $visit) {
79 1
            $rowData = $visit->jsonSerialize();
80 1
            $rowData['country'] = ($visit->getVisitLocation() ?? new UnknownVisitLocation())->getCountryName();
81 1
            return select_keys($rowData, ['referer', 'date', 'userAgent', 'country']);
82 4
        });
83 4
        ShlinkTable::fromOutput($output)->render(['Referer', 'Date', 'User agent', 'Country'], $rows);
84
85 4
        return ExitCodes::EXIT_SUCCESS;
86
    }
87
}
88