Completed
Push — master ( 25d3e2...ec2dfb )
by Steve
20:28 queued 07:36
created

Config::setConfigTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Elgg;
3
4
use Elgg\Filesystem\Directory;
5
use Elgg\Database\ConfigTable;
6
7
/**
8
 * Access to configuration values
9
 *
10
 * @since 1.10.0
11
 */
12
class Config implements Services\Config {
13
	/**
14
	 * Configuration storage. Is usually reference to global $CONFIG
15
	 *
16
	 * @var \stdClass
17
	 */
18
	private $config;
19
20
	/**
21
	 * @var bool
22
	 */
23
	private $settings_loaded = false;
24
25
	/**
26
	 * @var bool
27
	 */
28
	private $cookies_configured = false;
29
30
	/**
31
	 * @var ConfigTable Do not use directly. Use getConfigTable().
32
	 */
33
	private $config_table;
34
35
	/**
36
	 * Constructor
37
	 *
38
	 * @internal Access this object via Elgg\Application::$config
39
	 *
40
	 * @param \stdClass $config     Elgg's $CONFIG object
41
	 * @param bool      $set_global Copy the config object to global $CONFIG
42
	 */
43 187
	public function __construct(\stdClass $config = null, $set_global = true) {
44 187
		if (!$config) {
45
			$config = new \stdClass();
46
		}
47 187
		$this->config = $config;
48 187
		$this->config->path = Directory\Local::root()->getPath('/');
49
50 187
		if ($set_global) {
51
			/**
52
			 * Configuration values.
53
			 *
54
			 * The $CONFIG global contains configuration values required
55
			 * for running Elgg as defined in the settings.php file.
56
			 *
57
			 * Plugin authors are encouraged to use elgg_get_config() instead of accessing
58
			 * the global directly.
59
			 *
60
			 * @see elgg_get_config()
61
			 * @see engine/settings.php
62
			 * @global \stdClass $CONFIG
63
			 */
64 187
			global $CONFIG;
65 187
			$CONFIG = $config;
66
		}
67 187
	}
68
69
	/**
70
	 * {@inheritdoc}
71
	 */
72 215
	public function getSiteUrl() {
73 215
		return $this->config->wwwroot;
74
	}
75
76
	/**
77
	 * {@inheritdoc}
78
	 */
79
	public function getPluginsPath() {
80
		return $this->config->pluginspath;
81
	}
82
83
	/**
84
	 * Set up and return the cookie configuration array resolved from settings.php
85
	 *
86
	 * @return array
87
	 */
88 344
	public function getCookieConfig() {
89 344
		$c = $this->config;
90
91 344
		if ($this->cookies_configured) {
92 157
			return $c->cookies;
93
		}
94
95 187
		$this->loadSettingsFile();
96
97
		// set cookie values for session and remember me
98 187
		if (!isset($c->cookies)) {
99
			$c->cookies = [];
100
		}
101 187
		if (!isset($c->cookies['session'])) {
102
			$c->cookies['session'] = [];
103
		}
104 187
		$session_defaults = session_get_cookie_params();
105 187
		$session_defaults['name'] = 'Elgg';
106 187
		$c->cookies['session'] = array_merge($session_defaults, $c->cookies['session']);
107 187
		if (!isset($c->cookies['remember_me'])) {
108
			$c->cookies['remember_me'] = [];
109
		}
110 187
		$session_defaults['name'] = 'elggperm';
111 187
		$session_defaults['expire'] = strtotime("+30 days");
112 187
		$c->cookies['remember_me'] = array_merge($session_defaults, $c->cookies['remember_me']);
113
114 187
		$this->cookies_configured = true;
115
116 187
		return $c->cookies;
117
	}
118
119
	/**
120
	 * {@inheritdoc}
121
	 */
122 15
	public function getDataPath() {
123 15
		$this->loadSettingsFile();
124 15
		return $this->config->dataroot;
125
	}
126
127
	/**
128
	 * {@inheritdoc}
129
	 */
130 2
	public function getCachePath() {
131 2
		$this->loadSettingsFile();
132 2
		return $this->config->cacheroot;
133
	}
134
135
	/**
136
	 * {@inheritdoc}
137
	 */
138 380
	public function get($name, $default = null) {
139 380
		$name = trim($name);
140
	
141 380
		if (isset($this->config->$name)) {
142 295
			return $this->config->$name;
143
		}
144
145 238
		if (!empty($this->config->site_config_loaded)) {
146 238
			return $default;
147
		}
148
		
149
		$value = $this->getConfigTable()->get($name);
150
151
		if ($value === null) {
152
			return $default;
153
		}
154
	
155
		$this->config->$name = $value;
156
		
157
		return $value;
158
	}
159
160
	/**
161
	 * {@inheritdoc}
162
	 */
163 201
	public function getVolatile($name) {
164 201
		return isset($this->config->{$name}) ? $this->config->{$name} : null;
165
	}
166
167
	/**
168
	 * {@inheritdoc}
169
	 */
170 12
	public function set($name, $value) {
171 12
		$name = trim($name);
172 12
		$this->config->$name = $value;
173 12
	}
174
175
	/**
176
	 * {@inheritdoc}
177
	 */
178
	public function save($name, $value) {
179
		$name = trim($name);
180
	
181
		if (strlen($name) > 255) {
182
			_elgg_services()->logger->error("The name length for configuration variables cannot be greater than 255");
183
			return false;
184
		}
185
186
		$result = $this->getConfigTable()->set($name, $value);
187
188
		$this->set($name, $value);
189
	
190
		return $result;
191
	}
192
193
	/**
194
	 * {@inheritdoc}
195
	 */
196
	public function remove($name) {
197
		$name = trim($name);
198
199
		$result = $this->getConfigTable()->remove($name);
200
201
		unset($this->config->$name);
202
	
203
		return $result;
204
	}
205
206
	/**
207
	 * {@inheritdoc}
208
	 */
209 204
	public function loadSettingsFile() {
0 ignored issues
show
Coding Style introduced by
loadSettingsFile uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
210 204
		if ($this->settings_loaded) {
211 204
			return;
212
		}
213
214 187
		if (isset($this->config->Config_file)) {
215 187
			if ($this->config->Config_file === false) {
216 187
				$this->settings_loaded = true;
217 187
				return;
218
			}
219
			$path = $this->config->Config_file;
220
		} else {
221
			$path = Directory\Local::root()->getPath('engine/settings.php');
222
			if (!is_file($path)) {
223
				$path = Directory\Local::root()->getPath('elgg-config/settings.php');
224
			}
225
		}
226
227
		// No settings means a fresh install
228
		if (!is_file($path)) {
229
			if ($this->getVolatile('installer_running')) {
230
				$this->settings_loaded = true;
231
				return;
232
			}
233
234
			header("Location: install.php");
235
			exit;
236
		}
237
238
		if (!is_readable($path)) {
239
			echo "The Elgg settings file exists but the web server doesn't have read permission to it.";
240
			exit;
241
		}
242
243
		// we assume settings is going to write to CONFIG, but we may need to copy its values
244
		// into our local config
245
		global $CONFIG;
246
		$global_is_bound = (isset($CONFIG) && $CONFIG === $this->config);
247
248
		require_once $path;
249
250
		if (empty($CONFIG->dataroot)) {
251
			echo 'The Elgg settings file is missing $CONFIG->dataroot.';
252
			exit;
253
		}
254
255
		// normalize commonly needed values
256
		$CONFIG->dataroot = rtrim($CONFIG->dataroot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
257
258
		$GLOBALS['_ELGG']->simplecache_enabled_in_settings = isset($CONFIG->simplecache_enabled);
259
260
		if (empty($CONFIG->cacheroot)) {
261
			$CONFIG->cacheroot = $CONFIG->dataroot;
262
		} else {
263
			$CONFIG->cacheroot = rtrim($CONFIG->cacheroot, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
264
		}
265
266
		if (!$global_is_bound) {
267
			// must manually copy settings into our storage
268
			foreach ($CONFIG as $key => $value) {
269
				$this->config->{$key} = $value;
270
			}
271
		}
272
273
		$this->settings_loaded = true;
274
	}
275
276
	/**
277
	 * Get the raw \stdClass object used for storage.
278
	 *
279
	 * We need this, for now, to construct some services.
280
	 *
281
	 * @internal Do not use this plugins or new core code!
282
	 * @todo Get rid of this.
283
	 *
284
	 * @return \stdClass
285
	 * @access private
286
	 */
287 191
	public function getStorageObject() {
288 191
		return $this->config;
289
	}
290
291
	/**
292
	 * Set the config table service (must be set)
293
	 *
294
	 * This is a necessary evil until we refactor so that the service provider has no dependencies.
295
	 *
296
	 * @param ConfigTable $table
297
	 * @return void
298
	 *
299
	 * @access private
300
	 * @internal
301
	 */
302 187
	public function setConfigTable(ConfigTable $table) {
303 187
		$this->config_table = $table;
304 187
	}
305
306
	/**
307
	 * Get the config table API
308
	 *
309
	 * @return ConfigTable
310
	 */
311
	private function getConfigTable() {
312
		if (!$this->config_table) {
313
			if (!function_exists('_elgg_services')) {
314
				throw new \RuntimeException('setConfigTable() must be called before using API that' .
315
					' uses the database.');
316
			}
317
318
			$this->config_table = _elgg_services()->configTable;
319
		}
320
321
		return $this->config_table;
322
	}
323
}
324