Db   A
last analyzed

Complexity

Total Complexity 38

Size/Duplication

Total Lines 334
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 74.73%

Importance

Changes 0
Metric Value
wmc 38
lcom 1
cbo 1
dl 0
loc 334
ccs 68
cts 91
cp 0.7473
rs 9.36
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A construct() 0 4 1
C init() 0 51 11
A getStatus() 0 21 5
A setAutoIncrement() 0 13 2
B countTablePrefix() 0 39 6
A forTablePrefix() 0 4 1
A leftJoinPrefix() 0 4 1
A whereLikeMany() 0 4 1
A whereLanguageIs() 0 4 1
A findFlatArray() 0 4 1
A orderBySetting() 0 5 1
A limitBySetting() 0 15 3
A getSetting() 0 18 4
1
<?php
2
namespace Redaxscript;
3
4
use ORM;
5
use PDO;
6
use PDOException;
7
use function array_column;
8
use function implode;
9
use function strstr;
10
11
/**
12
 * children class to handle the database
13
 *
14
 * @since 2.2.0
15
 *
16
 * @package Redaxscript
17
 * @category Db
18
 * @author Henry Ruhs
19
 *
20
 * @method $this _addJoinSource(string $operator, string $table, string|array $constraint, string $tableAlias)
21
 * @method $this _addOrderBy(string $column, string $value)
22
 * @method $this _addWhere(string $clause, string|array $value)
23
 */
