updateRegionByMagentoRegionId()   D
last analyzed

Complexity

Conditions 9
Paths 12

Size

Total Lines 35
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 35
rs 4.909
c 0
b 0
f 0
cc 9
eloc 20
nc 12
nop 3
1
<?php
2
3
namespace Oro\Bundle\MagentoBundle\ImportExport\Strategy\StrategyHelper;
4
5
use Akeneo\Bundle\BatchBundle\Item\InvalidItemException;
6
7
use Oro\Bundle\AddressBundle\Entity\Country;
8
use Oro\Bundle\AddressBundle\Entity\AddressType;
9
use Oro\Bundle\AddressBundle\Entity\Region as BAPRegion;
10
use Oro\Bundle\AddressBundle\Entity\AbstractAddress;
11
use Oro\Bundle\AddressBundle\Entity\AbstractTypedAddress;
12
use Oro\Bundle\MagentoBundle\Entity\Region;
13
14
class AddressImportHelper
15
{
16
    /** @var DoctrineHelper */
17
    protected $doctrineHelper;
18
19
    /** @var array */
20
    protected $regionsCache = [];
21
22
    /** @var array */
23
    protected $countriesCache = [];
24
25
    /** @var array */
26
    protected $mageRegionsCache = [];
27
28
    /** @var AddressType[] */
29
    protected $addressTypesCache = [];
30
31
    /**
32
     * @param DoctrineHelper $doctrineHelper
33
     */
34
    public function __construct(DoctrineHelper $doctrineHelper)
35
    {
36
        $this->doctrineHelper = $doctrineHelper;
37
    }
38
39
    /**
40
     * @param AbstractAddress $address
41
     * @param int             $mageRegionId
42
     *
43
     * @throws InvalidItemException
44
     */
45
    public function updateAddressCountryRegion(AbstractAddress $address, $mageRegionId)
46
    {
47
        if (!$address->getCountry()) {
48
            return;
49
        }
50
51
        $countryCode = $address->getCountry()->getIso2Code();
52
        $country     = $this->getAddressCountryByCode($address, $countryCode);
53
        $address->setCountry($country);
0 ignored issues
show
Bug introduced by
It seems like $country defined by $this->getAddressCountry...$address, $countryCode) on line 52 can be null; however, Oro\Bundle\AddressBundle...ctAddress::setCountry() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
54
        if (!$country) {
55
            return;
56
        }
57
58
        $this->updateRegionByMagentoRegionId($address, $countryCode, $mageRegionId);
59
    }
60
61
    /**
62
     * @param AbstractTypedAddress $address
63
     */
64
    public function updateAddressTypes(AbstractTypedAddress $address)
65
    {
66
        $addressTypes = $address->getTypes();
67
        foreach ($addressTypes as $index => $type) {
68
            $addressTypes->set($index, $this->updateAddressType($type->getName()));
69
        }
70
    }
71
72
    /**
73
     * @param AbstractTypedAddress $localAddress
74
     * @param AbstractTypedAddress $remoteAddress
75
     */
76
    public function mergeAddressTypes(AbstractTypedAddress $localAddress, AbstractTypedAddress $remoteAddress)
77
    {
78
        $newAddressTypes     = array_diff($remoteAddress->getTypeNames(), $localAddress->getTypeNames());
79
        $deletedAddressTypes = array_diff($localAddress->getTypeNames(), $remoteAddress->getTypeNames());
80
81
        foreach ($deletedAddressTypes as $addressType) {
82
            $localAddress->removeType($localAddress->getTypeByName($addressType));
0 ignored issues
show
Bug introduced by
It seems like $localAddress->getTypeByName($addressType) can be null; however, removeType() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
83
        }
84
        foreach ($newAddressTypes as $addressType) {
85
            $localAddress->addType($remoteAddress->getTypeByName($addressType));
0 ignored issues
show
Bug introduced by
It seems like $remoteAddress->getTypeByName($addressType) can be null; however, addType() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
86
        }
87
    }
88
89
    /**
90
     * @param $mageRegionId
91
     *
92
     * @return object
93
     */
94
    public function findRegionByRegionId($mageRegionId)
95
    {
96
        return $this->doctrineHelper->getEntityByCriteria(
97
            ['regionId' => $mageRegionId],
98
            'Oro\Bundle\MagentoBundle\Entity\Region'
99
        );
100
    }
101
102
    /**
103
     * @param string $name
104
     *
105
     * @return AddressType
106
     */
107
    protected function updateAddressType($name)
108
    {
109
        $typeClass = 'OroAddressBundle:AddressType';
110
111
        if (empty($this->addressTypesCache[$name])
112
            || !$this->doctrineHelper->getEntityManager($typeClass)
113
                ->getUnitOfWork()->isInIdentityMap($this->addressTypesCache[$name])
114
        ) {
115
            $this->addressTypesCache[$name] = $this->doctrineHelper->getEntityRepository($typeClass)->find($name);
116
        }
117
118
        return $this->addressTypesCache[$name];
119
    }
