Completed
Push — master ( f81184...3aae6e )
by Andrii
04:04
created

AbstractConnection   A

Complexity

Total Complexity 28

Size/Duplication

Total Lines 252
Duplicated Lines 0 %

Coupling/Cohesion

Components 5
Dependencies 5

Test Coverage

Coverage 43.66%

Importance

Changes 0
Metric Value
wmc 28
lcom 5
cbo 5
dl 0
loc 252
ccs 31
cts 71
cp 0.4366
rs 10
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A getDb() 0 4 2
A disableAuth() 0 4 1
A enableAuth() 0 4 1
A __sleep() 0 4 1
A getDriverName() 0 4 1
A createCommand() 0 6 1
A getHandler() 0 4 1
A setHandler() 0 4 1
A isDisabledAuth() 0 4 1
A setDisabledAuth() 0 4 1
A setErrorChecker() 0 4 1
getResponseError() 0 1 ?
A getUserAgent() 0 4 1
A setAuth() 0 4 1
A getAuth() 0 11 3
A getQueryBuilder() 0 8 2
A decodeErrorBody() 0 14 3
A checkResponse() 0 12 3
A getBaseUri() 0 12 3
1
<?php
2
/**
3
 * Tools to use API as ActiveRecord for Yii2
4
 *
5
 * @link      https://github.com/hiqdev/yii2-hiart
6
 * @package   yii2-hiart
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2017, HiQDev (http://hiqdev.com/)
9
 */
10
11
namespace hiqdev\hiart;
12
13
use Closure;
14
use hiqdev\hiart\stream\Request;
15
use Yii;
16
use yii\base\Component;
17
use yii\base\InvalidParamException;
18
use yii\helpers\Json;
19
20
/**
21
 * Abstract connection class.
22
 */
