Passed
Pull Request — master (#315)
by
unknown
03:23
created

MethodList   A

Complexity

Total Complexity 42

Size/Duplication

Total Lines 281
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 95
dl 0
loc 281
rs 9.0399
c 2
b 0
f 0
wmc 42

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getBannedPaymentMethods() 0 12 3
A removeBannedPaymentMethods() 0 13 4
A __construct() 0 12 1
A filterMethodsByScore() 0 16 6
A getScoreByCreditrating() 0 19 6
A getQuote() 0 3 1
A getConfigParam() 0 7 2
A removeAmazonPay() 0 8 4
A removeNotWhitelistedPaymentMethods() 0 12 4
A afterGetAvailableMethods() 0 26 4
B checkKlarnaMethods() 0 25 7

How to fix   Complexity   

Complex Class

Complex classes like MethodList 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.

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 MethodList, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * PAYONE Magento 2 Connector is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * PAYONE Magento 2 Connector is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with PAYONE Magento 2 Connector. If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * PHP version 5
18
 *
19
 * @category  Payone
20
 * @package   Payone_Magento2_Plugin
21
 * @author    FATCHIP GmbH <[email protected]>
22
 * @copyright 2003 - 2016 Payone GmbH
23
 * @license   <http://www.gnu.org/licenses/> GNU Lesser General Public License
24
 * @link      http://www.payone.de
25
 */
26
27
namespace Payone\Core\Model\Plugins;
28
29
use Magento\Payment\Model\MethodList as OrigMethodList;
0 ignored issues
show
Bug introduced by
The type Magento\Payment\Model\MethodList was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
use Magento\Payment\Model\MethodInterface;
0 ignored issues
show
Bug introduced by
The type Magento\Payment\Model\MethodInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
use Magento\Quote\Api\Data\AddressInterface;
0 ignored issues
show
Bug introduced by
The type Magento\Quote\Api\Data\AddressInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
32
use Payone\Core\Model\PayoneConfig;
33
use Payone\Core\Model\Source\CreditratingIntegrationEvent as Event;
34
use Magento\Quote\Model\Quote;
0 ignored issues
show
Bug introduced by
The type Magento\Quote\Model\Quote was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
35
use Payone\Core\Model\Source\PersonStatus;
36
37
/**
38
 * Plugin for Magentos MethodList class
39
 */
40
class MethodList
41
{
42
    /**
43
     * PAYONE consumerscore request model
44
     *
45
     * @var \Payone\Core\Model\Api\Request\Consumerscore
46
     */
47
    protected $consumerscore;
48
49
    /**
50
     * Consumerscore helper
51
     *
52
     * @var \Payone\Core\Helper\Consumerscore
53
     */
54
    protected $consumerscoreHelper;
55
56
    /**
57
     * Checkout session
58
     *
59
     * @var \Magento\Checkout\Model\Session
0 ignored issues
show
Bug introduced by
The type Magento\Checkout\Model\Session was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
60
     */
61
    protected $checkoutSession;
62
63
    /**
64
     * Payment ban entity
65
     *
66
     * @var \Payone\Core\Model\ResourceModel\PaymentBan
67
     */
68
    protected $paymentBan;
69
70
    /**
71
     * Addresscheck management object
72
     *
73
     * @var \Payone\Core\Model\Risk\Addresscheck
74
     */
75
    protected $addresscheck;
76
77
    /**
78
     * Constructor
79
     *
80
     * @param \Payone\Core\Model\Api\Request\Consumerscore $consumerscore
81
     * @param \Payone\Core\Helper\Consumerscore            $consumerscoreHelper
82
     * @param \Magento\Checkout\Model\Session              $checkoutSession
83
     * @param \Payone\Core\Model\ResourceModel\PaymentBan  $paymentBan
84
     * @param \Payone\Core\Model\Risk\Addresscheck         $addresscheck
85
     */
86
    public function __construct(
87
        \Payone\Core\Model\Api\Request\Consumerscore $consumerscore,
88
        \Payone\Core\Helper\Consumerscore $consumerscoreHelper,
89
        \Magento\Checkout\Model\Session $checkoutSession,
90
        \Payone\Core\Model\ResourceModel\PaymentBan $paymentBan,
91
        \Payone\Core\Model\Risk\Addresscheck $addresscheck
92
    ) {
93
        $this->consumerscore = $consumerscore;
94
        $this->consumerscoreHelper = $consumerscoreHelper;
95
        $this->checkoutSession = $checkoutSession;
96
        $this->paymentBan = $paymentBan;
97
        $this->addresscheck = $addresscheck;
98
    }
99
100
    /**
101
     * Filter methods by the worst score
102
     *
103
     * @param  MethodInterface[] $aPaymentMethods
104
     * @param  string            $sWorstScore
105
     * @return MethodInterface[]
106
     */
107
    protected function filterMethodsByScore($aPaymentMethods, $sWorstScore)
108
    {
109
        $aRedMethods = $this->consumerscoreHelper->getAllowedMethodsForScore('R');
110
        $aYellowMethods = array_merge($aRedMethods, $this->consumerscoreHelper->getAllowedMethodsForScore('Y'));
111
112
        $aReturnMethods = [];
113
        foreach ($aPaymentMethods as $oMethod) {
114
            if ($sWorstScore == 'Y' && array_search($oMethod->getCode(), $aYellowMethods) !== false) {
115
                $aReturnMethods[] = $oMethod;
116
            }
117
118
            if ($sWorstScore == 'R' && array_search($oMethod->getCode(), $aRedMethods) !== false) {
119
                $aReturnMethods[] = $oMethod;
120
            }
121
        }
122
        return $aReturnMethods;
123
    }
124
125
    /**
126
     * Execute a consumerscore request to PAYONE or load an old score if its lifetime is still active
127
     *
128
     * @param  AddressInterface $oShipping
129
     * @return string
130
     */
131
    protected function getScoreByCreditrating(AddressInterface $oShipping)
132
    {
133
        $aResponse = $this->consumerscore->sendRequest($oShipping);
134
        if ($aResponse === true) {// creditrating not executed because of a previous check
135
            $this->consumerscoreHelper->copyOldStatusToNewAddress($oShipping);
136
        }
137
138
        if (isset($aResponse['score'])) {
139
            $oShipping->setPayoneProtectScore($aResponse['score'])->save();
140
        }
141
142
        $sScore = $oShipping->getPayoneProtectScore();
143
        if (isset($aResponse['personstatus']) && $aResponse['personstatus'] !== PersonStatus::NONE) {
144
            $aMapping = $this->addresscheck->getPersonstatusMapping();
145
            if (array_key_exists($aResponse['personstatus'], $aMapping)) {
146
                $sScore = $this->consumerscoreHelper->getWorstScore([$sScore, $aMapping[$aResponse['personstatus']]]);
147
            }
148
        }
149
        return $sScore;
150
    }
151
152
    /**
153
     * Get parameter from config
154
     *
155
     * @param  string $sParam
156
     * @param  bool   $blIsAddresscheck
157
     * @return string
158
     */
159
    protected function getConfigParam($sParam, $blIsAddresscheck = false)
160
    {
161
        $sGroup = 'creditrating';
162
        if ($blIsAddresscheck === true) {
163
            $sGroup = 'address_check';
164
        }
165
        return $this->consumerscoreHelper->getConfigParam($sParam, $sGroup, 'payone_protect');
166
    }
167
168
    /**
169
     * Get quote object from session
170
     *
171
     * @return Quote
172
     */
173
    protected function getQuote()
174
    {
175
        return $this->checkoutSession->getQuote();
176
    }
177
178
    /**
179
     * Return banned payment methods for the current user
180
     *
181
     * @param  Quote $oQuote
182
     * @return array
183
     */
184
    protected function getBannedPaymentMethods(Quote $oQuote)
185
    {
186
        $aBans = [];
187
        if (!empty($oQuote->getCustomerId())) {
188
            $aBans = $this->paymentBan->getPaymentBans($oQuote->getCustomerId());
189
        } else { // guest checkout
190
            $aSessionBans = $this->checkoutSession->getPayonePaymentBans();
191
            if (!empty($aSessionBans)) {
192
                $aBans = $aSessionBans;
193
            }
194
        }
195
        return $aBans;
196
    }
197
198
    /**
199
     * Remove banned paymenttypes
200
     *
201
     * @param  array $aPaymentMethods
202
     * @param  Quote $oQuote
203
     * @return array
204
     */
205
    protected function removeBannedPaymentMethods($aPaymentMethods, Quote $oQuote)
206
    {
207
        $aBannedMethos = $this->getBannedPaymentMethods($oQuote);
208
        for($i = 0; $i < count($aPaymentMethods); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
209
            $sCode = $aPaymentMethods[$i]->getCode();
210
            if (array_key_exists($sCode, $aBannedMethos) !== false) {
211
                $iBannedUntil = strtotime($aBannedMethos[$sCode]);
212
                if ($iBannedUntil > time()) {
213
                    unset($aPaymentMethods[$i]);
214
                }
215
            }
216
        }
217
        return $aPaymentMethods;
218
    }
219
220
    /**
221
     * Remove paymenttypes not on the session whitelist
222
     *
223
     * @param  array $aPaymentMethods
224
     * @return array
225
     */
226
    protected function removeNotWhitelistedPaymentMethods($aPaymentMethods)
227
    {
228
        $aWhitelist = $this->checkoutSession->getPayonePaymentWhitelist();
229
        if (!empty($aWhitelist)) {
230
            $iCount = count($aPaymentMethods);
231
            for($i = 0; $i < $iCount; $i++) {
232
                if (array_search($aPaymentMethods[$i]->getCode(), $aWhitelist) === false) {
233
                    unset($aPaymentMethods[$i]);
234
                }
235
            }
236
        }
237
        return $aPaymentMethods;
238
    }
239
240
    /**
241
     * Remove Amazon Pay from payment method array
242
     *
243
     * @param  array $aPaymentMethods
244
     * @return array
245
     */
246
    public function removeAmazonPay($aPaymentMethods)
247
    {
248
        for($i = 0; $i < count($aPaymentMethods); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
249
            if (isset($aPaymentMethods[$i]) && $aPaymentMethods[$i]->getCode() == PayoneConfig::METHOD_AMAZONPAY) {
250
                unset($aPaymentMethods[$i]);
251
            }
252
        }
253
        return $aPaymentMethods;
254
    }
255
256
    /**
257
     * Removes Klarna base methode if there are no Klarna sub-types available
258
     *
259
     * @param  array $aPaymentMethods
260
     * @return array
261
     */
262
    public function checkKlarnaMethods($aPaymentMethods)
263
    {
264
        $iKeyKlarna = false;
265
        $blHasKlarnaSubtypes = false;
266
        $aKlarnaSubtypes = [
267
            PayoneConfig::METHOD_KLARNA_INVOICE,
268
            PayoneConfig::METHOD_KLARNA_DEBIT,
269
            PayoneConfig::METHOD_KLARNA_INSTALLMENT
270
        ];
271
        for($i = 0; $i < count($aPaymentMethods); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
272
            if (isset($aPaymentMethods[$i])) {
273
                if ($aPaymentMethods[$i]->getCode() == PayoneConfig::METHOD_KLARNA_BASE) {
274
                    $iKeyKlarna = $i;
275
                }
276
                if (in_array($aPaymentMethods[$i]->getCode(), $aKlarnaSubtypes) === true) {
277
                    $blHasKlarnaSubtypes = true;
278
                    break;
279
                }
280
            }
281
        }
282
283
        if ($iKeyKlarna !== false && $blHasKlarnaSubtypes === false) {
284
            unset($aPaymentMethods[$iKeyKlarna]);
285
        }
286
        return $aPaymentMethods;
287
    }
288
289
    /**
290
     *
291
     * @param  OrigMethodList    $subject
292
     * @param  MethodInterface[] $aPaymentMethods
293
     * @return MethodInterface[]
294
     */
295
    public function afterGetAvailableMethods(OrigMethodList $subject, $aPaymentMethods)
0 ignored issues
show
Unused Code introduced by
The parameter $subject is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

295
    public function afterGetAvailableMethods(/** @scrutinizer ignore-unused */ OrigMethodList $subject, $aPaymentMethods)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
296
    {
297
        $oQuote = $this->getQuote();
298
        $oShipping = $oQuote->getShippingAddress();
299
300
        $aScores = [];
301
        if ($this->getConfigParam('enabled', true)) {// is addresscheck active
302
            $aScores[] = $oShipping->getPayoneAddresscheckScore();
303
        }
304
305
        $dTotal = $oQuote->getGrandTotal();
306
        if ($this->consumerscoreHelper->isCreditratingNeeded(Event::BEFORE_PAYMENT, $dTotal) === true) {
307
            $aScores[] = $this->getScoreByCreditrating($oShipping);
308
        }
309
310
        $sScore = $this->consumerscoreHelper->getWorstScore($aScores);
311
        if ($sScore != 'G') { // no need to filter
312
            $aPaymentMethods = $this->filterMethodsByScore($aPaymentMethods, $sScore);
313
        }
314
315
        $aPaymentMethods = $this->removeBannedPaymentMethods($aPaymentMethods, $oQuote);
316
        $aPaymentMethods = $this->removeNotWhitelistedPaymentMethods($aPaymentMethods);
317
        $aPaymentMethods = $this->removeAmazonPay($aPaymentMethods);
318
        $aPaymentMethods = $this->checkKlarnaMethods($aPaymentMethods);
319
320
        return $aPaymentMethods;
321
    }
322
}
323