transformOptionsToFilters()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 8
nc 5
nop 1
dl 0
loc 14
rs 10
c 0
b 0
f 0
ccs 8
cts 8
cp 1
crap 4
1
<?php
2
/**
3
 * File: GetModelDetailsCommand.php
4
 *
5
 * @author      Maciej Sławik <[email protected]>
6
 * Github:      https://github.com/maciejslawik
7
 */
8
9
namespace MSlwk\Otomoto\Cli\Command;
10
11
use MSlwk\Otomoto\App\Exception\NoSuchFilterException;
12
use MSlwk\Otomoto\App\Manufacturer\Data\ManufacturerDTO;
13
use MSlwk\Otomoto\App\Manufacturer\Data\ManufacturerDTOInterface;
14
use MSlwk\Otomoto\App\Model\Data\ModelDTO;
15
use MSlwk\Otomoto\App\Model\Data\ModelDTOInterface;
16
use MSlwk\Otomoto\App\Stats\Data\StatsDTOInterface;
17
use MSlwk\Otomoto\App\Stats\Filter\FilterArray;
18
use MSlwk\Otomoto\App\Stats\Filter\FilterFactory;
19
use MSlwk\Otomoto\Middleware\App\Stats\StatsFactory;
20
use Symfony\Component\Console\Command\Command;
21
use Symfony\Component\Console\Input\InputInterface;
22
use Symfony\Component\Console\Input\InputOption;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use Symfony\Component\Console\Input\InputArgument;
25
26
/**
27
 * Class GetModelDetailsCommand
28
 * @package MSlwk\Otomoto\Cli\Command
29
 */
