Completed
Push — feature/fixing_cost ( ef981e )
by Laurent
01:53
created

FlightValidator   C

Complexity

Total Complexity 54

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 0
loc 257
rs 6.4799
c 0
b 0
f 0
wmc 54
lcom 1
cbo 3

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A isValid() 0 19 2
A isGroupedFlight() 0 4 2
A isHourValid() 0 5 4
A fetchService() 0 5 1
A getMinPrice() 0 7 2
C checkBillingInformation() 0 23 12
A checkInstructionInformation() 0 15 4
B checkPassengersInformation() 0 26 7
A checkKilometers() 0 14 5
B checkFlightInformation() 0 24 7
A checkOrderInformation() 0 21 5
A checkFlightDate() 0 8 2

How to fix   Complexity   

Complex Class

Complex classes like FlightValidator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FlightValidator, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
require_once __DIR__ . '/AbstractValidator.php';
4
require_once __DIR__ . '/../class/bbcvols.class.php';
5
6
/**
7
 * Validates a flight
8
 *
9
 * @author Laurent De Coninck <[email protected]>
10
 */
11
class FlightValidator extends AbstractValidator
12
{
13
    /**
14
     * @var Product
15
     */
16
    private $defaultService;
17
18
    /**
19
     * @inheritDoc
20
     */
21
    public function __construct(Translate $langs, DoliDB $db, $defaultServiceId)
22
    {
23
        parent::__construct($langs, $db);
24
        $this->fetchService($defaultServiceId);
25
    }
26
27
    /**
28
     * {@inheritdoc}
29
     */
30
    public function isValid($flight, $context = [])
31
    {
32
        if (!($flight instanceof Bbcvols)) {
33
            throw new \InvalidArgumentException('Flight validator only accepts a flight');
34
        }
35
36
        $this->valid = true;
37
38
        $this
39
            ->checkFlightDate($flight)
40
            ->checkFlightInformation($flight)
41
            ->checkPassengersInformation($flight)
42
            ->checkInstructionInformation($flight, $context)
43
            ->checkBillingInformation($flight, $context)
44
            ->checkKilometers($flight)
45
            ->checkOrderInformation($flight);
46
47
        return $this->valid;
48
    }
49
50
    /**
51
     * @param array $context
52
     *
53
     * @return bool
54
     */
55
    private function isGroupedFlight($context)
56
    {
57
        return key_exists('grouped_flight', $context) && !empty($context['grouped_flight']);
58
    }
59
60
    /**
61
     * @param string $hour
62
     *
63
     * @return bool
64
     */
65
    private function isHourValid($hour)
66
    {
67
        $patern = '(([0-9]{4})|([0-9]{2}:[0-9]{2}(:[0-9]{2})?))';
68
        return !(preg_match($patern, $hour) == 0 || (strlen($hour) != 4 && strlen($hour) != 8 && strlen($hour) != 5));
69
    }
70
71
    /**
72
     * @param $defaultServiceId
73
     */
74
    private function fetchService($defaultServiceId)
75
    {
76
        $this->defaultService = new Product($this->db);
77
        $this->defaultService->fetch($defaultServiceId);
78
    }
79
80
    /**
81
     * Returns the minimum price.
82
     *
83
     * @return int
84
     */
85
    private function getMinPrice()
86
    {
87
        if ($this->defaultService->price_base_type == 'TTC') {
88
            return $this->defaultService->price_min;
89
        }
90
        return $this->defaultService->price_min_ttc;
91
    }
92
93
    /**
94
     * @param Bbcvols $vol
95
     * @param array $context
96
     *
97
     * @return $this
98
     */
99
    private function checkBillingInformation($vol, $context)
100
    {
101
        if ($vol->isLinkedToOrder() || $vol->isBilled()) {
102
            return $this;
103
        }
104
105
        if ((!$this->isGroupedFlight($context) || $vol->getPilotId() === $vol->getFkReceiver()) && $vol->getFlightType()->isBillingRequired() && $vol->isFree()) {
106
            $this->addError('cost', 'Erreur ce type de vol doit être payant.');
107
        }
108
109
        if ($vol->getFlightType()->isBillingRequired() && !$vol->hasReceiver()) {
110
            $this->addError('cost',
111
                'Erreur ce type de vol doit être payant, mais personne n\'a été signalé comme recepteur d\'argent.');
112
        }
113
114
        if (!$this->isGroupedFlight($context) && $vol->getFlightType()->isBillingRequired() && ($vol->getAmountPerPassenger()) < $this->getMinPrice()) {
115
            $this->addError('cost',
116
                sprintf('Le montant demandé pour ce vol n\'est pas suffisant un minimum de %s euros est demandé',
117
                    $this->getMinPrice()));
118
        }
119
120
        return $this;
121
    }
122
123
    /**
124
     * @param Bbcvols $vol
125
     * @param array $context
126
     *
127
     * @return $this
128
     */
129
    private function checkInstructionInformation($vol, $context)
130
    {
131
        if ($vol->isInstruction()) {
132
            if ($vol->getPilotId() === $vol->getOrganisatorId()) {
133
                $this->addError('organisator',
134
                    'l\'organisateur d\'un vol d\'instruction doit être l\'instructeur et non le pilote');
135
            }
136
137
            if ($this->isGroupedFlight($context)) {
138
                $this->addError('alone', "Le vol d'instruction est un vol à un seul ballon.");
139
            }
140
        }
141
142
        return $this;
143
    }
144
145
    /**
146
     * @param Bbcvols $vol
147
     *
148
     * @return $this
149
     */
150
    private function checkPassengersInformation($vol)
151
    {
152
        if (!is_numeric($vol->nbrPax) || (int)$vol->nbrPax < 0) {
153
            $this->addError('nbrPax', 'Erreur le nombre de passager est un nombre négatif.');
154
        }
155
156
        if (!$vol->mustHavePax()) {
157
            return $this;
158
        }
159
160
        if (!$vol->hasPax()) {
161
            $this->addError('nbrPax', 'Erreur ce type de vol doit etre fait avec des passagers.');
162
        }
163
164
        if (empty(trim($vol->getPassengerNames()))) {
165
            $this->addError('passenger_names', 'Le nom des passagers est obligatoire.');
166
        }
167
168
        $passengers = explode(';', $vol->getPassengerNames());
169
        if (count($passengers) !== $vol->getNumberOfPassengers()) {
170
            $this->addError('passenger_names',
171
                'Le nombre de noms des passagers doit être égale au nombre de passagers.');
172
        }
173
174
        return $this;
175
    }
176
177
    /**
178
     * @param Bbcvols $vol
179
     *
180
     * @return $this
181
     */
182
    private function checkKilometers($vol)
183
    {
184
        if ($vol->hasKilometers() && !$vol->getKilometers() > 0) {
185
            $this->addError('kilometers',
186
                'Les kilometres doivent être un nombre positif');
187
        }
188
189
        if ($vol->hasKilometers() && !$vol->hasKilometersDescription()) {
190
            $this->addError('justif_kilometers',
191
                'Vous essayez d\'encoder des kilometres sans justificatif.');
192
        }
193
194
        return $this;
195
    }
196
197
    /**
198
     * @param Bbcvols $vol
199
     *
200
     * @return $this
201
     */
202
    private function checkFlightInformation($vol)
203
    {
204
        if (!$this->isHourValid($vol->heureD)) {
205
            $this->addError('heureD', "L'heure depart n'est pas correcte'");
206
        }
207
208
        if (!$this->isHourValid($vol->heureA)) {
209
            $this->addError('heureA', 'L\'heure d\'arrivee n\'est pas correcte');
210
        }
211
212
        if (empty($this->errors) && ($vol->heureA - $vol->heureD) <= 0) {
213
            $this->addError('heures', 'L\'heure de depart est plus grande  que l\'heure d\'arrivee');
214
        }
215
216
        if (empty($vol->lieuD)) {
217
            $this->addError('lieuD', 'Le lieu de départ est vide');
218
        }
219
220
        if (empty($vol->lieuA)) {
221
            $this->addError('lieuA', 'Le lieu d\'arrivée est vide');
222
        }
223
224
        return $this;
225
    }
226
227
    /**
228
     * @param Bbcvols $vol
229
     *
230
     * @return $this
231
     */
232
    private function checkOrderInformation(Bbcvols $vol)
233
    {
234
        if (!$vol->isLinkedToOrder()) {
235
            return $this;
236
        }
237
238
        $totalPassenegrs = 0;
239
        foreach ($vol->getOrderIds() as $orderId => $nbrPassengers) {
240
            if ($nbrPassengers <= 0) {
241
                $this->addError('order_id', 'Le nombre de passager par commande doit être >= 0.');
242
            }
243
244
            $totalPassenegrs += (int)$nbrPassengers;
245
        }
246
247
        if ($totalPassenegrs !== (int)$vol->getNumberOfPassengers()) {
248
            $this->addError('nbrPax', 'Le nombre de passagers ne correspond pas au nombre entré sur les commandes');
249
        }
250
251
        return $this;
252
    }
253
254
    /**
255
     * @param Bbcvols $flight
256
     *
257
     * @return $this
258
     */
259
    private function checkFlightDate(Bbcvols $flight)
260
    {
261
        if($flight->getDate() > new DateTimeImmutable()){
262
            $this->addError('date', 'La date est plus grande que la date d\'aujourd\'hui');
263
        }
264
265
        return $this;
266
    }
267
}