Completed
Push — master ( 5c0dbc...42c9a9 )
by Nazar
04:27
created

Config   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 229
ccs 85
cts 85
cp 1
rs 10
c 0
b 0
f 0
wmc 25
lcom 1
cbo 10

12 Methods

Rating   Name   Duplication   Size   Complexity  
A fill_mirrors() 0 13 2
A cdb() 0 3 1
A core_url() 0 4 1
A construct() 0 11 2
A apply() 0 3 1
B apply_internal() 0 25 3
B save() 0 16 5
A cancel_available() 0 3 1
A cancel() 0 4 1
A base_url() 0 11 3
A module() 0 6 2
A load_configuration() 0 17 3
1
<?php
2
/**
3
 * @package   CleverStyle Framework
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2011-2016, Nazar Mokrynskyi
6
 * @license   MIT License, see license.txt
7
 */
8
namespace cs;
9
10
/**
11
 * Provides next events:
12
 *  System/Config/init/before
13
 *
14
 *  System/Config/init/after
15
 *
16
 *  System/Config/changed
17
 *
18
 * @method static $this instance($check = false)
19
 */
20
class Config {
21
	use
22
		CRUD,
23
		Singleton;
24
	const SYSTEM_MODULE = 'System';
25
	const SYSTEM_THEME  = 'CleverStyle';
26
	/**
27
	 * Most of general configuration properties
28
	 *
29
	 * @var mixed[]
30
	 */
31
	public $core = [];
32
	/**
33
	 * Configuration of databases, except the main database, parameters of which are stored in configuration file
34
	 *
35
	 * @var mixed[]
36
	 */
37
	public $db = [];
38
	/**
39
	 * Configuration of storages, except the main storage, parameters of which are stored in configuration file
40
	 *
41
	 * @var mixed[]
42
	 */
43
	public $storage = [];
44
	/**
45
	 * Internal structure of components parameters
46
	 *
47
	 * @var mixed[]
48
	 */
49
	public $components = [];
50
	/**
51
	 * Array of all domains, which allowed to access the site
52
	 *
53
	 * Contains keys:
54
	 * * count - Total count
55
	 * * http - Insecure (http) domains
56
	 * * https - Secure (https) domains
57
	 *
58
	 * @var array
59
	 */
60
	public    $mirrors;
61
	protected $data_model = [
62
		'domain'     => 'text',
63
		'core'       => 'json',
64
		'db'         => 'json',
65
		'storage'    => 'json',
66
		'components' => 'json'
67
	];
68
	protected $table      = '[prefix]config';
69 4
	protected function cdb () {
70 4
		return 0;
71
	}
72
	/**
73
	 * Loading of configuration, initialization of $Config, $Cache, $L and Page objects, Routing processing
74
	 *
75
	 * @throws ExitException
76
	 */
77 50
	protected function construct () {
78 50
		Event::instance()->fire('System/Config/init/before');
79 50
		$this->load_configuration();
80 50
		date_default_timezone_set($this->core['timezone']);
81 50
		$this->fill_mirrors();
82 50
		Event::instance()->fire('System/Config/init/after');
83 50
		if (!file_exists(MODULES.'/'.$this->core['default_module'])) {
84 2
			$this->core['default_module'] = self::SYSTEM_MODULE;
85 2
			$this->save();
86
		}
87 50
	}
88
	/**
89
	 * Is used to fill `$this->mirrors` using current configuration
90
	 */
91 50
	protected function fill_mirrors () {
92 50
		$this->mirrors = [
93
			'count' => 0,
94
			'http'  => [],
95
			'https' => []
96
		];
97 50
		foreach ($this->core['url'] as $i => $address) {
98 50
			list($protocol, $urls) = explode('://', $address, 2);
99 50
			$urls                       = explode(';', $urls);
100 50
			$this->mirrors[$protocol][] = $urls[0];
101
		}
102 50
		$this->mirrors['count'] = count($this->mirrors['http']) + count($this->mirrors['https']);
103 50
	}
104
	/**
105
	 * Reloading of settings cache
106
	 *
107
	 * @throws ExitException
108
	 */
109 50
	protected function load_configuration () {
110 50
		$config = Cache::instance()->get(
111 50
			'config',
112 50
			function () {
113 4
				return $this->read(Core::instance()->domain);
114 50
			}
115
		);
116 50
		if (!$config) {
117 2
			throw new ExitException('Failed to load system configuration', 500);
118
		}
119 50
		foreach ($config as $part => $value) {
120 50
			$this->$part = $value;
121
		}
122 50
		$this->core += file_get_json(MODULES.'/System/core_settings_defaults.json');
123 50
		date_default_timezone_set($this->core['timezone']);
124 50
		$this->fill_mirrors();
125 50
	}
126
	/**
127
	 * Applying settings without saving changes into db
128
	 *
129
	 * @return bool
130
	 *
131
	 * @throws ExitException
132
	 */
133 2
	function apply () {
134 2
		return $this->apply_internal();
135
	}
136
	/**
137
	 * Applying settings without saving changes into db
138
	 *
139
	 * @param bool $cache_not_saved_mark
140
	 *
141
	 * @return bool
142
	 *
143
	 * @throws ExitException
144
	 */
145 2
	protected function apply_internal ($cache_not_saved_mark = true) {
146 2
		if ($cache_not_saved_mark) {
147 2
			$this->core['cache_not_saved'] = true;
148
		} else {
149 2
			unset($this->core['cache_not_saved']);
150
		}
151 2
		$Cache = Cache::instance();
152 2
		if (!$Cache->set(
153 2
			'config',
154
			[
155 2
				'core'       => $this->core,
156 2
				'db'         => $this->db,
157 2
				'storage'    => $this->storage,
158 2
				'components' => $this->components
159
			]
160
		)
161
		) {
162 2
			return false;
163
		}
164 2
		$Cache->del('languages');
165 2
		date_default_timezone_set($this->core['timezone']);
166 2
		$this->fill_mirrors();
167 2
		Event::instance()->fire('System/Config/changed');
168 2
		return true;
169
	}
170
	/**
171
	 * Saving settings
172
	 *
173
	 * @return bool
174
	 *
175
	 * @throws ExitException
176
	 */
177 2
	function save () {
178 2
		if ($this->cancel_available()) {
179 2
			unset($this->core['cache_not_saved']);
180
		}
181 2
		$core_settings_defaults = file_get_json(MODULES.'/System/core_settings_defaults.json');
182 2
		$this->core += $core_settings_defaults;
183 2
		foreach ($this->core as $key => $value) {
184 2
			if (!isset($core_settings_defaults[$key])) {
185 2
				unset($this->core[$key]);
186
			}
187
		}
188 2
		if (!$this->update(Core::instance()->domain, $this->core, $this->db, $this->storage, $this->components)) {
189 2
			return false;
190
		}
191 2
		return $this->apply_internal(false);
192
	}
193
	/**
194
	 * Whether configuration was applied (not saved) and can be canceled
195
	 *
196
	 * @return bool
197
	 */
198 2
	function cancel_available () {
199 2
		return isset($this->core['cache_not_saved']);
200
	}
201
	/**
202
	 * Canceling of applied settings
203
	 *
204
	 * @throws ExitException
205
	 */
206 2
	function cancel () {
207 2
		Cache::instance()->del('config');
208 2
		$this->load_configuration();
209 2
	}
210
	/**
211
	 * Get base url of current mirror including language suffix
212
	 *
213
	 * @return string
214
	 */
215 8
	function base_url () {
216 8
		if (Request::instance()->mirror_index === -1) {
217 2
			return '';
218
		}
219 8
		$base_url = $this->core_url();
220 8
		if ($this->core['multilingual']) {
221 4
			$L = Language::instance();
222 4
			$base_url .= "/$L->clang";
223
		}
224 8
		return $base_url;
225
	}
226
	/**
227
	 * Get base url of main domain
228
	 *
229
	 * @return string
230
	 */
231 32
	function core_url () {
232 32
		$Request = Request::instance();
233 32
		return "$Request->scheme://$Request->host";
234
	}
235
	/**
236
	 * Get object for getting db and storage configuration of module
237
	 *
238
	 * @param string $module_name
239
	 *
240
	 * @return Config\Module_Properties
241
	 */
242 40
	function module ($module_name) {
243 40
		if (!isset($this->components['modules'][$module_name])) {
244 2
			return False_class::instance();
245
		}
246 40
		return new Config\Module_Properties($this->components['modules'][$module_name], $module_name);
247
	}
248
}
249