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

GetVisitsCommand   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Test Coverage

Coverage 90.2%

Importance

Changes 0
Metric Value
eloc 52
dl 0
loc 89
ccs 46
cts 51
cp 0.902
rs 10
c 0
b 0
f 0
wmc 8

5 Methods

Rating   Name   Duplication   Size   Complexity  
A interact() 0 13 3
A configure() 0 24 1
A execute() 0 19 1
A getDateOption() 0 4 2
A __construct() 0 5 1
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 Zend\I18n\Translator\TranslatorInterface;
17
use function array_map;
18
use function Functional\select_keys;
19
20
class GetVisitsCommand extends Command
21
{
22
    public const NAME = 'short-url:visits';
23
    private const ALIASES = ['shortcode:visits', 'short-code:visits'];
24
25
    /**
26
     * @var VisitsTrackerInterface
27
     */
28
    private $visitsTracker;
29
    /**
30
     * @var TranslatorInterface
31
     */
32
    private $translator;
33
34 3
    public function __construct(VisitsTrackerInterface $visitsTracker, TranslatorInterface $translator)
35
    {
36 3
        $this->visitsTracker = $visitsTracker;
37 3
        $this->translator = $translator;
38 3
        parent::__construct();
39
    }
40
41 3
    protected function configure(): void
42
    {
43
        $this
44 3
            ->setName(self::NAME)
45 3
            ->setAliases(self::ALIASES)
46 3
            ->setDescription(
47 3
                $this->translator->translate('Returns the detailed visits information for provided short code')
48
            )
49 3
            ->addArgument(
50 3
                'shortCode',
51 3
                InputArgument::REQUIRED,
52 3
                $this->translator->translate('The short code which visits we want to get')
53
            )
54 3
            ->addOption(
55 3
                'startDate',
56 3
                's',
57 3
                InputOption::VALUE_OPTIONAL,
58 3
                $this->translator->translate('Allows to filter visits, returning only those older than start date')
59
            )
60 3
            ->addOption(
61 3
                'endDate',
62 3
                'e',
63 3
                InputOption::VALUE_OPTIONAL,
64 3
                $this->translator->translate('Allows to filter visits, returning only those newer than end date')
65
            );
66
    }
67
68 3
    protected function interact(InputInterface $input, OutputInterface $output): void
69
    {
70 3
        $shortCode = $input->getArgument('shortCode');
71 3
        if (! empty($shortCode)) {
72 3
            return;
73
        }
74
75
        $io = new SymfonyStyle($input, $output);
76
        $shortCode = $io->ask(
77
            $this->translator->translate('A short code was not provided. Which short code do you want to use?')
78
        );
79
        if (! empty($shortCode)) {
80
            $input->setArgument('shortCode', $shortCode);
81
        }
82
    }
83
84 3
    protected function execute(InputInterface $input, OutputInterface $output): void
85
    {
86 3
        $io = new SymfonyStyle($input, $output);
87 3
        $shortCode = $input->getArgument('shortCode');
88 3
        $startDate = $this->getDateOption($input, 'startDate');
89 3
        $endDate = $this->getDateOption($input, 'endDate');
90
91 3
        $visits = $this->visitsTracker->info($shortCode, new DateRange($startDate, $endDate));
92
        $rows = array_map(function (Visit $visit) {
93 1
            $rowData = $visit->jsonSerialize();
94 1
            $rowData['country'] = $visit->getVisitLocation()->getCountryName();
95 1
            return select_keys($rowData, ['referer', 'date', 'userAgent', 'country']);
96 3
        }, $visits);
97 3
        $io->table([
98 3
            $this->translator->translate('Referer'),
99 3
            $this->translator->translate('Date'),
100 3
            $this->translator->translate('User agent'),
101 3
            $this->translator->translate('Country'),
102 3
        ], $rows);
103
    }
104
105 3
    private function getDateOption(InputInterface $input, $key)
106
    {
107 3
        $value = $input->getOption($key);
108 3
        return ! empty($value) ? Chronos::parse($value) : $value;
109
    }
110
}
111