Completed
Push — master ( 157634...9df170 )
by Andrii
02:13
created

Connection::setResponseData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
ccs 0
cts 7
cp 0
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
crap 2
1
<?php
2
/**
3
 * HiPanel API client made with HiART.
4
 *
5
 * @link      https://github.com/hiqdev/hipanel-hiart
6
 * @package   hipanel-hiart
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hipanel\hiart;
12
13
use hiqdev\hiart\ResponseInterface;
14
use yii\base\Application;
15
16
class Connection extends \hiqdev\hiart\rest\Connection implements ConnectionInterface
17
{
18
    public $queryBuilderClass = QueryBuilder::class;
19
20
    private $app;
21
22
    public function __construct(Application $app, $config = [])
23
    {
24
        $this->app = $app;
25
        parent::__construct($config);
26
    }
27
28
    /**
29
     * Fixes response:
30
     * - if batch - don't touch
31
     * - if single: [] => null, else get first item
32
     * @param ResponseInterface $response
33
     * @return bool if response doesn't need to be checked for error
34
     */
35
    protected function fixResponse(ResponseInterface $response)
36
    {
37
        if ($response->getRequest()->getQuery()->getOption('batch')) {
38
            return false;
39
        }
40
41
        $rows = $response->getData();
42
        $empty = $rows === [];
43
        $this->setResponseData($response, $empty ? null : reset($rows));
44
45
        return $empty;
46
    }
47
48
    /**
49
     * @param ResponseInterface $response
50
     * @param array|null $data
51
     */
52
    protected function setResponseData(ResponseInterface $response, $data)
53
    {
54
        $class = new \ReflectionObject($response);
55
        $prop = $class->getProperty('data');
56
        $prop->setAccessible(true);
57
        $prop->setValue($response, $data);
58
    }
59
60
    /**
61
     * Calls fixResponse.
62
     * @param ResponseInterface $response
63
     * @return string|false error text or false
64
     */
65
    public function getResponseError(ResponseInterface $response)
66
    {
67
        if ($this->fixResponse($response)) {
68
            return false;
69
        }
70
71
        if (!$this->isError($response)) {
72
            return false;
73
        }
74
75
        $error = $this->getError($response);
76
        if ($error === 'invalid_token') {
77
            $this->app->user->logout();
78
            $this->app->response->refresh()->send();
0 ignored issues
show
Bug introduced by
The method refresh does only exist in yii\web\Response, but not in yii\console\Response.

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...
79
            $this->app->end();
80
        }
81
82
        return $error ?: 'unknown api error';
83
    }
84
85
    /**
86
     * @param ResponseInterface $response
87
     * @return bool
88
     */
89
    public function isError(ResponseInterface $response)
90
    {
91
        if ($this->isRawDataEmpty($response)) {
92
            return true;
93
        }
94
95
        $data = $response->getData();
96
        if ($data === '0') {
97
            return false;
98
        }
99
100
        return is_array($data) ? array_key_exists('_error', $data) : !$data;
101
    }
102
103
    private function isRawDataEmpty(ResponseInterface $response)
104
    {
105
        return $response->getRawData() === null || $response->getRawData() === '';
106
    }
107
108
    private function getError(ResponseInterface $response)
109
    {
110
        if ($this->isRawDataEmpty($response)) {
111
            return 'The response body is empty';
112
        }
113
114
        $data = $response->getData();
115
        if (isset($data['_error'])) {
116
            return $data['_error'];
117
        }
118
119
        return null;
120
    }
121
122
    /**
123
     * Gets auth data from user.
124
     * @return array
125
     */
126
    public function getAuth()
127
    {
128
        if ($this->_disabledAuth) {
129
            return [];
130
        }
131
132
        return $this->app->user->getAuthData();
133
    }
134
}
135