120
121
    /**
122
     * @param AbstractAddress $address
123
     * @param string          $countryCode
124
     *
125
     * @throws InvalidItemException
126
     * @return Country|null
127
     */
128
    public function getAddressCountryByCode(AbstractAddress $address, $countryCode)
129
    {
130
        if (!$address->getCountry()) {
131
            return null;
132
        }
133
134
        if (array_key_exists($countryCode, $this->countriesCache)) {
135
            if (!empty($this->countriesCache[$countryCode])) {
136
                $this->countriesCache[$countryCode] = $this->doctrineHelper->merge($this->countriesCache[$countryCode]);
137
            }
138
        } else {
139
            /** @var Country $country */
140
            $country                            = $this->doctrineHelper->findAndReplaceEntity(
141
                $address->getCountry(),
142
                'Oro\Bundle\AddressBundle\Entity\Country',
143
                'iso2Code',
144
                ['iso2Code', 'iso3Code', 'name']
145
            );
146
            $this->countriesCache[$countryCode] = $country->getIso2Code() ? $country : null;
147
        }
148
149
        return $this->countriesCache[$countryCode];
150
    }
151
152
    /**
153
     * @param string $combinedCode
154
     * @param string $countryCode
155
     * @param string $code
156
     *
157
     * @return BAPRegion
158
     */
159
    public function loadRegionByCode($combinedCode, $countryCode, $code)
160
    {
161
        $regionClass  = 'Oro\Bundle\AddressBundle\Entity\Region';
162
        $countryClass = 'Oro\Bundle\AddressBundle\Entity\Country';
163
164
        // Simply search region by combinedCode
165
        $region = $this->doctrineHelper->getEntityByCriteria(
166
            [
167
                 'combinedCode' => $combinedCode
168
            ],
169
            $regionClass
170
        );
171
        if (!$region) {
172
            // Some region codes in magento are filled by region names
173
            $em      = $this->doctrineHelper->getEntityManager($countryClass);
174
            $country = $em->getReference($countryClass, $countryCode);
175
            $region  = $this->doctrineHelper->getEntityByCriteria(
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $region is correct as $this->doctrineHelper->g...nedCode), $regionClass) (which targets Oro\Bundle\MagentoBundle...::getEntityByCriteria()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
176
                [
177
                     'country' => $country,
178
                     'name'    => $combinedCode
179
                ],
180
                $regionClass
181
            );
182
        }
183
        if (!$region) {
184
            // Some numeric regions codes may be padded by 0 in ISO format and not padded in magento
185
            // As example FR-1 in magento and FR-01 in ISO
186
            $region = $this->doctrineHelper->getEntityByCriteria(
187
                [
188
                     'combinedCode' =>
189
                         BAPRegion::getRegionCombinedCode(
190
                             $countryCode,
191
                             str_pad($code, 2, '0', STR_PAD_LEFT)
192
                         )
193
                ],
194
                $regionClass
195
            );
196
        }
197
198
        return $region;
199
    }
200
201
    /**
202
     * @param AbstractAddress $address
203
     * @param string $countryCode
204
     * @param int|string|null $mageRegionId
205
     * @throws InvalidItemException
206
     */
207
    public function updateRegionByMagentoRegionId(AbstractAddress $address, $countryCode, $mageRegionId = null)
208
    {
209
        if (!empty($mageRegionId) && empty($this->mageRegionsCache[$mageRegionId]) && is_numeric($mageRegionId)) {
210
            $this->mageRegionsCache[$mageRegionId] = $this->findRegionByRegionId($mageRegionId);
211
        }
212
213
        if (!empty($this->mageRegionsCache[$mageRegionId])) {
214
            /** @var Region $mageRegion */
215
            $mageRegion = $this->mageRegionsCache[$mageRegionId];
216
            $combinedCode = $mageRegion->getCombinedCode();
217
            $regionCode = $mageRegion->getCode();
218
219
            if (!array_key_exists($combinedCode, $this->regionsCache)) {
220
                $this->regionsCache[$combinedCode] = $this->loadRegionByCode($combinedCode, $countryCode, $regionCode);
221
            }
222
223
            /**
224
             * no region found in system db for corresponding magento region, use region text
225
             */
226
            if (empty($this->regionsCache[$combinedCode])) {
227
                $address->setRegion(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<Oro\Bundle\AddressBundle\Entity\Region>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
228
                $address->setRegionText($mageRegion->getName());
229
            } else {
230
                $this->regionsCache[$combinedCode] = $this->doctrineHelper->merge($this->regionsCache[$combinedCode]);
231
                $address->setRegion($this->regionsCache[$combinedCode]);
232
                $address->setRegionText(null);
233
            }
234
        } elseif ($address->getRegionText() || $address->getCountry()) {
235
            $address->setRegion(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<Oro\Bundle\AddressBundle\Entity\Region>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
236
            // unable to find corresponding region and region text is empty,
237
            // it's correct case for UK addresses, if country present
238
        } else {
239
            throw new InvalidItemException('Unable to handle region for address', [$address]);
240
        }
241
    }
242
}
243