RedisSource::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 10
rs 10
1
<?php
2
App::uses('DataSource', 'Model/Datasource');
3
4
/**
5
 * Redis Source class
6
 *
7
 */
8
class RedisSource extends DataSource {
0 ignored issues
show
Bug introduced by
The type DataSource was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
/**
11
 * Datasource description.
12
 *
13
 * @var string
14
 */
15
	public $description = 'Redis Data Source';
16
17
/**
18
 * Base configuration.
19
 *
20
 * @var array
21
 */
22
	protected $_baseConfig = [
23
		'host' => '127.0.0.1',
24
		'port' => 6379,
25
		'password' => '',
26
		'database' => 0,
27
		'timeout' => 0,
28
		'persistent' => false,
29
		'unix_socket' => '',
30
		'prefix' => '',
31
	];
32
33
/**
34
 * Configuration.
35
 *
36
 * @var array
37
 */
38
	public $config = [];
39
40
/**
41
 * A reference to the physical connection of this DataSource.
42
 *
43
 * @var Redis
44
 */
45
	protected $_connection = null;
46
47
/**
48
 * Whether or not we are connected to the DataSource.
49
 *
50
 * @var bool
51
 */
52
	public $connected = false;
53
54
/**
55
 * Whether or not source data like available tables and schema descriptions should be cached.
56
 *
57
 * @var bool
58
 */
59
	public $cacheSources = false;
60
61
/**
62
 * Constructor.
63
 *
64
 * @param array $config Array of configuration information for the Datasource
65
 * @return bool True if connecting to the DataSource succeeds, else false
66
 * @throws RedisSourceException
67
 */
68
	public function __construct($config = []) {
69
		parent::__construct($config);
70
71
		if (!$this->enabled()) {
72
			throw new RedisSourceException(__d('redis', 'Extension is not loaded.'));
0 ignored issues
show
Bug introduced by
The function __d was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

72
			throw new RedisSourceException(/** @scrutinizer ignore-call */ __d('redis', 'Extension is not loaded.'));
Loading history...
73
		}
74
75
		$this->_connection = new Redis();
76
77
		return $this->connect();
78
	}
79
80
/**
81
 * Destructor.
82
 *
83
 *  Closes the connection to the host (if needed).
84
 *
85
 * @return void
86
 * @todo Write test
87
 */
88
	public function __destruct() {
89
		if (!$this->config['persistent']) {
90
			$this->close();
91
		}
92
	}
93
94
/**
95
 * Passes (non-existing) method calls to `Redis`.
96
 *
97
 * @param string $name The name of the method being called
98
 * @param array $arguments An enumerated array containing the parameters passed to the method
99
 * @return mixed Method return value
100
 * @throws RedisSourceException
101
 */
102
	public function __call($name, $arguments) {
103
		if (!method_exists($this->_connection, $name)) {
104
			throw new RedisSourceException(__d('redis', 'Method (%s) does not exist.', $name));
0 ignored issues
show
Bug introduced by
The function __d was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

104
			throw new RedisSourceException(/** @scrutinizer ignore-call */ __d('redis', 'Method (%s) does not exist.', $name));
Loading history...
105
		}
106
107
		try {
108
			return call_user_func_array([$this->_connection, $name], $arguments);
109
		} catch (RedisException $e) {
110
			throw new RedisSourceException(__d('redis', 'Method (%s) failed: %s.', $name, $e->getMessage()));
111
		}
112
	}
113
114
/**
115
 * Check that the redis extension is loaded.
116
 *
117
 * @return bool Whether or not the extension is loaded
118
 */
119
	public function enabled() {
120
		return extension_loaded('redis');
121
	}
122
123
/**
124
 * Connects to the database using options in the given configuration array.
125
 *
126
 *  "Connects" means:
127
 *  - connect
128
 *  - authenticate
129
 *  - select
130
 *  - setPrefix
131
 *
132
 * @return bool True if all of the above steps succeed, else false
133
 * @throws RedisSourceException
134
 */
135
	public function connect() {
136
		if (!$this->_connect()) {
137
			throw new RedisSourceException(__d('redis', 'Could not connect.'));
0 ignored issues
show
Bug introduced by
The function __d was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

137
			throw new RedisSourceException(/** @scrutinizer ignore-call */ __d('redis', 'Could not connect.'));
Loading history...
138
		}
139
140
		if (!$this->_authenticate()) {
141
			throw new RedisSourceException(__d('redis', 'Could not authenticate.'));
142
		}
143
144
		if (!$this->_select()) {
145
			throw new RedisSourceException(__d('redis', 'Could not select.'));
146
		}
147
148
		if (!$this->_setPrefix()) {
149
			throw new RedisSourceException(__d('redis', 'Could not set prefix.'));
150
		}
151
152
		$this->connected = true;
153
154
		return $this->connected;
155
	}
156
157
/**
158
 * Connects to the database using options in the given configuration array.
159
 *
160
 * @return bool True if connecting to the DataSource succeeds, else false
161
 */
162
	protected function _connect() {
163
		$unixSocket = $this->config['unix_socket'];
164
		$persistent = $this->config['persistent'];
165
		$host = $this->config['host'];
166
		$port = $this->config['port'];
167
		$timeout = $this->config['timeout'];
168
169
		if ($unixSocket) {
170
			return $this->_connection->connect($unixSocket);
171
		} elseif ($persistent) {
172
			return $this->_connection->pconnect($host, $port, $timeout, $persistent);
173
		} else {
174
			return $this->_connection->connect($host, $port, $timeout);
175
		}
176
	}
177
178
/**
179
 * Authenticates to the database (if needed) using options in the given configuration array.
180
 *
181
 * @return bool True if the authentication succeeded or no password was specified, else false
182
 */
183
	protected function _authenticate() {
184
		if ($this->config['password']) {
185
			return $this->_connection->auth($this->config['password']);
186
		}
187
188
		return true;
189
	}
190
191
/**
192
 * Selects a database (if needed) using options in the given configuration array.
193
 *
194
 * @return bool True if the select succeeded or no database was specified, else false
195
 */
196
	protected function _select() {
197
		if ($this->config['database']) {
198
			return $this->_connection->select($this->config['database']);
199
		}
200
201
		return true;
202
	}
203
204
/**
205
 * Sets a prefix for all keys (if needed) using options in the given configuration array.
206
 *
207
 * @return bool True if setting the prefix succeeded or no prefix was specified, else false
208
 */
209
	protected function _setPrefix() {
210
		if ($this->config['prefix']) {
211
			return $this->_connection->setOption(Redis::OPT_PREFIX, $this->config['prefix']);
212
		}
213
214
		return true;
215
	}
216
217
/**
218
 * Closes a connection.
219
 *
220
 * @return bool Always true
221
 */
222
	public function close() {
223
		if ($this->isConnected()) {
224
			$this->_connection->close();
225
		}
226
227
		$this->connected = false;
228
		$this->_connection = null;
229
230
		return true;
231
	}
232
233
/**
234
 * Checks if the source is connected to the database.
235
 *
236
 * @return bool True if the database is connected, else false
237
 */
238
	public function isConnected() {
239
		return $this->connected;
240
	}
241
242
/**
243
 * Caches/returns cached results for child instances.
244
 *
245
 * @param mixed $data List of tables
246
 * @return array Array of sources available in this datasource
247
 */
248
	public function listSources($data = null) {
249
		return parent::listSources($data);
250
	}
251
252
/**
253
 * Returns a Model description (metadata) or null if none found.
254
 *
255
 * @param Model|string $model Name of database table to inspect or model instance
0 ignored issues
show
Bug introduced by
The type Model was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
256
 * @return array Array of Metadata for the $model
257
 */
258
	public function describe($model) {
259
		return parent::describe($model);
260
	}
261
262
}
263
264
/**
265
 * Redis Source Exception class.
266
 *
267
 */
268
class RedisSourceException extends CakeException {
0 ignored issues
show
Bug introduced by
The type CakeException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
269
}
270