Completed
Push — 1.9 ( 482137...30c3e5 )
by
unknown
43:10
created

updateRegionByMagentoRegionId()   D

Complexity

Conditions 9
Paths 12

Size

Total Lines 35
Code Lines 20

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 35
rs 4.909
cc 9
eloc 20
nc 12
nop 3
1
<?php
2
3
namespace OroCRM\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
13
use OroCRM\Bundle\MagentoBundle\Entity\Region;
14
15
class AddressImportHelper
16
{
17
    /** @var DoctrineHelper */
18
    protected $doctrineHelper;
19
20
    /** @var array */
21
    protected $regionsCache = [];
22
23
    /** @var array */
24
    protected $countriesCache = [];
25
26
    /** @var array */
27
    protected $mageRegionsCache = [];
28
29
    /** @var AddressType[] */
30
    protected $addressTypesCache = [];
31
32
    /**
33
     * @param DoctrineHelper $doctrineHelper
34
     */
35
    public function __construct(DoctrineHelper $doctrineHelper)
36
    {
37
        $this->doctrineHelper = $doctrineHelper;
38
    }
39
40
    /**
41
     * @param AbstractAddress $address
42
     * @param int             $mageRegionId
43
     *
44
     * @throws InvalidItemException
45
     */
46
    public function updateAddressCountryRegion(AbstractAddress $address, $mageRegionId)
47
    {
48
        if (!$address->getCountry()) {
49
            return;
50
        }
51
52
        $countryCode = $address->getCountry()->getIso2Code();
53
        $country     = $this->getAddressCountryByCode($address, $countryCode);
54
        $address->setCountry($country);
0 ignored issues
show
Bug introduced by
It seems like $country defined by $this->getAddressCountry...$address, $countryCode) on line 53 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...
55
        if (!$country) {
56
            return;
57
        }
58
59
        $this->updateRegionByMagentoRegionId($address, $countryCode, $mageRegionId);
60
    }
61
62
    /**
63
     * @param AbstractTypedAddress $address
64
     */
65
    public function updateAddressTypes(AbstractTypedAddress $address)
66
    {
67
        $addressTypes = $address->getTypes();
68
        foreach ($addressTypes as $index => $type) {
69
            $addressTypes->set($index, $this->updateAddressType($type->getName()));
70
        }
71
    }
72
73
    /**
74
     * @param AbstractTypedAddress $localAddress
75
     * @param AbstractTypedAddress $remoteAddress
76
     */
77
    public function mergeAddressTypes(AbstractTypedAddress $localAddress, AbstractTypedAddress $remoteAddress)
78
    {
79
        $newAddressTypes     = array_diff($remoteAddress->getTypeNames(), $localAddress->getTypeNames());
80
        $deletedAddressTypes = array_diff($localAddress->getTypeNames(), $remoteAddress->getTypeNames());
81
82
        foreach ($deletedAddressTypes as $addressType) {
83
            $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...
84
        }
85
        foreach ($newAddressTypes as $addressType) {
86
            $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...
87
        }
88
    }
89
90
    /**
91
     * @param $mageRegionId
92
     *
93
     * @return object
94
     */
95
    public function findRegionByRegionId($mageRegionId)
96
    {
97
        return $this->doctrineHelper->getEntityByCriteria(
98
            ['regionId' => $mageRegionId],
99
            'OroCRM\Bundle\MagentoBundle\Entity\Region'
100
        );
101
    }
102
103
    /**
104
     * @param string $name
105
     *
106
     * @return AddressType
107
     */
108
    protected function updateAddressType($name)
109
    {
110
        $typeClass = 'OroAddressBundle:AddressType';
111
112
        if (empty($this->addressTypesCache[$name])
113
            || !$this->doctrineHelper->getEntityManager($typeClass)
114
                ->getUnitOfWork()->isInIdentityMap($this->addressTypesCache[$name])
115
        ) {
116
            $this->addressTypesCache[$name] = $this->doctrineHelper->getEntityRepository($typeClass)->find($name);
117
        }
118
119
        return $this->addressTypesCache[$name];
120
    }
121
122
    /**
123
     * @param AbstractAddress $address
124
     * @param string          $countryCode
125
     *
126
     * @throws InvalidItemException
127
     * @return Country|null
128
     */
129
    public function getAddressCountryByCode(AbstractAddress $address, $countryCode)