23
abstract class AbstractConnection extends Component implements ConnectionInterface
24
{
25
    const EVENT_AFTER_OPEN = 'afterOpen';
26
27
    /**
28
     * @var string to be specified in concrete implementation
29
     */
30
    public $queryBuilderClass;
31
32
    public $requestClass = Request::class;
33
34
    public $commandClass = Command::class;
35
36
    public $queryClass = Query::class;
37
38
    public $activeQueryClass = ActiveQuery::class;
39
40
    public static $dbname = 'hiart';
41
42
    public $name = 'hiart';
43
44
    public $userAgent = 'HiArt/0.x';
45
46
    public $baseUri;
47
48
    /**
49
     * @var array transport config will be used in Request for handler or proxy request
50
     */
51
    public $config = [];
52
53
    /**
54
     * @var object request handler common for all requests of this connection
55
     */
56
    protected $_handler;
57
58
    /**
59
     * @var AbstractQueryBuilder the query builder for this connection
60
     */
61
    protected $_builder;
62
63
    /**
64
     * @var array authorization config
65
     */
66
    protected $_auth = [];
67
68
    /**
69
     * @var bool is auth disabled
70
     */
71
    protected $_disabledAuth = false;
72
73
    /**
74
     * @var Closure callback to test if API response has error
75
     * The function signature: `function ($response)`
76
     * Must return `null`, if the response does not contain an error
77
     */
78
    protected $_errorChecker;
79
80
    /**
81
     * @param null $dbname
82
     * @return ConnectionInterface|AbstractConnection
83
     */
84
    public static function getDb($dbname = null)
85
    {
86
        return $dbname ? Yii::$app->get($dbname) : Yii::$container->get(ConnectionInterface::class);
87
    }
88
89 1
    public function setAuth($auth)
90
    {
91 1
        $this->_auth = $auth;
92 1
    }
93
94
    /**
95
     * Returns auth settings.
96
     * @return array
97
     */
98 2
    public function getAuth()
99
    {
100 2
        if ($this->_disabledAuth) {
101
            return [];
102
        }
103 2
        if ($this->_auth instanceof Closure) {
104
            $this->_auth = call_user_func($this->_auth, $this);
0 ignored issues
show
Documentation Bug introduced by
It seems like call_user_func($this->_auth, $this) of type * is incompatible with the declared type array of property $_auth.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
105
        }
106
107 2
        return $this->_auth;
108
    }
109
110
    public function disableAuth()
111
    {
112
        $this->_disabledAuth = true;
113
    }
114
115
    public function enableAuth()
116
    {
117
        $this->_disabledAuth = false;
118
    }
119
120
    /**
121
     * Closes the connection when this component is being serialized.
122
     * @return array
123
     */
124
    public function __sleep()
125
    {
126
        return array_keys(get_object_vars($this));
127
    }
128
129
    /**
130
     * Returns the name of the DB driver for the current [[dsn]].
131
     * @return string name of the DB driver
132
     */
133
    public function getDriverName()
134
    {
135
        return 'hiart';
136
    }
137
138
    /**
139
     * Creates a command for execution.
140
     * @param array $config the configuration for the Command class
141
     * @return Command the DB command
142
     */
143 2
    public function createCommand(array $config = [])
144
    {
145 2
        $config['db'] = $this;
146
147 2
        return new $this->commandClass($config);
148
    }
149
150
    /**
151
     * @return AbstractQueryBuilder the query builder for this connection
152
     */
153 3
    public function getQueryBuilder()
154
    {
155 3
        if ($this->_builder === null) {
156 2
            $this->_builder = new $this->queryBuilderClass($this);
157 2
        }
158
159 3
        return $this->_builder;
160
    }
161
162
    /**
163
     * Handler is created and set by request.
164
     * @see setHandler
165
     * @return object
166
     */
167
    public function getHandler()
168
    {
169
        return $this->_handler;
170
    }
171
172
    /**
173
     * Requests use this function to keep request handler.
174
     * @param object $handler
175
     */
176
    public function setHandler($handler)
177
    {
178
        $this->_handler = $handler;
179
    }
180
181
    /**
182
     * @return boolean
183
     */
184
    public function isDisabledAuth()
185
    {
186
        return $this->_disabledAuth;
187
    }
188
189
    /**
190
     * @param boolean $disabledAuth
191
     */
192
    public function setDisabledAuth($disabledAuth)
193
    {
194
        $this->_disabledAuth = $disabledAuth;
195
    }
196
197
    /**
198
     * Try to decode error information if it is valid json, return it if not.
199
     * @param $body
200
     * @return mixed
201
     */
202
    protected function decodeErrorBody($body)
203
    {
204
        try {
205
            $decoded = Json::decode($body);
206
            if (isset($decoded['error'])) {
207
                $decoded['error'] = preg_replace('/\b\w+?Exception\[/',
208
                    "<span style=\"color: red;\">\\0</span>\n               ", $decoded['error']);
209
            }
210
211
            return $decoded;
212
        } catch (InvalidParamException $e) {
213
            return $body;
214
        }
215
    }
216
217
    /**
218
     * Setter for errorChecker.
219
     * @param Closure $checker
220
     */
221
    public function setErrorChecker($checker)
222
    {
223
        $this->_errorChecker = $checker;
224
    }
225
226
    /**
227
     * Checks response method and raises exception if error found.
228
     * @param ResponseInterface $response response data from API
229
     * @throws ResponseErrorException when response is invalid
230
     */
231 2
    public function checkResponse(ResponseInterface $response)
232
    {
233 2
        if (isset($this->_errorChecker)) {
234
            $error = call_user_func($this->_errorChecker, $response);
235
        } else {
236 2
            $error = $this->getResponseError($response);
237
        }
238
239 2
        if ($error) {
240
            throw new ResponseErrorException($error, $response);
241
        }
242 2
    }
243
244
    /**
245
     * Method checks whether the response is an error
246
     *
247
     * @param ResponseInterface $response
248
     * @return false|string the error text or boolean `false`, when the response is not an error
249
     */
250
    abstract public function getResponseError(ResponseInterface $response);
251
252
    /**
253
     * Return API base uri.
254
     * Adds trailing slash if uri is domain only.
255
     * @return string
256
     */
257 3
    public function getBaseUri()
258
    {
259 3
        static $checked;
260 3
        if (empty($checked)) {
261 1
            if (count(explode('/', $this->baseUri, 4)) === 3) {
262 1
                $this->baseUri .= '/';
263 1
            }
264 1
            $checked = true;
265 1
        }
266
267 3
        return $this->baseUri;
268
    }
269
270 2
    public function getUserAgent()
271
    {
272 2
        return $this->userAgent;
273
    }
274
}
275