RoutingCommand   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 14
eloc 72
c 3
b 0
f 0
dl 0
loc 138
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 13 1
F execute() 0 93 12
A __construct() 0 5 1
1
<?php
2
3
namespace DH\NavigationBundle\Command;
4
5
use DateTime;
6
use DH\NavigationBundle\Model\Routing\Summary;
7
use DH\NavigationBundle\NavigationManager;
8
use Symfony\Component\Console\Command\Command;
9
use Symfony\Component\Console\Exception\InvalidArgumentException;
10
use Symfony\Component\Console\Helper\Table;
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
16
class RoutingCommand extends Command
17
{
18
    protected static $defaultName = 'navigation:routing';
19
20
    /**
21
     * @var NavigationManager
22
     */
23
    private $manager;
24
25
    public function __construct(NavigationManager $manager)
26
    {
27
        $this->manager = $manager;
28
29
        parent::__construct();
30
    }
31
32
    /**
33
     * {@inheritdoc}
34
     */
35
    protected function configure(): void
36
    {
37
        $this
38
            ->setName('navigation:routing')
39
            ->setDescription('Computes a route')
40
            ->addOption('provider', null, InputOption::VALUE_REQUIRED)
41
            ->addOption('waypoint', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Point de passage')
42
            ->addOption('departure', null, InputOption::VALUE_REQUIRED, 'Departure date and time (YYYY-MM-DDD HH:II:SS)')
43
            ->addOption('arrival', null, InputOption::VALUE_REQUIRED, 'Arrival date and time (YYYY-MM-DDD HH:II:SS)')
44
            ->addOption('traffic', null, InputOption::VALUE_REQUIRED, 'Traffic mode (enabled/disabled/default depending on provider)')
45
            ->addOption('language', null, InputOption::VALUE_REQUIRED, 'Language (fr-FR, en-US, etc.)')
46
            ->setHelp(
47
                <<<'EOF'
48
The <info>navigation:routing</info> command will compute a route from the given addresses.
49
50
You can choose a provider with the "provider" option.
51
52
<info>php bin/console navigation:routing --waypoint="45.834278,1.260816" --waypoint="44.830109,-0.603649" --provider=here</info>
53
EOF
54
            )
55
        ;
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     */
61
    protected function execute(InputInterface $input, OutputInterface $output)
62
    {
63
        if (\count($input->getOption('waypoint')) < 2) {
0 ignored issues
show
Bug introduced by
It seems like $input->getOption('waypoint') can also be of type boolean and string; however, parameter $var of count() does only seem to accept Countable|array, 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

63
        if (\count(/** @scrutinizer ignore-type */ $input->getOption('waypoint')) < 2) {
Loading history...
64
            throw new InvalidArgumentException('A route needs at least two waypoints (start and end locations).');
65
        }
66
67
        if ($input->getOption('provider')) {
68
            $this->manager->using($input->getOption('provider'));
69
        }
70
71
        $query = $this->manager->createRoutingQuery();
72
73
        foreach ($input->getOption('waypoint') as $waypoint) {
74
            $query->addWaypoint($waypoint);
75
        }
76
77
        if ($input->getOption('departure')) {
78
            $query->setDepartureTime(new DateTime($input->getOption('departure')));
0 ignored issues
show
Bug introduced by
It seems like $input->getOption('departure') can also be of type string[]; however, parameter $time of DateTime::__construct() 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

78
            $query->setDepartureTime(new DateTime(/** @scrutinizer ignore-type */ $input->getOption('departure')));
Loading history...
79
        }
80
81
        if ($input->getOption('arrival')) {
82
            $query->setArrivalTime(new DateTime($input->getOption('arrival')));
83
        }
84
85
        if ($input->getOption('traffic')) {
86
            $query->setTrafficMode($input->getOption('traffic'));
0 ignored issues
show
Bug introduced by
The method setTrafficMode() does not exist on DH\NavigationBundle\Cont...g\RoutingQueryInterface. It seems like you code against a sub-type of DH\NavigationBundle\Cont...g\RoutingQueryInterface such as DH\NavigationBundle\Prov...re\Routing\RoutingQuery. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

86
            $query->/** @scrutinizer ignore-call */ 
87
                    setTrafficMode($input->getOption('traffic'));
Loading history...
87
        }
88
89
        if ($input->getOption('language')) {
90
            $query->setLanguage($input->getOption('language'));
91
        }
92
93
        $response = $query->execute();
94
95
        $io = new SymfonyStyle($input, $output);
96
97
        $routes = $response->getRoutes();
98
99
        $io->section('Summary');
100
101
        $data = [];
102
        foreach ($routes as $index => $route) {
103
            /**
104
             * @var Summary
105
             */
106
            $summary = $route->getSummary();
107
            $data[] = [
108
                $index + 1,
109
                $summary->getDistance()->getFormattedValue(2),
110
                $summary->getTravelTime()->getFormattedValue(2),
111
            ];
112
        }
113
114
        $table = new Table($output);
115
        $table
116
            ->setHeaders(['route', 'distance', 'duration'])
117
            ->setRows($data)
118
        ;
119
        $table->render();
120
121
        $io->newLine();
122
123
        foreach ($routes as $routeIndex => $route) {
124
            $io->section('Route #'.($routeIndex + 1));
125
126
            $legs = $route->getLegs();
127
            foreach ($legs as $legIndex => $leg) {
128
                $steps = $leg->getSteps();
129
                $io->writeln(sprintf('<comment>Leg #%d</comment> - %d steps.', $legIndex + 1, \count($steps)));
130
131
                $data = [];
132
                foreach ($steps as $stepIndex => $step) {
133
                    $data[] = [
134
                        $stepIndex + 1,
135
                        implode(', ', $step->getPosition()),
136
                        $step->getDistance()->getFormattedValue(2),
137
                        $step->getDuration()->getFormattedValue(2),
138
                        $step->getInstruction(),
139
                    ];
140
                }
141
142
                $table = new Table($output);
143
                $table
144
                    ->setHeaders(['step', 'position', 'distance', 'duration', 'instruction'])
145
                    ->setRows($data)
146
                    ->setColumnMaxWidth(4, 100)
147
                ;
148
                $table->render();
149
                $io->newLine();
150
            }
151
        }
152
153
        return 0;
154
    }
155
}
156