24
25
class Db extends ORM
26
{
27
	/**
28
	 * instance of the config class
29
	 *
30
	 * @var Config
31
	 */
32
33
	protected static $_config;
34
35
	/**
36
	 * constructor of the class
37
	 *
38
	 * @since 2.6.0
39
	 *
40
	 * @param Config $config instance of the config class
41
	 */
42
43 4
	public static function construct(Config $config) : void
44
	{
45 4
		self::$_config = $config;
46 4
	}
47
48
	/**
49
	 * init the class
50
	 *
51
	 * @since 3.1.0
52
	 */
53
54 4
	public static function init() : void
55
	{
56 4
		$dbType = self::$_config->get('dbType');
57 4
		$dbHost = self::$_config->get('dbHost');
58 4
		$dbName = self::$_config->get('dbName');
59 4
		$dbUser = self::$_config->get('dbUser');
60 4
		$dbPassword = self::$_config->get('dbPassword');
61 4
		$dbSocket = strstr($dbHost, '.sock');
62
63
		/* handle various types */
64
65 4
		if ($dbType === 'mssql' || $dbType === 'mysql' || $dbType === 'pgsql')
66
		{
67 3
			if ($dbType === 'mssql')
68
			{
69 1
				self::configure('connection_string', 'sqlsrv:server=' . $dbHost . ';database=' . $dbName);
70
			}
71 3
			if ($dbType === 'mysql')
72
			{
73 1
				self::configure('connection_string', 'mysql:' . ($dbSocket ? 'unix_socket' : 'host') . '=' . $dbHost . ';dbname=' . $dbName . ';charset=utf8');
74
			}
75 3
			if ($dbType === 'pgsql')
76
			{
77 1
				self::configure('connection_string', 'pgsql:' . ($dbSocket ? 'unix_socket' : 'host') . '=' . $dbHost . ';dbname=' . $dbName . ';options=--client_encoding=utf8');
78
			}
79
80
			/* username and password */
81
82 3
			self::configure('username', $dbUser);
83 3
			if ($dbPassword)
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $dbPassword of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
84
			{
85 3
				self::configure('password', $dbPassword);
86
			}
87
		}
88
89
		/* else handle sqlite */
90
91 4
		if ($dbType === 'sqlite')
92
		{
93 1
			self::configure('sqlite:' . $dbHost);
94
		}
95
96
		/* general */
97
98 4
		self::configure(
99
		[
100 4
			'caching' => true,
101
			'caching_auto_clear' => true,
102
			'return_result_sets' => true
103
		]);
104 4
	}
105
106
	/**
107
	 * get the database status
108
	 *
109
	 * @since 3.1.0
110
	 *
111
	 * @return int
112
	 */
113
114 1
	public static function getStatus() : int
115
	{
116 1
		$output = 0;
117
118
		/* has connection */
119
120
		try
121
		{
122 1
			$dbType = self::$_config->get('dbType') === 'mssql' ? 'sqlsrv' : self::$_config->get('dbType');
123 1
			$dbDriver = self::getDb()->getAttribute(PDO::ATTR_DRIVER_NAME);
124 1
			if ($dbType === $dbDriver)
125
			{
126 1
				$output = self::countTablePrefix() > 7 ? 2 : 1;
127
			}
128
		}
129
		catch (PDOException $exception)
130
		{
131
			$output = 0;
132
		}
133 1
		return $output;
134
	}
135
136
	/**
137
	 * set the auto increment
138
	 *
139
	 * @since 4.0.0
140
	 *
141
	 * @param string $table name of the table
142
	 * @param int $increment value of the auto increment
143
	 *
144
	 * @return bool
145
	 */
146
147
	public static function setAutoIncrement(string $table = null, int $increment = 0) : bool
148
	{
149
		$dbType = self::$_config->get('dbType');
150
		$dbPrefix = self::$_config->get('dbPrefix');
151
152
		/* mysql */
153
154
		if ($dbType === 'mysql')
155
		{
156
			return self::rawExecute('ALTER TABLE ' . $dbPrefix . $table . ' AUTO_INCREMENT = ' . $increment);
157
		}
158
		return false;
159
	}
160
161
	/**
162
	 * count table with prefix
163
	 *
164
	 * @since 3.1.0
165
	 *
166
	 * @return int
167
	 */
168
169 2
	public static function countTablePrefix() : int
170
	{
171 2
		$output = 0;
172 2
		$dbType = self::$_config->get('dbType');
173 2
		$dbName = self::$_config->get('dbName');
174 2
		$dbPrefix = self::$_config->get('dbPrefix');
175
176
		/* mssql and mysql */
177
178 2
		if ($dbType === 'mssql' || $dbType === 'mysql')
179
		{
180
			$output = self::forTable('information_schema.tables')
181
				->where($dbType === 'mssql' ? 'table_catalog' : 'table_schema', $dbName)
182
				->whereLike('table_name', $dbPrefix . '%')
183
				->count();
184
		}
185
186
		/* pgsql */
187
188 2
		if ($dbType === 'pgsql')
189
		{
190
			$output = self::forTable('pg_catalog.pg_tables')
191
				->whereLike('tablename', $dbPrefix . '%')
192
				->whereNotLike('tablename', 'pg_%')
193
				->whereNotLike('tablename', 'sql_%')
194
				->count();
195
		}
196
197
		/* sqlite */
198
199 2
		if ($dbType === 'sqlite')
200
		{
201 2
			$output = self::forTable('sqlite_master')
202 2
				->whereLike('tbl_name', $dbPrefix . '%')
203 2
				->whereNotLike('tbl_name', 'sql_%')
204 2
				->count();
205
		}
206 2
		return $output;
207
	}
208
209
	/**
210
	 * for table with prefix
211
	 *
212
	 * @since 2.2.0
213
	 *
214
	 * @param string $table name of the table
215
	 * @param string $connection which connection to use
216
	 *
217
	 * @return self
218
	 */
219
220 14
	public static function forTablePrefix(string $table = null, string $connection = self::DEFAULT_CONNECTION) : self
221
	{
222 14
		return new self(self::$_config->get('dbPrefix') . $table, [], $connection);
223
	}
224
225
	/**
226
	 * left join with prefix
227
	 *
228
	 * @since 2.2.0
229
	 *
230
	 * @param string $table name of the table
231
	 * @param string|array $constraint constraint as needed
232
	 * @param string $tableAlias alias of the table
233
	 *
234
	 * @return self
235
	 */
236
237 1
	public function leftJoinPrefix(string $table = null, string $constraint = null, string $tableAlias = null) : self
238
	{
239 1
		return $this->_addJoinSource('LEFT', self::$_config->get('dbPrefix') . $table, $constraint, $tableAlias);
240
	}
241
242
	/**
243
	 * where like with many
244
	 *
245
	 * @since 3.0.0
246
	 *
247
	 * @param array $columnArray array of column names
248
	 * @param array $likeArray array of the like
249
	 *
250
	 * @return self
251
	 */
252
253 1
	public function whereLikeMany(array $columnArray = [], array $likeArray = []) : self
254
	{
255 1
		return $this->_addWhere('(' . implode($columnArray, ' LIKE ? OR ') . ' LIKE ?)', $likeArray);
256
	}
257
258
	/**
259
	 * where language is
260
	 *
261
	 * @since 3.0.0
262
	 *
263
	 * @param string $language value of the language
264
	 *
265
	 * @return self
266
	 */
267
268 3
	public function whereLanguageIs(string $language = null) : self
269
	{
270 3
		return $this->_addWhere('(language = ? OR language IS NULL)', $language);
271
	}
272
273
	/**
274
	 * find the flat array
275
	 *
276
	 * @since 4.0.0
277
	 *
278
	 * @param string $column name of the column
279
	 *
280
	 * @return array
281
	 */
282
283
	public function findFlatArray(string $column = 'id') : array
284
	{
285
		return array_column($this->findArray(), $column);
286
	}
287
288
	/**
289
	 * order by global setting
290
	 *
291
	 * @since 3.3.0
292
	 *
293
	 * @param string $column name of the column
294
	 *
295
	 * @return self
296
	 */
297
298 1
	public function orderBySetting(string $column = 'rank') : self
299
	{
300 1
		$order = $this->getSetting('order');
301 1
		return $this->_addOrderBy($column, $order);
302
	}
303
304
	/**
305
	 * limit by global setting
306
	 *
307
	 * @since 3.3.0
308
	 *
309
	 * @param int $step step of the offset
310
	 *
311
	 * @return self
312
	 */
313
314 1
	public function limitBySetting(int $step = null) : self
315
	{
316 1
		$dbType = self::$_config->get('dbType');
317 1
		$limit = $this->getSetting('limit');
318 1
		$this->limit($limit);
319 1
		if ($step > 0)
320
		{
321
			if ($dbType === 'mssql')
322
			{
323
				return $this;
324
			}
325
			$this->offset($step * $limit);
326
		}
327 1
		return $this;
328
	}
329
330
	/**
331
	 * get the value from settings
332
	 *
333
	 * @since 4.0.0
334
	 *
335
	 * @param string $key key of the item
336
	 *
337
	 * @return string|null
338
	 */
339
340 2
	public function getSetting(string $key = null) : ?string
341
	{
342 2
		$settings = self::forTablePrefix('settings')->findMany();
343
344
		/* process settings */
345
346 2
		if ($key)
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $key of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
347
		{
348 2
			foreach ($settings as $setting)
349
			{
350 2
				if ($setting->name === $key)
351
				{
352 2
					return $setting->value;
353
				}
354
			}
355
		}
356
		return null;
357
	}
358
}
359