AbstractConnection::getAuth()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.3332

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 0
dl 0
loc 10
ccs 4
cts 6
cp 0.6667
crap 3.3332
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * ActiveRecord for API
4
 *
5
 * @link      https://github.com/hiqdev/yii2-hiart
6
 * @package   yii2-hiart
7
 * @license   BSD-3-Clause
8
 * @copyright Copyright (c) 2015-2019, 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 $name
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $name is correct as it would always require null to be passed?
Loading history...
82
     * @return ConnectionInterface|AbstractConnection
83
     */
84 3
    public static function getDb($name = null, $class = ConnectionInterface::class)
85
    {
86 3
        if ($name) {
0 ignored issues
show
introduced by
$name is of type null, thus it always evaluated to false.
Loading history...
87
            return Yii::$app->get($name);
88
        }
89 3
        if (Yii::$container->hasSingleton($class)) {
90 2
            return Yii::$container->get($class);
91
        }
92
93 1
        return Yii::$app->get(static::$dbname);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Yii::app->get(static::dbname) also could return the type mixed which is incompatible with the documented return type hiqdev\hiart\AbstractCon...art\ConnectionInterface.
Loading history...
94
    }
95
96 1
    public function setAuth($auth)
97
    {
98 1
        $this->_auth = $auth;
99 1
    }
100
101
    /**
102
     * Returns auth settings.
103
     * @return array
104
     */
105 2
    public function getAuth()
106
    {
107 2
        if ($this->_disabledAuth) {
108
            return [];
109
        }
110 2
        if ($this->_auth instanceof Closure) {
0 ignored issues
show
introduced by
$this->_auth is never a sub-type of Closure.
Loading history...
111
            $this->_auth = call_user_func($this->_auth, $this);
112
        }
113
114 2
        return $this->_auth;
115
    }
116
117
    public function disableAuth()
118
    {
119
        $this->_disabledAuth = true;
120
    }
121
122
    public function enableAuth()
123
    {
124
        $this->_disabledAuth = false;
125
    }
126
127
    /**
128
     * Closes the connection when this component is being serialized.
129
     * @return array
130
     */
131
    public function __sleep()
132
    {
133
        return array_keys(get_object_vars($this));
134
    }
135
136
    /**
137
     * Returns the name of the DB driver for the current [[dsn]].
138
     * @return string name of the DB driver
139
     */
140
    public function getDriverName()
141
    {
142
        return 'hiart';
143
    }
144
145
    /**
146
     * Creates a command for execution.
147
     * @param array $config the configuration for the Command class
148
     * @return Command the DB command
149
     */
150 2
    public function createCommand(array $config = [])
151
    {
152 2
        $config['db'] = $this;
153
154 2
        return new $this->commandClass($config);
155
    }
156
157
    /**
158
     * @return AbstractQueryBuilder the query builder for this connection
159
     */
160 3
    public function getQueryBuilder()
161
    {
162 3
        if ($this->_builder === null) {
163 2
            $this->_builder = new $this->queryBuilderClass($this);
164
        }
165
166 3
        return $this->_builder;
167
    }
168
169
    /**
170
     * Handler is created and set by request.
171
     * @see setHandler
172
     * @return object
173
     */
174
    public function getHandler()
175
    {
176
        return $this->_handler;
177
    }
178
179
    /**
180
     * Requests use this function to keep request handler.
181
     * @param object $handler
182
     */
183
    public function setHandler($handler)
184
    {
185
        $this->_handler = $handler;
186
    }
187
188
    /**
189
     * @return boolean
190
     */
191
    public function isDisabledAuth()
192
    {
193
        return $this->_disabledAuth;
194
    }
195
196
    /**
197
     * @param boolean $disabledAuth
198
     */
199
    public function setDisabledAuth($disabledAuth)
200
    {
201
        $this->_disabledAuth = $disabledAuth;
202
    }
203
204
    /**
205
     * Disables auth and calls $closure.
206
     *
207
     * @param Closure $closure
208
     * @return mixed
209
     */
210
    public function callWithDisabledAuth(Closure $closure)
211
    {
212
        if ($this->isDisabledAuth()) {
213
            return call_user_func($closure);
214
        }
215
216
        try {
217
            $this->disableAuth();
218
219
            return call_user_func($closure);
220
        } finally {
221
            $this->enableAuth();
222
        }
223
    }
224
225
    /**
226
     * Try to decode error information if it is valid json, return it if not.
227
     * @param $body
228
     * @return mixed
229
     */
230
    protected function decodeErrorBody($body)
231
    {
232
        try {
233
            $decoded = Json::decode($body);
234
            if (isset($decoded['error'])) {
235
                $decoded['error'] = preg_replace('/\b\w+?Exception\[/',
236
                    "<span style=\"color: red;\">\\0</span>\n               ", $decoded['error']);
237
            }
238
239
            return $decoded;
240
        } catch (InvalidParamException $e) {
241
            return $body;
242
        }
243
    }
244
245
    /**
246
     * Setter for errorChecker.
247
     * @param Closure $checker
248
     */
249
    public function setErrorChecker($checker)
250
    {
251
        $this->_errorChecker = $checker;
252
    }
253
254
    /**
255
     * Checks response method and raises exception if error found.
256
     * @param ResponseInterface $response response data from API
257
     * @throws ResponseErrorException when response is invalid
258
     */
259 2
    public function checkResponse(ResponseInterface $response)
260
    {
261 2
        if (isset($this->_errorChecker)) {
262
            $error = call_user_func($this->_errorChecker, $response);
263
        } else {
264 2
            $error = $this->getResponseError($response);
265
        }
266
267 2
        if ($error) {
268
            throw new ResponseErrorException($error, $response);
269
        }
270 2
    }
271
272
    /**
273
     * Method checks whether the response is an error.
274
     *
275
     * @param ResponseInterface $response
276
     * @return false|string the error text or boolean `false`, when the response is not an error
277
     */
278
    abstract public function getResponseError(ResponseInterface $response);
279
280
    protected $baseUriChecked;
281
282
    /**
283
     * Return API base uri.
284
     * Adds trailing slash if uri is domain only.
285
     * @return string
286
     */
287 4
    public function getBaseUri()
288
    {
289 4
        if (empty($this->baseUriChecked)) {
290 3
            if (preg_match('#^https?://[^/]+$#', $this->baseUri)) {
291 1
                $this->baseUri .= '/';
292
            }
293 3
            $this->baseUriChecked = true;
294
        }
295
296 4
        return $this->baseUri;
297
    }
298
299 2
    public function getUserAgent()
300
    {
301 2
        return $this->userAgent;
302
    }
303
}
304