Completed
Push — master ( da58d4...61a0f7 )
by Henry
06:34
created

includes/Db.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 4
43
	public static function construct(Config $config) : void
44 4
	{
45 4
		self::$_config = $config;
46
	}
47
48
	/**
49
	 * init the class
50
	 *
51
	 * @since 3.1.0
52
	 */
53 4
54
	public static function init() : void
55 4
	{
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
		$dbSocket = strstr($dbHost, '.sock');
62
63
		/* handle various types */
64 4
65
		if ($dbType === 'mssql' || $dbType === 'mysql' || $dbType === 'pgsql')
66 3
		{
67
			if ($dbType === 'mssql')
68 1
			{
69
				self::configure('connection_string', 'sqlsrv:server=' . $dbHost . ';database=' . $dbName);
70 3
			}
71
			if ($dbType === 'mysql')
72 1
			{
73
				self::configure('connection_string', 'mysql:' . ($dbSocket ? 'unix_socket' : 'host') . '=' . $dbHost . ';dbname=' . $dbName . ';charset=utf8');
74 3
			}
75
			if ($dbType === 'pgsql')
76 1
			{
77
				self::configure('connection_string', 'pgsql:' . ($dbSocket ? 'unix_socket' : 'host') . '=' . $dbHost . ';dbname=' . $dbName . ';options=--client_encoding=utf8');
78
			}
79
80
			/* username and password */
81 3
82 3
			self::configure('username', $dbUser);
83
			if ($dbPassword)
0 ignored issues
show
Bug Best Practice introduced by
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 3
			{
85
				self::configure('password', $dbPassword);
86
			}
87
		}
88
89
		/* else handle sqlite */
90 4
91
		if ($dbType === 'sqlite')
92 1
		{
93
			self::configure('sqlite:' . $dbHost);
94
		}
95
96
		/* general */
97 4
98
		self::configure(
99 4
		[
100
			'caching' => true,
101
			'caching_auto_clear' => true,
102
			'return_result_sets' => true
103 4
		]);
104
	}
105
106
	/**
107
	 * get the database status
108
	 *
109
	 * @since 3.1.0
110
	 *
111
	 * @return int
112
	 */
113 1
114
	public static function getStatus() : int
115 1
	{
116
		$output = 0;
117
118
		/* has connection */
119
120
		try
121 1
		{
122 1
			$dbType = self::$_config->get('dbType') === 'mssql' ? 'sqlsrv' : self::$_config->get('dbType');
123 1
			$dbDriver = self::getDb()->getAttribute(PDO::ATTR_DRIVER_NAME);
124
			if ($dbType === $dbDriver)
125 1
			{
126
				$output = self::countTablePrefix() > 7 ? 2 : 1;
127
			}
128
		}
129
		catch (PDOException $exception)
130
		{
131
			$output = 0;
132 1
		}
133
		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 2
169
	public static function countTablePrefix() : int
170 2
	{
171 2
		$output = 0;
172 2
		$dbType = self::$_config->get('dbType');
173 2
		$dbName = self::$_config->get('dbName');
174
		$dbPrefix = self::$_config->get('dbPrefix');
175
176
		/* mssql and mysql */
177 2
178
		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 2
188
		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 2
199
		if ($dbType === 'sqlite')
200 2
		{
201 2
			$output = self::forTable('sqlite_master')
202 2
				->whereLike('tbl_name', $dbPrefix . '%')
203 2
				->whereNotLike('tbl_name', 'sql_%')
204
				->count();
205 2
		}
206
		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 14
220
	public static function forTablePrefix(string $table = null, string $connection = self::DEFAULT_CONNECTION) : self
221 14
	{
222
		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 1
237
	public function leftJoinPrefix(string $table = null, string $constraint = null, string $tableAlias = null) : self
238 1
	{
239
		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 1
253
	public function whereLikeMany(array $columnArray = [], array $likeArray = []) : self
254 1
	{
255
		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 3
268
	public function whereLanguageIs(string $language = null) : self
269 3
	{
270
		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 1
283
	public function findFlatArray(string $column = 'id') : array
284 1
	{
285 1
		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 = null) : self
299
	{
300 1
		$order = $this->getSetting('order');
301 1
		return $this->_addOrderBy($column, $order);
302 1
	}
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
	public function limitBySetting(int $step = null) : self
315 2
	{
316
		$limit = $this->getSetting('limit');
317 2
		$this->_limit = $step > 0 ? $step * $limit . ',' . $limit : $limit;
318
		return $this;
319
	}
320
321 2
	/**
322
	 * get the value from settings
323 2
	 *
324
	 * @since 4.0.0
325 2
	 *
326
	 * @param string $key key of the item
327 2
	 *
328
	 * @return string|null
329
	 */
330
331
	public function getSetting(string $key = null) : ?string
332
	{
333
		$settings = self::forTablePrefix('settings')->findMany();
334
335
		/* process settings */
336
337
		if ($key)
338
		{
339
			foreach ($settings as $setting)
340
			{
341
				if ($setting->name === $key)
342
				{
343
					return $setting->value;
344
				}
345
			}
346
		}
347
		return null;
348
	}
349
}
350