30
class GetModelDetailsCommand extends Command
31
{
32
    const COMMAND_NAME = 'app:model-details';
33
    const COMMAND_DESC = 'Retrieve stats for car model';
34
35
    const MANUFACTURER_ARG_NAME = 'manufacturer';
36
    const MANUFACTURER_ARG_DESC = 'Full manufacturer name';
37
38
    const MODEL_ARG_NAME = 'model';
39
    const MODEL_ARG_DESC = 'Full model name';
40
41
    const FROM_YEAR_OPTION_NAME = 'from';
42
    const FROM_YEAR_OPTION_DESC = 'From year of production';
43
    const FROM_YEAR_OPTION_SHORTCUT = 'f';
44
45
    const TO_YEAR_OPTION_NAME = 'to';
46
    const TO_YEAR_OPTION_DESC = 'To year of production';
47
    const TO_YEAR_OPTION_SHORTCUT = 't';
48
49
    /**
50
     * @var StatsFactory
51
     */
52
    private $statsFactory;
53
54
    /**
55
     * @var FilterFactory
56
     */
57
    private $filterFactory;
58
59
    /**
60
     * GetModelDetailsCommand constructor.
61
     * @param StatsFactory|null $statsFactory
62
     * @param FilterFactory|null $filterFactory
63
     * @param null $name
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $name is correct as it would always require null to be passed?
Loading history...
64
     */
65 4
    public function __construct(
66
        StatsFactory $statsFactory = null,
67
        FilterFactory $filterFactory = null,
68
        $name = null
69
    ) {
70 4
        parent::__construct($name);
71 4
        $this->statsFactory = $statsFactory ?? new StatsFactory();
72 4
        $this->filterFactory = $filterFactory ?? new FilterFactory();
73 4
    }
74
75
    /**
76
     * @inheritdoc
77
     */
78 4
    protected function configure()
79
    {
80 4
        $this->setName(self::COMMAND_NAME)
81 4
            ->setDescription(self::COMMAND_DESC)
82 4
            ->addArgument(
83 4
                self::MANUFACTURER_ARG_NAME,
84 4
                InputArgument::REQUIRED,
85 4
                self::MANUFACTURER_ARG_DESC
86 4
            )->addArgument(
87 4
                self::MODEL_ARG_NAME,
88 4
                InputArgument::REQUIRED,
89 4
                self::MODEL_ARG_DESC
90 4
            )->addOption(
91 4
                self::FROM_YEAR_OPTION_NAME,
92 4
                self::FROM_YEAR_OPTION_SHORTCUT,
93 4
                InputOption::VALUE_OPTIONAL,
94 4
                self::FROM_YEAR_OPTION_DESC
95 4
            )->addOption(
96 4
                self::TO_YEAR_OPTION_NAME,
97 4
                self::TO_YEAR_OPTION_SHORTCUT,
98 4
                InputOption::VALUE_OPTIONAL,
99 4
                self::TO_YEAR_OPTION_DESC
100
            );
101
102 4
        parent::configure();
103 4
    }
104
105
    /**
106
     * @param InputInterface $input
107
     * @param OutputInterface $output
108
     * @return void
109
     */
110 1
    protected function execute(InputInterface $input, OutputInterface $output)
111
    {
112 1
        $manufacturerName = $input->getArgument(self::MANUFACTURER_ARG_NAME);
113 1
        $modelName = $input->getArgument(self::MODEL_ARG_NAME);
114 1
        $options = $input->getOptions();
115
116 1
        $manufacturer = new ManufacturerDTO($manufacturerName);
0 ignored issues
show
Bug introduced by
It seems like $manufacturerName can also be of type null and string[]; however, parameter $name of MSlwk\Otomoto\App\Manufa...turerDTO::__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

116
        $manufacturer = new ManufacturerDTO(/** @scrutinizer ignore-type */ $manufacturerName);
Loading history...
117 1
        $model = new ModelDTO($modelName);
0 ignored issues
show
Bug introduced by
It seems like $modelName can also be of type null and string[]; however, parameter $name of MSlwk\Otomoto\App\Model\...ModelDTO::__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

117
        $model = new ModelDTO(/** @scrutinizer ignore-type */ $modelName);
Loading history...
118 1
        $filters = $this->transformOptionsToFilters($options);
119
120 1
        $this->displaySearchParams($manufacturer, $model, $filters, $output);
121
122 1
        $statsMiddleware = $this->statsFactory->create();
123 1
        $stats = $statsMiddleware->getStats($manufacturer, $model, $filters);
124
125 1
        $this->displayStats($stats, $output);
126 1
    }
127
128
    /**
129
     * @param array $options
130
     * @return FilterArray
131
     */
132 1
    private function transformOptionsToFilters(array $options): FilterArray
133
    {
134 1
        $filterArray = new FilterArray();
135 1
        foreach ($options as $name => $value) {
136
            try {
137 1
                if ($value) {
138 1
                    $filter = $this->filterFactory->create($name, $value);
139 1
                    $filterArray->add($filter);
140
                }
141 1
            } catch (NoSuchFilterException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
142
143
            }
144
        }
145 1
        return $filterArray;
146
    }
147
148
    /**
149
     * @param float $average
150
     * @return float
151
     */
152 1
    private function formatStatsData(float $average): float
153
    {
154 1
        return round($average);
155
    }
156
157
    /**
158
     * @param ManufacturerDTOInterface $manufacturer
159
     * @param ModelDTOInterface $model
160
     * @param FilterArray $filters
161
     * @param OutputInterface $output
162
     * @return void
163
     */
164 1
    private function displaySearchParams(
165
        ManufacturerDTOInterface $manufacturer,
166
        ModelDTOInterface $model,
167
        FilterArray $filters,
168
        OutputInterface $output
169
    ): void {
170 1
        $output->writeln(
171 1
            "<info>Manufacturer: {$manufacturer->getName()}</info>"
172
        );
173 1
        $output->writeln(
174 1
            "<info>Model: {$model->getName()}</info>"
175
        );
176 1
        foreach ($filters as $filter) {
177 1
            $output->writeln(
178 1
                "<info>{$filter->getDescription()}: {$filter->getValue()}</info>"
179
            );
180
        }
181 1
    }
182
183
    /**
184
     * @param StatsDTOInterface $stats
185
     * @param OutputInterface $output
186
     * @return void
187
     */
188 1
    private function displayStats(StatsDTOInterface $stats, OutputInterface $output): void
189
    {
190 1
        $output->writeln(
191 1
            "<comment>Average mileage: {$this->formatStatsData($stats->getAverageMileage())} km</comment>"
192
        );
193 1
        $output->writeln(
194 1
            "<comment>Average price: {$this->formatStatsData($stats->getAveragePrice())} PLN</comment>"
195
        );
196 1
        $output->writeln(
197 1
            "<comment>Average year: {$this->formatStatsData($stats->getAverageYear())}</comment>"
198
        );
199 1
    }
200
}
201