Passed
Push — master ( bc2cf1...5553cf )
by Hannes
03:34
created

DonorArgument::readDonor()   C

Complexity

Conditions 12
Paths 13

Size

Total Lines 48
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 12
eloc 24
c 1
b 0
f 0
nc 13
nop 1
dl 0
loc 48
rs 6.9666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of byrokrat\giroapp.
4
 *
5
 * byrokrat\giroapp is free software: you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License as published
7
 * by the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * byrokrat\giroapp is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with byrokrat\giroapp. If not, see <http://www.gnu.org/licenses/>.
17
 *
18
 * Copyright 2016-19 Hannes Forsgård
19
 */
20
21
declare(strict_types = 1);
22
23
namespace byrokrat\giroapp\Console\Helper;
24
25
use byrokrat\giroapp\DependencyInjection\DonorQueryProperty;
26
use byrokrat\giroapp\Exception\DonorDoesNotExistException;
27
use byrokrat\giroapp\Exception\RuntimeException;
28
use byrokrat\giroapp\Domain\Donor;
29
use byrokrat\giroapp\Validator\StringValidator;
30
use Symfony\Component\Console\Command\Command;
31
use Symfony\Component\Console\Input\InputArgument;
32
use Symfony\Component\Console\Input\InputInterface;
33
use Symfony\Component\Console\Input\InputOption;
34
35
/**
36
 * Methods for fetching donors based on command line argument
37
 */
38
trait DonorArgument
39
{
40
    use DonorQueryProperty;
41
42
    protected function configureDonorArgument(Command $command, bool $required = true): void
43
    {
44
        $requiredFlag = $required ? InputArgument::REQUIRED : InputArgument::OPTIONAL;
45
        $command->addArgument('donor', $requiredFlag, 'Donor identified by mandate key, payer number or name');
46
        $command->addOption('id-payer-number', null, InputOption::VALUE_NONE, 'Only use payer number as donor id');
47
        $command->addOption('id-mandate-key', null, InputOption::VALUE_NONE, 'Only use mandate key as donor id');
48
    }
49
50
    public function readDonor(InputInterface $input): Donor
51
    {
52
        $taintedId = $input->getArgument('donor');
53
54
        if (!is_string($taintedId)) {
55
            throw new \LogicException('Donor key must be string');
56
        }
57
58
        $donorId = (new StringValidator)->validate('donor', $taintedId);
59
60
        if ($input->getOption('id-payer-number') && $input->getOption('id-mandate-key')) {
61
            throw new RuntimeException("Illegal to use the 'id-payer-number' and 'id-mandate-key' flags toghether.");
62
        }
63
64
        if ($input->getOption('id-payer-number')) {
65
            return $this->donorQuery->requireByPayerNumber($donorId);
66
        }
67
68
        if ($input->getOption('id-mandate-key')) {
69
            return $this->donorQuery->requireByMandateKey($donorId);
70
        }
71
72
        if ($donor = $this->donorQuery->findByPayerNumber($donorId)) {
73
            return $donor;
74
        }
75
76
        if ($donor = $this->donorQuery->findByMandateKey($donorId)) {
77
            return $donor;
78
        }
79
80
        $regexp = '/'. preg_quote($donorId, '/') . '/i';
81
82
        $matchedDonor = null;
83
84
        foreach ($this->donorQuery->findAll() as $donor) {
85
            if (preg_match($regexp, $donor->getName())) {
86
                if ($matchedDonor) {
87
                    throw new DonorDoesNotExistException("Unable to find donor '$donorId', more than one match.");
88
                }
89
                $matchedDonor = $donor;
90
            }
91
        }
92
93
        if ($matchedDonor) {
0 ignored issues
show
introduced by
$matchedDonor is of type null, thus it always evaluated to false.
Loading history...
94
            return $matchedDonor;
95
        }
96
97
        throw new DonorDoesNotExistException("Unable to find donor '$donorId'");
98
    }
99
}
100