public function start()
{
if (self::$started) {
return;
}
$this->configure($this->options);
$id = $this->request->getCookie(session_name());
if (is_string($id) && preg_match('#^[0-9a-zA-Z,-]{22,256}\\z#i', $id)) {
session_id($id);
} else {
unset($_COOKIE[session_name()]);
}
try {
// session_start returns FALSE on failure only sometimes
Nette\Utils\Callback::invokeSafe('session_start', [], function ($message) use(&$e) {
$e = new Nette\InvalidStateException($message);
});
} catch (\Exception $e) {
}
if ($e) {
@session_write_close();
// this is needed
throw $e;
}
self::$started = TRUE;
/* structure:
__NF: Data, Meta, Time
DATA: section->variable = data
META: section->variable = Timestamp
*/
$nf =& $_SESSION['__NF'];
if (!is_array($nf)) {
$nf = [];
}
// regenerate empty session
if (empty($nf['Time'])) {
$nf['Time'] = time();
$this->regenerated = TRUE;
}
// resend cookie
$this->sendCookie();
// process meta metadata
if (isset($nf['META'])) {
$now = time();
// expire section variables
foreach ($nf['META'] as $section => $metadata) {
if (is_array($metadata)) {
foreach ($metadata as $variable => $value) {
if (!empty($value['T']) && $now > $value['T']) {
if ($variable === '') {
// expire whole section
unset($nf['META'][$section], $nf['DATA'][$section]);
continue 2;
}
unset($nf['META'][$section][$variable], $nf['DATA'][$section][$variable]);
}
}
}
}
}
if ($this->regenerated) {
$this->regenerated = FALSE;
$this->regenerateId();
}
register_shutdown_function([$this, 'clean']);
}