Test Failed
Push — master ( 8c47c2...3acf9f )
by Steve
12:37
created

engine/classes/Elgg/BootService.php (2 issues)

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
3
namespace Elgg;
4
5
use Elgg\Filesystem\Directory\Local;
6
use Stash\Driver\BlackHole;
7
use Stash\Driver\FileSystem;
8
use Stash\Driver\Memcache;
9
use Stash\Invalidation;
10
use Stash\Pool;
11
12
/**
13
 * Boots Elgg and manages a cache of data needed during boot
14
 *
15
 * @access private
16
 * @since 2.1
17
 */
18
class BootService {
19
	use Profilable;
20
21
	/**
22
	 * Under load, a short TTL gives nearly all of the benefits of a longer TTL, but it also ensures
23
	 * that, should cache invalidation fail for some reason, it'll be rebuilt quickly anyway.
24
	 *
25
	 * In 2.x we do not cache by default. This will likely change to 10 in 3.0.
26
	 */
27
	const DEFAULT_BOOT_CACHE_TTL = 0;
28
29
	/**
30
	 * Boots the engine
31
	 *
32
	 * @return void
33
	 */
34
	public function boot() {
0 ignored issues
show
boot 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...
35
		// Register the error handlers
36
		set_error_handler('_elgg_php_error_handler');
37
		set_exception_handler('_elgg_php_exception_handler');
38
39
		$db = _elgg_services()->db;
40
41
		// we inject the logger here to allow use of DB without loading core
42
		$db->setLogger(_elgg_services()->logger);
43
44
		$db->setupConnections();
45
		$db->assertInstalled();
46
47
		$CONFIG = _elgg_services()->config->getStorageObject();
48
		$local_path = Local::root()->getPath();
49
50
		// setup stuff available without any DB info
51
		$CONFIG->path = $local_path;
52
		$CONFIG->plugins_path = "{$local_path}mod/";
53
		$CONFIG->pluginspath = "{$local_path}mod/";
54
		$CONFIG->entity_types = ['group', 'object', 'site', 'user'];
55
		$CONFIG->language = 'en';
56
57
		// set cookie values for session and remember me
58
		_elgg_services()->config->getCookieConfig();
59
60
		$CONFIG->site_guid = 1;
61
		if (!isset($CONFIG->boot_cache_ttl)) {
62
			$CONFIG->boot_cache_ttl = self::DEFAULT_BOOT_CACHE_TTL;
63
		}
64
65
		if ($this->timer) {
66
			$this->timer->begin([__CLASS__ . '::getBootData']);
67
		}
68
69
		// early config is done, now get the core boot data
70
		$data = $this->getBootData($CONFIG, $db);
71
72
		if ($this->timer) {
73
			$this->timer->begin([__CLASS__ . '::getBootData']);
74
		}
75
76
		$configs_cache = $data->getConfigValues();
77
78
		$CONFIG->site = $data->getSite();
79
		$CONFIG->sitename = $CONFIG->site->name;
80
		$CONFIG->sitedescription = $CONFIG->site->description;
81
		$CONFIG->url = $CONFIG->wwwroot;
82
83
		_elgg_services()->subtypeTable->setCachedValues($data->getSubtypeData());
84
85
		foreach ($data->getConfigValues() as $key => $value) {
86
			$CONFIG->$key = $value;
87
		}
88
89
		_elgg_services()->plugins->setBootPlugins($data->getActivePlugins());
90
91
		_elgg_services()->pluginSettingsCache->setCachedValues($data->getPluginSettings());
92
93
		if (!$GLOBALS['_ELGG']->simplecache_enabled_in_settings) {
94
			$simplecache_enabled = $configs_cache['simplecache_enabled'];
95
			$CONFIG->simplecache_enabled = ($simplecache_enabled === false) ? 1 : $simplecache_enabled;
96
		}
97
98
		$system_cache_enabled = $configs_cache['system_cache_enabled'];
99
		$CONFIG->system_cache_enabled = ($system_cache_enabled === false) ? 1 : $system_cache_enabled;
100
101
		// needs to be set before [init, system] for links in html head
102
		$CONFIG->lastcache = (int) $configs_cache['simplecache_lastupdate'];
103
104
		$GLOBALS['_ELGG']->i18n_loaded_from_cache = false;
105
106
		if (!empty($CONFIG->debug)) {
107
			_elgg_services()->logger->setLevel($CONFIG->debug);
108
			_elgg_services()->logger->setDisplay(true);
109
		}
110
111
		_elgg_services()->views->view_path = \Elgg\Application::elggDir()->getPath("/views/");
0 ignored issues
show
The property view_path does not seem to exist in Elgg\ViewsService.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
112
113
		// finish boot sequence
114
		_elgg_session_boot();
115
		if ($CONFIG->system_cache_enabled) {
116
			_elgg_services()->systemCache->loadAll();
117
		}
118
119
		// we don't store langs in boot data because it varies by user
120
		_elgg_services()->translator->loadTranslations();
121
122
		// we always need site->email and user->icontime, so load them together
123
		$user_guid = _elgg_services()->session->getLoggedInUserGuid();
124
		if ($user_guid) {
125
			_elgg_services()->metadataCache->populateFromEntities([$user_guid]);
126
		}
127
128
		// gives hint to get() how to approach missing values
129
		$CONFIG->site_config_loaded = true;
130
131
		// invalidate on some actions just in case other invalidation triggers miss something
132
		_elgg_services()->hooks->registerHandler('action', 'all', function ($action) {
133
			if (0 === strpos($action, 'admin/' || $action === 'plugins/settings/save')) {
134
				$this->invalidateCache();
135
			}
136
		}, 1);
137
	}
138
139
	/**
140
	 * Invalidate the cache item
141
	 *
142
	 * @return void
143
	 */
144 10
	public function invalidateCache() {
145 10
		$CONFIG = _elgg_services()->config->getStorageObject();
146
		
147
		// this gets called a lot on plugins page, avoid thrashing cache
148 10
		static $cleared = false;
149 10
		if (!$cleared) {
150 1
			$this->getStashItem($CONFIG)->clear();
151 1
			$cleared = true;
152
		}
153 10
	}
154
155
	/**
156
	 * Get the boot data
157
	 *
158
	 * @param \stdClass $CONFIG Elgg config object
159
	 * @param Database  $db     Elgg database
160
	 *
161
	 * @return BootData
162
	 *
163
	 * @throws \InstallationException
164
	 */
165
	private function getBootData(\stdClass $CONFIG, Database $db) {
166
		$CONFIG->_boot_cache_hit = false;
167
168
		if (!$CONFIG->boot_cache_ttl) {
169
			$data = new BootData();
170
			$data->populate($CONFIG, $db, _elgg_services()->entityTable, _elgg_services()->plugins);
171
			return $data;
172
		}
173
174
		$item = $this->getStashItem($CONFIG);
175
		$item->setInvalidationMethod(Invalidation::NONE);
176
		$data = $item->get();
177
		if ($item->isMiss()) {
178
			$data = new BootData();
179
			$data->populate($CONFIG, $db, _elgg_services()->entityTable, _elgg_services()->plugins);
180
			$item->set($data);
181
			$item->expiresAfter($CONFIG->boot_cache_ttl);
182
			$item->save();
183
		} else {
184
			$CONFIG->_boot_cache_hit = true;
185
		}
186
187
		return $data;
188
	}
189
190
	/**
191
	 * Get a Stash cache item
192
	 *
193
	 * @param \stdClass $CONFIG Elgg config object
194
	 *
195
	 * @return \Stash\Interfaces\ItemInterface
196
	 */
197 1
	private function getStashItem(\stdClass $CONFIG) {
198 1
		if (!empty($CONFIG->memcache) && class_exists('Memcache')) {
199
			$options = [];
200
			if (!empty($CONFIG->memcache_servers)) {
201
				$options['servers'] = $CONFIG->memcache_servers;
202
			}
203
			$driver = new Memcache($options);
204
		} else {
205 1
			if (!$CONFIG->dataroot) {
206
				// we're in the installer
207
				$driver = new BlackHole();
208
			} else {
209 1
				$driver = new FileSystem([
210 1
					'path' => $CONFIG->dataroot,
211
				]);
212
			}
213
		}
214 1
		return (new Pool($driver))->getItem("boot_data");
215
	}
216
}
217