130
    {
131
        if (!$address->getCountry()) {
132
            return null;
133
        }
134
135
        if (array_key_exists($countryCode, $this->countriesCache)) {
136
            if (!empty($this->countriesCache[$countryCode])) {
137
                $this->countriesCache[$countryCode] = $this->doctrineHelper->merge($this->countriesCache[$countryCode]);
138
            }
139
        } else {
140
            /** @var Country $country */
141
            $country                            = $this->doctrineHelper->findAndReplaceEntity(
142
                $address->getCountry(),
143
                'Oro\Bundle\AddressBundle\Entity\Country',
144
                'iso2Code',
145
                ['iso2Code', 'iso3Code', 'name']
146
            );
147
            $this->countriesCache[$countryCode] = $country->getIso2Code() ? $country : null;
148
        }
149
150
        return $this->countriesCache[$countryCode];
151
    }
152
153
    /**
154
     * @param string $combinedCode
155
     * @param string $countryCode
156
     * @param string $code
157
     *
158
     * @return BAPRegion
159
     */
160
    public function loadRegionByCode($combinedCode, $countryCode, $code)
161
    {
162
        $regionClass  = 'Oro\Bundle\AddressBundle\Entity\Region';
163
        $countryClass = 'Oro\Bundle\AddressBundle\Entity\Country';
164
165
        // Simply search region by combinedCode
166
        $region = $this->doctrineHelper->getEntityByCriteria(
167
            [
168
                 'combinedCode' => $combinedCode
169
            ],
170
            $regionClass
171
        );
172
        if (!$region) {
173
            // Some region codes in magento are filled by region names
174
            $em      = $this->doctrineHelper->getEntityManager($countryClass);
175
            $country = $em->getReference($countryClass, $countryCode);
176
            $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 OroCRM\Bundle\MagentoBun...::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...
177
                [
178
                     'country' => $country,
179
                     'name'    => $combinedCode
180
                ],
181
                $regionClass
182
            );
183
        }
184
        if (!$region) {
185
            // Some numeric regions codes may be padded by 0 in ISO format and not padded in magento
186
            // As example FR-1 in magento and FR-01 in ISO
187
            $region = $this->doctrineHelper->getEntityByCriteria(
188
                [
189
                     'combinedCode' =>
190
                         BAPRegion::getRegionCombinedCode(
191
                             $countryCode,
192
                             str_pad($code, 2, '0', STR_PAD_LEFT)
193
                         )
194
                ],
195
                $regionClass
196
            );
197
        }
198
199
        return $region;
200
    }
201
202
    /**
203
     * @param AbstractAddress $address
204
     * @param string $countryCode
205
     * @param int|string|null $mageRegionId
206
     * @throws InvalidItemException
207
     */
208
    public function updateRegionByMagentoRegionId(AbstractAddress $address, $countryCode, $mageRegionId = null)
209
    {
210
        if (!empty($mageRegionId) && empty($this->mageRegionsCache[$mageRegionId]) && is_numeric($mageRegionId)) {
211
            $this->mageRegionsCache[$mageRegionId] = $this->findRegionByRegionId($mageRegionId);
212
        }
213
214
        if (!empty($this->mageRegionsCache[$mageRegionId])) {
215
            /** @var Region $mageRegion */
216
            $mageRegion = $this->mageRegionsCache[$mageRegionId];
217
            $combinedCode = $mageRegion->getCombinedCode();
218
            $regionCode = $mageRegion->getCode();
219
220
            if (!array_key_exists($combinedCode, $this->regionsCache)) {
221
                $this->regionsCache[$combinedCode] = $this->loadRegionByCode($combinedCode, $countryCode, $regionCode);
222
            }
223
224
            /**
225
             * no region found in system db for corresponding magento region, use region text
226
             */
227
            if (empty($this->regionsCache[$combinedCode])) {
228
                $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...
229
                $address->setRegionText($mageRegion->getName());
230
            } else {
231
                $this->regionsCache[$combinedCode] = $this->doctrineHelper->merge($this->regionsCache[$combinedCode]);
232
                $address->setRegion($this->regionsCache[$combinedCode]);
233
                $address->setRegionText(null);
234
            }
235
        } elseif ($address->getRegionText() || $address->getCountry()) {
236
            $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...
237
            // unable to find corresponding region and region text is empty,
238
            // it's correct case for UK addresses, if country present
239
        } else {
240
            throw new InvalidItemException('Unable to handle region for address', [$address]);
241
        }
242
    }
243
}
244