Elgg  Version 2.2
 All Classes Namespaces Files Functions Variables Pages
BootService.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
6 use Stash\Driver\BlackHole;
7 use Stash\Driver\FileSystem;
8 use Stash\Driver\Memcache;
9 use Stash\Invalidation;
10 use Stash\Pool;
11 
18 class BootService {
19  use Profilable;
20 
27  const DEFAULT_BOOT_CACHE_TTL = 0;
28 
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  // we need this stuff before cache
61  $rows = $db->getData("
62  SELECT *
63  FROM {$db->getTablePrefix()}datalists
64  WHERE `name` IN ('__site_secret__', 'default_site', 'dataroot')
65  ");
66  $datalists = [];
67  foreach ($rows as $row) {
68  $datalists[$row->name] = $row->value;
69  }
70 
71  // booting during installation
72  if (empty($datalists['dataroot'])) {
73  $datalists['dataroot'] = '';
74 
75  // don't use cache
76  $CONFIG->boot_cache_ttl = 0;
77  }
78 
79  if (!$GLOBALS['_ELGG']->dataroot_in_settings) {
80  $CONFIG->dataroot = rtrim($datalists['dataroot'], '/\\') . DIRECTORY_SEPARATOR;
81  }
82  $CONFIG->site_guid = (int)$datalists['default_site'];
83  $CONFIG->site_id = (int)$datalists['default_site'];
84  if (!isset($CONFIG->boot_cache_ttl)) {
85  $CONFIG->boot_cache_ttl = self::DEFAULT_BOOT_CACHE_TTL;
86  }
87 
88  if ($this->timer) {
89  $this->timer->begin([__CLASS__ . '::getBootData']);
90  }
91 
92  // early config is done, now get the core boot data
93  $data = $this->getBootData($CONFIG, $db);
94 
95  if ($this->timer) {
96  $this->timer->begin([__CLASS__ . '::getBootData']);
97  }
98 
99  // copy earlier fetches values into the datalist cache and inject into the service
100  $datalist_cache = $data->getDatalistCache();
101  foreach (['__site_secret__', 'default_site', 'dataroot'] as $key) {
102  $datalist_cache->put($key, $datalists[$key]);
103  }
104  _elgg_services()->datalist->setCache($datalist_cache);
105 
106  $CONFIG->site = $data->getSite();
107  $CONFIG->wwwroot = $CONFIG->site->url;
108  $CONFIG->sitename = $CONFIG->site->name;
109  $CONFIG->sitedescription = $CONFIG->site->description;
110  $CONFIG->url = $CONFIG->wwwroot;
111 
112  _elgg_services()->subtypeTable->setCachedValues($data->getSubtypeData());
113 
114  foreach ($data->getConfigValues() as $key => $value) {
115  $CONFIG->$key = $value;
116  }
117 
118  _elgg_services()->plugins->setBootPlugins($data->getActivePlugins());
119 
120  _elgg_services()->pluginSettingsCache->setCachedValues($data->getPluginSettings());
121 
122  if (!$GLOBALS['_ELGG']->simplecache_enabled_in_settings) {
123  $simplecache_enabled = $datalist_cache->get('simplecache_enabled');
124  $CONFIG->simplecache_enabled = ($simplecache_enabled === false) ? 1 : $simplecache_enabled;
125  }
126 
127  $system_cache_enabled = $datalist_cache->get('system_cache_enabled');
128  $CONFIG->system_cache_enabled = ($system_cache_enabled === false) ? 1 : $system_cache_enabled;
129 
130  // needs to be set before [init, system] for links in html head
131  $CONFIG->lastcache = (int)$datalist_cache->get("simplecache_lastupdate");
132 
133  $GLOBALS['_ELGG']->i18n_loaded_from_cache = false;
134 
135  if (!empty($CONFIG->debug)) {
136  _elgg_services()->logger->setLevel($CONFIG->debug);
137  _elgg_services()->logger->setDisplay(true);
138  }
139 
140  $GLOBALS['_ELGG']->view_path = \Elgg\Application::elggDir()->getPath("/views/");
141 
142  // finish boot sequence
144  if ($CONFIG->system_cache_enabled) {
145  _elgg_services()->systemCache->loadAll();
146  }
147  _elgg_services()->translator->loadTranslations();
148 
149  // we always need site->email and user->icontime, so load them together
150  $preload_md_guids = [$CONFIG->site_guid];
151  $user_guid = _elgg_services()->session->getLoggedInUserGuid();
152  if ($user_guid) {
153  $preload_md_guids[] = $user_guid;
154  }
155  _elgg_services()->metadataCache->populateFromEntities($preload_md_guids);
156 
157  // TODO get rid of in 3.0, then we can drop the metadata preload for anon visitors
158  $CONFIG->siteemail = $CONFIG->site->email;
159 
160  // gives hint to get() how to approach missing values
161  $CONFIG->site_config_loaded = true;
162 
163  // invalidate on some actions just in case other invalidation triggers miss something
164  _elgg_services()->hooks->registerHandler('action', 'all', function ($action) {
165  if (0 === strpos($action, 'admin/' || $action === 'plugins/settings/save')) {
166  $this->invalidateCache();
167  }
168  }, 1);
169  }
170 
178  public function invalidateCache($site_guid = 0) {
179  $CONFIG = _elgg_services()->config->getStorageObject();
180  if (!$site_guid) {
181  $site_guid = $CONFIG->site_guid;
182  }
183 
184  // this gets called a lot on plugins page, avoid thrashing cache
185  static $cleared = [];
186  if (empty($cleared[$site_guid])) {
187  $this->getStashItem($CONFIG, $site_guid)->clear();
188  $cleared[$site_guid] = true;
189  }
190  }
191 
202  private function getBootData(\stdClass $CONFIG, Database $db) {
203  $CONFIG->_boot_cache_hit = false;
204 
205  if (!$CONFIG->boot_cache_ttl) {
206  $data = new BootData();
207  $data->populate($CONFIG, $db, _elgg_services()->entityTable, _elgg_services()->plugins);
208  return $data;
209  }
210 
211  $item = $this->getStashItem($CONFIG, $CONFIG->site_guid);
212  $item->setInvalidationMethod(Invalidation::NONE);
213  $data = $item->get();
214  if ($item->isMiss()) {
215  $data = new BootData();
216  $data->populate($CONFIG, $db, _elgg_services()->entityTable, _elgg_services()->plugins);
217  $item->set($data);
218  $item->expiresAfter($CONFIG->boot_cache_ttl);
219  $item->save();
220  } else {
221  $CONFIG->_boot_cache_hit = true;
222  }
223 
224  return $data;
225  }
226 
235  private function getStashItem(\stdClass $CONFIG, $site_guid) {
236  if (!empty($CONFIG->memcache)) {
237  $options = [];
238  if (!empty($CONFIG->memcache_servers)) {
239  $options['servers'] = $CONFIG->memcache_servers;
240  }
241  $driver = new Memcache($options);
242  } else {
243  if (!$CONFIG->dataroot) {
244  // we're in the installer
245  $driver = new BlackHole();
246  } else {
247  $driver = new FileSystem([
248  'path' => $CONFIG->dataroot,
249  ]);
250  }
251  }
252  return (new Pool($driver))->getItem("boot_data_{$site_guid}");
253  }
254 }
$action
Definition: full.php:125
invalidateCache($site_guid=0)
Invalidate the cache item.
boot()
Boots the engine.
Definition: BootService.php:34
$data
Definition: opendd.php:13
$value
Definition: longtext.php:26
trait Profilable
Make an object accept a timer.
Definition: Profilable.php:9
$options
Elgg admin footer.
Definition: footer.php:6
Namespace for generating local filesystems.
Definition: Local.php:13
$key
Definition: summary.php:34
$item
Definition: item.php:12
global $CONFIG
_elgg_services(\Elgg\Di\ServiceProvider $services=null)
Get the global service provider.
Definition: autoloader.php:17
Boots Elgg and manages a cache of data needed during boot.
Definition: BootService.php:18
Serializable collection of data used to boot Elgg.
Definition: BootData.php:16
static elggDir()
Returns a directory that points to the root of Elgg, but not necessarily the install root...
$row
$rows
_elgg_session_boot()
Initializes the session and checks for the remember me cookie.
Definition: sessions.php:408
$user_guid
Avatar remove action.
Definition: remove.php:6