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() { |
||
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
|
|||
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 |
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.