databases::admin_databases_patch()   C
last analyzed

Complexity

Conditions 8
Paths 8

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 19
nc 8
nop 1
dl 0
loc 25
rs 5.3846
c 0
b 0
f 0
ccs 0
cts 20
cp 0
crap 72
1
<?php
2
/**
3
 * @package    CleverStyle Framework
4
 * @subpackage System module
5
 * @category   modules
6
 * @author     Nazar Mokrynskyi <[email protected]>
7
 * @license    0BSD
8
 */
9
namespace cs\modules\System\api\Controller\admin;
10
use
11
	cs\Config,
12
	cs\Core,
13
	cs\ExitException,
14
	cs\Language;
15
16
trait databases {
17
	/**
18
	 * Get array of databases
19
	 */
20
	public static function admin_databases_get () {
21
		$Config       = Config::instance();
22
		$Core         = Core::instance();
23
		$databases    = $Config->db;
24
		$databases[0] = array_merge(
25
			isset($databases[0]) ? $databases[0] : [],
26
			[
27
				'host'    => $Core->db_host,
28
				'driver'  => $Core->db_driver,
29
				'prefix'  => $Core->db_prefix,
30
				'name'    => $Core->db_name,
31
				'user'    => '',
32
				'mirrors' => []
33
			]
34
		);
35
		foreach ($databases as $i => &$db) {
36
			$db['index'] = $i;
37
			foreach ($db['mirrors'] as $j => &$mirror) {
38
				$mirror['index'] = $j;
39
			}
40
			unset($j, $mirror);
41
			$db['mirrors'] = array_values($db['mirrors']);
42
		}
43
		unset($i, $db);
44
		return array_values($databases);
45
	}
46
	/**
47
	 * Update database or database mirror settings
48
	 *
49
	 * @param \cs\Request $Request
50
	 *
51
	 * @throws ExitException
52
	 */
53
	public static function admin_databases_patch ($Request) {
54
		$data = $Request->data('host', 'driver', 'prefix', 'name', 'user', 'password');
0 ignored issues
show
Bug introduced by
'host' of type string is incompatible with the type array<mixed,string[]>|string[] expected by parameter $name of cs\Request::data(). ( Ignorable by Annotation )

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

54
		$data = $Request->data(/** @scrutinizer ignore-type */ 'host', 'driver', 'prefix', 'name', 'user', 'password');
Loading history...
55
		if (!$data || !in_array($data['driver'], static::admin_databases_get_drivers())) {
56
			throw new ExitException(400);
57
		}
58
		$Config         = Config::instance();
59
		$database_index = $Request->route_ids(0);
60
		$databases      = &$Config->db;
61
		if (!isset($databases[$database_index])) {
62
			throw new ExitException(404);
63
		}
64
		$database     = &$databases[$database_index];
65
		$mirror_index = $Request->route_ids(1);
66
		// Maybe, we are changing database mirror
67
		if ($mirror_index !== null) {
0 ignored issues
show
introduced by
The condition $mirror_index !== null is always true.
Loading history...
68
			if (!isset($database['mirrors'][$mirror_index])) {
69
				throw new ExitException(404);
70
			}
71
			$database = &$database['mirrors'][$mirror_index];
72
		} elseif ($database_index == 0) {
73
			throw new ExitException(400);
74
		}
75
		$database = $data + $database;
76
		if (!$Config->save()) {
77
			throw new ExitException(500);
78
		}
79
	}
80
	/**
81
	 * Create database or database mirror
82
	 *
83
	 * @param \cs\Request $Request
84
	 *
85
	 * @throws ExitException
86
	 */
87
	public static function admin_databases_post ($Request) {
88
		$data = $Request->data('mirror', 'host', 'driver', 'prefix', 'name', 'user', 'password');
0 ignored issues
show
Bug introduced by
'mirror' of type string is incompatible with the type array<mixed,string[]>|string[] expected by parameter $name of cs\Request::data(). ( Ignorable by Annotation )

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

88
		$data = $Request->data(/** @scrutinizer ignore-type */ 'mirror', 'host', 'driver', 'prefix', 'name', 'user', 'password');
Loading history...
89
		if (!$data || !in_array($data['driver'], static::admin_databases_get_drivers())) {
90
			throw new ExitException(400);
91
		}
92
		$Config         = Config::instance();
93
		$database_index = $Request->route_ids(0);
94
		$databases      = &$Config->db;
95
		// Maybe, we are adding database mirror
96
		if ($database_index !== null) {
0 ignored issues
show
introduced by
The condition $database_index !== null is always true.
Loading history...
97
			if (!isset($databases[$Request->route_ids[0]])) {
98
				throw new ExitException(404);
99
			}
100
			$databases = &$databases[$Request->route_ids[0]]['mirrors'];
101
		}
102
		$databases[] = $data;
103
		if (!$Config->save()) {
104
			throw new ExitException(500);
105
		}
106
	}
107
	/**
108
	 * Delete database or database mirror
109
	 *
110
	 * @param \cs\Request $Request
111
	 *
112
	 * @throws ExitException
113
	 */
114
	public static function admin_databases_delete ($Request) {
115
		$route_ids = $Request->route_ids;
116
		if (!isset($route_ids[0])) {
117
			throw new ExitException(400);
118
		}
119
		$Config         = Config::instance();
120
		$databases      = &$Config->db;
121
		$database_index = $route_ids[0];
122
		if (!isset($databases[$database_index])) {
123
			throw new ExitException(404);
124
		}
125
		// Maybe, we are deleting database mirror
126
		if (isset($route_ids[1])) {
127
			if (!isset($databases[$database_index]['mirrors'][$route_ids[1]])) {
128
				throw new ExitException(404);
129
			}
130
			unset($databases[$database_index]['mirrors'][$route_ids[1]]);
131
		} elseif ($database_index == 0) {
132
			throw new ExitException(400);
133
		} else {
134
			static::admin_databases_delete_check_usages($database_index);
135
			unset($databases[$database_index]);
136
		}
137
		if (!$Config->save()) {
138
			throw new ExitException(500);
139
		}
140
	}
141
	protected static function admin_databases_delete_check_usages ($database_index) {
142
		$Config  = Config::instance();
143
		$used_by = [];
144
		foreach ($Config->components['modules'] as $module => $module_data) {
145
			if (isset($module_data['db']) && is_array($module_data['db'])) {
146
				foreach ($module_data['db'] as $index) {
147
					if ($index == $database_index) {
148
						$used_by[] = $module;
149
					}
150
				}
151
			}
152
		}
153
		if ($used_by) {
154
			throw new ExitException(
155
				Language::instance()->system_admin_blocks_db_used_by_modules(implode(', ', $used_by)),
0 ignored issues
show
Bug introduced by
The method system_admin_blocks_db_used_by_modules() does not exist on cs\Language. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

155
				Language::instance()->/** @scrutinizer ignore-call */ system_admin_blocks_db_used_by_modules(implode(', ', $used_by)),
Loading history...
156
				409
157
			);
158
		}
159
	}
160
	/**
161
	 * Get array of available database drivers
162
	 */
163
	public static function admin_databases_drivers () {
164
		return static::admin_databases_get_drivers();
165
	}
166
	/**
167
	 * @return string[]
168
	 */
169
	protected static function admin_databases_get_drivers () {
170
		return _mb_substr(get_files_list(DIR.'/core/drivers/DB', '/^[^_].*?\.php$/i', 'f'), 0, -4);
171
	}
172
	/**
173
	 * Test database connection
174
	 *
175
	 * @param \cs\Request $Request
176
	 *
177
	 * @throws ExitException
178
	 */
179
	public static function admin_databases_test ($Request) {
180
		$data    = $Request->data('driver', 'name', 'user', 'password', 'host');
0 ignored issues
show
Bug introduced by
'driver' of type string is incompatible with the type array<mixed,string[]>|string[] expected by parameter $name of cs\Request::data(). ( Ignorable by Annotation )

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

180
		$data    = $Request->data(/** @scrutinizer ignore-type */ 'driver', 'name', 'user', 'password', 'host');
Loading history...
181
		$drivers = static::admin_databases_get_drivers();
182
		if (!$data || !in_array($data['driver'], $drivers, true)) {
183
			throw new ExitException(400);
184
		}
185
		$driver_class = "\\cs\\DB\\$data[driver]";
186
		/**
187
		 * @var \cs\DB\_Abstract $connection
188
		 */
189
		$connection = new $driver_class($data['name'], $data['user'], $data['password'], $data['host']);
190
		if (!$connection->connected()) {
191
			throw new ExitException(500);
192
		}
193
	}
194
	/**
195
	 * Get database settings
196
	 */
197
	public static function admin_databases_get_settings () {
198
		$Config = Config::instance();
199
		return [
200
			'db_balance'     => $Config->core['db_balance'],
201
			'db_mirror_mode' => $Config->core['db_mirror_mode'],
202
			'applied'        => $Config->cancel_available()
203
		];
204
	}
205
	/**
206
	 * Apply database settings
207
	 *
208
	 * @param \cs\Request $Request
209
	 *
210
	 * @throws ExitException
211
	 */
212
	public static function admin_databases_apply_settings ($Request) {
213
		static::admin_databases_settings_common($Request);
214
		if (!Config::instance()->apply()) {
215
			throw new ExitException(500);
216
		}
217
	}
218
	/**
219
	 * @param \cs\Request $Request
220
	 *
221
	 * @throws ExitException
222
	 */
223
	protected static function admin_databases_settings_common ($Request) {
224
		$data = $Request->data('db_balance', 'db_mirror_mode');
0 ignored issues
show
Bug introduced by
'db_balance' of type string is incompatible with the type array<mixed,string[]>|string[] expected by parameter $name of cs\Request::data(). ( Ignorable by Annotation )

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

224
		$data = $Request->data(/** @scrutinizer ignore-type */ 'db_balance', 'db_mirror_mode');
Loading history...
225
		if (!$data) {
226
			throw new ExitException(400);
227
		}
228
		$Config                         = Config::instance();
229
		$Config->core['db_balance']     = (int)(bool)$data['db_balance'];
230
		$Config->core['db_mirror_mode'] = (int)(bool)$data['db_mirror_mode'];
231
	}
232
	/**
233
	 * Save database settings
234
	 *
235
	 * @param \cs\Request $Request
236
	 *
237
	 * @throws ExitException
238
	 */
239
	public static function admin_databases_save_settings ($Request) {
240
		static::admin_databases_settings_common($Request);
241
		if (!Config::instance()->save()) {
242
			throw new ExitException(500);
243
		}
244
	}
245
	/**
246
	 * Cancel database settings
247
	 *
248
	 * @throws ExitException
249
	 */
250
	public static function admin_databases_cancel_settings () {
251
		Config::instance()->cancel();
252
	}
253
}
254