NormalizeLabelsCommand::execute()   F
last analyzed

Complexity

Conditions 16
Paths 247

Size

Total Lines 106
Code Lines 68

Duplication

Lines 22
Ratio 20.75 %

Importance

Changes 0
Metric Value
dl 22
loc 106
rs 3.7622
c 0
b 0
f 0
cc 16
eloc 68
nc 247
nop 2

How to fix   Long Method    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
namespace Loevgaard\PakkelabelsBundle\Command;
4
5
use Assert\Assert;
6
use Doctrine\Common\Persistence\ObjectManager;
7
use League\ISO3166\ISO3166;
8
use Loevgaard\PakkelabelsBundle\Entity\Label;
9
use Loevgaard\PakkelabelsBundle\Entity\ShippingMethodMapping;
10
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
11
use Symfony\Component\Console\Command\LockableTrait;
12
use Symfony\Component\Console\Input\InputInterface;
13
use Symfony\Component\Console\Input\InputOption;
14
use Symfony\Component\Console\Output\OutputInterface;
15
16
class NormalizeLabelsCommand extends ContainerAwareCommand
17
{
18
    use LockableTrait;
19
20
    protected function configure()
21
    {
22
        $this->setName('loevgaard:pakkelabels:normalize-labels')
23
            ->setDescription('Normalizes labels before creation')
24
            ->addOption('limit', 'l', InputOption::VALUE_REQUIRED, 'The number of labels to normalize', 20)
25
        ;
26
    }
27
28
    protected function execute(InputInterface $input, OutputInterface $output)
29
    {
30
        if (!$this->lock($this->getName())) {
31
            $output->writeln('The command is already running in another process.');
32
33
            return 0;
34
        }
35
36
        $limit = (int) $input->getOption('limit');
37
        Assert::that($limit)->integer()->greaterThan(0);
38
39
        $manager = $this->getManager();
40
41
        /** @var Label[] $labels */
42
        $labels = $manager->getRepository('LoevgaardPakkelabelsBundle:Label')->findBy([
43
            'status' => Label::STATUS_PENDING_NORMALIZATION,
44
        ], null, $limit);
45
46
        if ($output->isVerbose()) {
47
            $output->writeln('Label count: '.count($labels));
48
        }
49
50
        $iso3166 = new ISO3166();
51
52
        foreach ($labels as $label) {
53
            $output->writeln('Normalizing label id: '.$label->getId().' with order id: '.$label->getOrderId(), OutputInterface::VERBOSITY_VERBOSE);
54
55
            // check that countries are valid ISO 3166 alpha 2 codes
56
            $senderCountryValid = false;
57
            try {
58
                $iso3166->alpha2($label->getSenderCountryCode());
59
                $senderCountryValid = true;
60
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
61
            }
62
63 View Code Duplication
            if (!$senderCountryValid) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
64
                $senderCountry = $this->countryMapping($label->getSenderCountryCode());
65
                if ($senderCountry) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $senderCountry of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
66
                    $label->setSenderCountryCode($senderCountry);
67
                } else {
68
                    $output->writeln('Sender country code `'.$label->getSenderCountryCode().'` is not a valid ISO 3166 alpha 2 country code. Create a mapping or change the country manually.', OutputInterface::VERBOSITY_VERBOSE);
69
                    $label->markAsError('Sender country code `'.$label->getSenderCountryCode().'` is not a valid ISO 3166 alpha 2 country code. Create a mapping or change the country manually.');
70
                    $manager->flush();
71
                    continue;
72
                }
73
            }
74
75
            $receiverCountryValid = false;
76
            try {
77
                $iso3166->alpha2($label->getReceiverCountryCode());
78
                $receiverCountryValid = true;
79
            } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
80
            }
81
82 View Code Duplication
            if (!$receiverCountryValid) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
83
                $receiverCountry = $this->countryMapping($label->getReceiverCountryCode());
84
                if ($receiverCountry) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $receiverCountry of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
85
                    $label->setReceiverCountryCode($receiverCountry);
