Passed
Push — master ( 2fd05c...9d8025 )
by Bruno
02:00
created

VaultDetailsHandler::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 3
1
<?php
2
/**
3
 * Copyright © Wirecard Brasil. All rights reserved.
4
 *
5
 * @author    Bruno Elisei <[email protected]>
6
 * See COPYING.txt for license details.
7
 */
8
9
namespace Moip\Magento2\Gateway\Response;
10
11
use Magento\Framework\ObjectManagerInterface;
12
use Magento\Payment\Gateway\Data\PaymentDataObjectInterface;
13
use Magento\Payment\Gateway\Response\HandlerInterface;
14
use Magento\Payment\Model\InfoInterface;
15
use Magento\Sales\Api\Data\OrderPaymentExtensionInterface;
16
use Magento\Sales\Api\Data\OrderPaymentExtensionInterfaceFactory;
17
use Magento\Vault\Api\Data\PaymentTokenFactoryInterface;
18
use Magento\Vault\Api\Data\PaymentTokenInterface;
19
use Magento\Vault\Api\Data\PaymentTokenInterfaceFactory;
20
21
/**
22
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
23
 */
24
class VaultDetailsHandler implements HandlerInterface
25
{
26
    /**
27
     * @var PaymentTokenInterfaceFactory
28
     */
29
    protected $paymentTokenFactory;
30
31
    /**
32
     * @var OrderPaymentExtensionInterfaceFactory
33
     */
34
    protected $paymentExtensionFactory;
35
36
    /**
37
     * @var SubjectReader
38
     */
39
    protected $subjectReader;
40
41
    /**
42
     * @var ObjectManagerInterface
43
     */
44
    private $objectManager;
45
46
    /**
47
     * @var Json
48
     */
49
    private $serializer;
50
51
    /**
52
     * AccountPaymentTokenFactory constructor.
53
     *
54
     * @param ObjectManagerInterface       $objectManager
55
     * @param PaymentTokenFactoryInterface $paymentTokenFactory
56
     */
57
    public function __construct(
58
        ObjectManagerInterface $objectManager,
59
        OrderPaymentExtensionInterfaceFactory $paymentExtensionFactory,
60
        PaymentTokenFactoryInterface $paymentTokenFactory = null
61
    ) {
62
        if ($paymentTokenFactory === null) {
63
            $paymentTokenFactory = $objectManager->get(PaymentTokenFactoryInterface::class);
64
        }
65
66
        $this->objectManager = $objectManager;
67
        $this->paymentExtensionFactory = $paymentExtensionFactory;
68
        $this->paymentTokenFactory = $paymentTokenFactory;
69
    }
70
71
    /**
72
     * @inheritdoc
73
     */
74
    public function handle(array $handlingSubject, array $response)
75
    {
76
        if (!isset($handlingSubject['payment'])
77
            || !$handlingSubject['payment'] instanceof PaymentDataObjectInterface
0 ignored issues
show
Bug introduced by
The class Magento\Payment\Gateway\...mentDataObjectInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
78
        ) {
79
            throw new \InvalidArgumentException('Payment data object should be provided');
80
        }
81
82
        $paymentDO = $handlingSubject['payment'];
83
84
        $payment = $paymentDO->getPayment();
85
86
        if ($payment->getMethod() === 'moip_magento2_cc') {
87
            $paymentToken = $this->getVaultPaymentToken($response, $payment);
88
            if (null !== $paymentToken) {
89
                $extensionAttributes = $this->getExtensionAttributes($payment);
90
                $extensionAttributes->setVaultPaymentToken($paymentToken);
91
            }
92
        }
93
    }
94
95
    /**
96
     * Get vault payment token entity.
97
     *
98
     * @param $response
99
     *
100
     * @return PaymentTokenInterface|null
101
     */
102
    protected function getVaultPaymentToken($response, $payment)
103
    {
104
        $paymentAddtional = $response['fundingInstrument'];
105
        $ccExpYear = $payment->getAdditionalInformation('cc_exp_year');
106
        $ccExpMonth = $payment->getAdditionalInformation('cc_exp_month');
107
        $payment->unsAdditionalInformation('cc_exp_year');
108
        $payment->unsAdditionalInformation('cc_exp_month');
109
110
        if (isset($paymentAddtional['creditCard'])) {
111 View Code Duplication
            if (isset($paymentAddtional['creditCard']['id'])) {
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...
112
                $ccId = $paymentAddtional['creditCard']['id'];
113
                $ccType = $this->mapperCcType($paymentAddtional['creditCard']['brand']);
114
                $ccLast4 = $paymentAddtional['creditCard']['last4'];
115
            }
116
        } else {
117
            throw new \InvalidArgumentException('Payment data object should be provided');
118
        }
119
120
        if (empty($ccId)) {
121
            return null;
122
        }
123
124
        $paymentToken = $this->paymentTokenFactory->create();
125
        $paymentToken->setGatewayToken($ccId);
126
        $paymentToken->setExpiresAt(strtotime('+1 year'));
127
        $paymentToken->setType(PaymentTokenFactoryInterface::TOKEN_TYPE_CREDIT_CARD);
128
        // phpcs:ignore Generic.Files.LineLength
129
        $details = ['cc_last4' => $ccLast4, 'cc_exp_year' => $ccExpYear, 'cc_exp_month' => $ccExpMonth, 'cc_type' => $ccType];
0 ignored issues
show
Bug introduced by
The variable $ccLast4 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $ccType does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
130
        $paymentToken->setTokenDetails(json_encode($details));
131
132
        return $paymentToken;
133
    }
134
135
    /**
136
     * Get payment extension attributes.
137
     *
138
     * @param InfoInterface $payment
139
     *
140
     * @return OrderPaymentExtensionInterface
141
     */
142
    private function getExtensionAttributes(InfoInterface $payment): OrderPaymentExtensionInterface
143
    {
144
        $extensionAttributes = $payment->getExtensionAttributes();
145
        if (null === $extensionAttributes) {
146
            $extensionAttributes = $this->paymentExtensionFactory->create();
147
            $payment->setExtensionAttributes($extensionAttributes);
148
        }
149
150
        return $extensionAttributes;
151
    }
152
153
    /**
154
     * Get Type Cc by response payment.
155
     *
156
     * @param string $type
157
     */
158 View Code Duplication
    public function mapperCcType($type)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
159
    {
160
        if ($type === 'MASTERCARD') {
161
            return 'MC';
162
        } elseif ($type === 'VISA') {
163
            return 'VI';
164
        } elseif ($type === 'AMEX') {
165
            return 'AE';
166
        } elseif ($type === 'DINERS') {
167
            return 'DN';
168
        } elseif ($type === 'HIPERCARD') {
169
            return 'HC';
170
        } elseif ($type === 'HIPER') {
171
            return 'HI';
172
        } elseif ($type === 'ELO') {
173
            return 'ELO';
174
        }
175
    }
176
}
177