ApiTransactionRepository::save()   A
last analyzed

Complexity

Conditions 2
Paths 4

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 0
cts 12
cp 0
rs 9.7666
c 0
b 0
f 0
cc 2
nc 4
nop 1
crap 6
1
<?php
2
/**
3
 * Finance module for HiPanel
4
 *
5
 * @link      https://github.com/hiqdev/hipanel-module-finance
6
 * @package   hipanel-module-finance
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2019, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\modules\finance\transaction;
12
13
use hiqdev\hiart\AbstractConnection;
14
use hiqdev\hiart\ConnectionInterface;
15
use hiqdev\hiart\ResponseErrorException;
16
use hiqdev\yii2\merchant\transactions\Transaction;
17
use hiqdev\yii2\merchant\transactions\TransactionException;
18
use hiqdev\yii2\merchant\transactions\TransactionRepositoryInterface;
19
use ReflectionObject;
20
use yii\helpers\Json;
21
22
class ApiTransactionRepository implements TransactionRepositoryInterface
23
{
24
    /**
25
     * @var ConnectionInterface|AbstractConnection
26
     */
27
    private $connection;
28
29
    /**
30
     * ApiTransactionRepository constructor.
31
     * @param ConnectionInterface $connection
32
     */
33
    public function __construct(ConnectionInterface $connection)
34
    {
35
        $this->connection = $connection;
36
    }
37
38
    /**
39
     * @param string $id
40
     * @throws TransactionException when transaction with the specified ID
41
     * does not exists
42
     * @return Transaction
43
     */
44
    public function findById($id)
45
    {
46
        try {
47
            $data = $this->connection->callWithDisabledAuth(function () use ($id) {
0 ignored issues
show
Bug introduced by
The method callWithDisabledAuth does only exist in hiqdev\hiart\AbstractConnection, but not in hiqdev\hiart\ConnectionInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
48
                return $this->connection->createCommand()->perform('merchantTransactionGet', null, ['id' => $id]);
49
            })->getData();
50
        } catch (ResponseErrorException $e) {
51
            throw new TransactionException('Failed to get transaction information');
52
        }
53
54
        if (empty($data)) {
55
            throw new TransactionException('Transaction not found');
56
        }
57
58
        return $this->instantiate($data);
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function insert($transaction)
65
    {
66
        return $this->save($transaction);
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    public function create($id, $merchant, $parameters)
73
    {
74
        if (empty($id)) {
75
            throw new TransactionException('Transaction ID is missing');
76
        }
77
        if (empty($merchant)) {
78
            throw new TransactionException('Merchant name is missing');
79
        }
80
81
        $transaction = new Transaction($id, $merchant);
82
        $transaction->setParameters($parameters);
83
84
        return $transaction;
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function save($transaction)
91
    {
92
        try {
93
            $data = $transaction->toArray();
94
            $data['parameters'] = Json::encode($data['parameters']);
95
96
            $this->connection->callWithDisabledAuth(function () use ($data) {
0 ignored issues
show
Bug introduced by
The method callWithDisabledAuth does only exist in hiqdev\hiart\AbstractConnection, but not in hiqdev\hiart\ConnectionInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
97
                return $this->connection->createCommand()->perform('merchantTransactionSet', null, $data);
98
            });
99
        } catch (ResponseErrorException $e) {
100
            throw new TransactionException('Failed to save transaction');
101
        }
102
103
        return $transaction;
104
    }
105
106
    /**
107
     * @param $data
108
     * @return Transaction
109
     */
110
    protected function instantiate($data)
111
    {
112
        $transaction = $this->create($data['id'], $data['merchant'], $data['parameters']);
113
114
        if ($data['success'] !== null) {
115
            $successReflection = (new ReflectionObject($transaction))->getProperty('success');
116
            $successReflection->setAccessible(true);
117
            $successReflection->setValue($transaction, $data['success']);
118
            $successReflection->setAccessible(false);
119
        }
120
121
        return $transaction;
122
    }
123
}
124