86
                } else {
87
                    $output->writeln('Receiver country code `'.$label->getReceiverCountryCode().'` is not a valid ISO 3166 alpha 2 country code. Create a mapping or change the country manually.', OutputInterface::VERBOSITY_VERBOSE);
88
                    $label->markAsError('Receiver country code `'.$label->getReceiverCountryCode().'` is not a valid ISO 3166 alpha 2 country code. Create a mapping or change the country manually.');
89
                    $manager->flush();
90
                    continue;
91
                }
92
            }
93
94
            // check that the shipping method is mapped
95
            if ($label->getShippingMethod()) {
96
                $shippingMethodMapping = $this->shippingMethodMapping($label->getShippingMethod());
97
                if ($shippingMethodMapping) {
98
                    // check if the label is a return label and check if the return product codes are set
99
                    if ($label->isReturnLabel()) {
100
                        if (!$shippingMethodMapping->getReturnProductCode()) {
101
                            $output->writeln('Mapping of shipping method `'.$label->getShippingMethod().'` does not have a return product code, but the label is a return label. You need to edit the shipping method mapping and add a return product code.', OutputInterface::VERBOSITY_VERBOSE);
102
                            $label->markAsError('Mapping of shipping method `'.$label->getShippingMethod().'` does not have a return product code, but the label is a return label. You need to edit the shipping method mapping and add a return product code.');
103
                            $manager->flush();
104
                            continue;
105
                        }
106
107
                        $label->setProductCode($shippingMethodMapping->getReturnProductCode());
108
                        if (!empty($shippingMethodMapping->getReturnServiceCodes())) {
109
                            $label->setServiceCodes(join(',', $shippingMethodMapping->getReturnServiceCodes()));
110
                        }
111
                    } else {
112
                        $label->setProductCode($shippingMethodMapping->getProductCode());
113
                        if (!empty($shippingMethodMapping->getServiceCodes())) {
114
                            $label->setServiceCodes(join(',', $shippingMethodMapping->getServiceCodes()));
115
                        }
116
                    }
117
                } else {
118
                    $output->writeln('Shipping method `'.$label->getShippingMethod().'` is not mapped. Map it manually.', OutputInterface::VERBOSITY_VERBOSE);
119
                    $label->markAsError('Shipping method `'.$label->getShippingMethod().'` is not mapped. Map it manually.');
120
                    $manager->flush();
121
                    continue;
122
                }
123
            }
124
125
            $label->setStatus(Label::STATUS_PENDING_CREATION);
126
127
            $manager->flush();
128
129
            $output->writeln('Label was normalized', OutputInterface::VERBOSITY_VERBOSE);
130
        }
131
132
        return 0;
133
    }
134
135
    /**
136
     * @param string $country
137
     *
138
     * @return null|string
139
     */
140
    protected function countryMapping(string $country)
141
    {
142
        $manager = $this->getManager();
143
        $countryMapping = $manager->getRepository('LoevgaardPakkelabelsBundle:CountryMapping')->findOneBy([
144
            'source' => $country,
145
        ]);
146
147
        if ($countryMapping && $countryMapping->getCountryCode()) {
148
            return $countryMapping->getCountryCode();
149
        }
150
151
        return null;
152
    }
153
154
    /**
155
     * @param string $shippingMethod
156
     *
157
     * @return ShippingMethodMapping|null
158
     */
159
    protected function shippingMethodMapping(string $shippingMethod)
160
    {
161
        $manager = $this->getManager();
162
        $shippingMethodMapping = $manager->getRepository('LoevgaardPakkelabelsBundle:ShippingMethodMapping')->findOneBy([
163
            'source' => $shippingMethod,
164
        ]);
165
166
        if ($shippingMethodMapping && $shippingMethodMapping->getProductCode()) {
167
            return $shippingMethodMapping;
168
        }
169
170
        return null;
171
    }
172
173
    /**
174
     * @return ObjectManager
175
     */
176
    protected function getManager()
177
    {
178
        $em = $this->getContainer()->get('doctrine')->getManager();
179
180
        return $em;
181
    }
182
}
183