260 lines
5 KiB
PHP
260 lines
5 KiB
PHP
<?php
|
|
|
|
namespace alveolata\session;
|
|
|
|
// require_once(DIR_ALVEOLATA . '/definitions.php');
|
|
require_once(DIR_ALVEOLATA . '/session/interface.php');
|
|
require_once(DIR_ALVEOLATA . '/json/functions.php');
|
|
require_once(DIR_ALVEOLATA . '/file/functions.php');
|
|
|
|
|
|
/**
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
class _state_file
|
|
{
|
|
|
|
/**
|
|
* @var string
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
public static $directory = '/tmp/sessions';
|
|
|
|
|
|
/**
|
|
* @var int
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
public static $time_to_live_in_seconds = 3600;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
class struct_subject_file {
|
|
|
|
/**
|
|
* @var string
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
public $id;
|
|
|
|
|
|
/**
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
public function __construct(
|
|
string $id
|
|
)
|
|
{
|
|
$this->id = $id;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function file_set_directory(
|
|
string $directory
|
|
) : void
|
|
{
|
|
_state_file::$directory = $directory;
|
|
}
|
|
|
|
|
|
/**
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function file_set_time_to_live_in_seconds(
|
|
int $time_to_live_in_seconds
|
|
) : void
|
|
{
|
|
_state_file::$time_to_live_in_seconds = $time_to_live_in_seconds;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $id
|
|
* @return string
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function _file_get_path(
|
|
string $id
|
|
) : string
|
|
{
|
|
return \alveolata\string\coin(
|
|
'{{directory}}/{{id}}.json',
|
|
[
|
|
'directory' => _state_file::$directory,
|
|
'id' => $id,
|
|
]
|
|
);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param struct_subject_file $subject
|
|
* @return map<string,string>
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function _file_get_data(
|
|
struct_subject_file $subject
|
|
) : array
|
|
{
|
|
$path = _file_get_path($subject->id);
|
|
try {
|
|
$content = \alveolata\file\read($path);
|
|
$data = \alveolata\json\decode($content);
|
|
}
|
|
catch (\Exception $exception) {
|
|
$data = null;
|
|
}
|
|
if ($data === null) {
|
|
throw (new \Exception('session does not exist'));
|
|
}
|
|
else {
|
|
$now = time();
|
|
if (($data['timestamp'] + _state_file::$time_to_live_in_seconds) < $now) {
|
|
throw (new \Exception('session timed out'));
|
|
}
|
|
else {
|
|
return $data['data'];
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @return struct_subject_file
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function file_begin(
|
|
) : struct_subject_file
|
|
{
|
|
$id = hash('sha256', strval(time()));
|
|
$subject = (new struct_subject_file($id));
|
|
$path = _file_get_path($id);
|
|
$data = [
|
|
'timestamp' => time(),
|
|
'data' => [],
|
|
];
|
|
$content = \alveolata\json\encode($data);
|
|
\alveolata\file\write($path, $content, true);
|
|
return $subject;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $id
|
|
* @return struct_subject_file
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function file_get(
|
|
string $id
|
|
) : struct_subject_file
|
|
{
|
|
$subject = (new struct_subject_file($id));
|
|
return $subject;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param string $id
|
|
* @return struct_subject_file
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function file_id(
|
|
struct_subject_file $subject
|
|
) : string
|
|
{
|
|
return $subject->id;
|
|
}
|
|
|
|
|
|
/**
|
|
* @param struct_subject_file $subject
|
|
* @return string
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function file_read(
|
|
struct_subject_file $subject,
|
|
string $key
|
|
) : string
|
|
{
|
|
$data = _file_get_data($subject);
|
|
return $data[$key];
|
|
}
|
|
|
|
|
|
/**
|
|
* @param struct_subject_file $subject
|
|
* @param string $key
|
|
* @return string $value
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function file_write(
|
|
struct_subject_file $subject,
|
|
string $key,
|
|
string $value
|
|
) : void
|
|
{
|
|
$data = _file_get_data($subject);
|
|
$data['timestamp'] = time();
|
|
$data['data'][$key] = $value;
|
|
$content = \alveolata\json\encode($data);
|
|
$path = _file_get_path($subject->id);
|
|
\alveolata\file\write($path, $content, true);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param struct_subject_file $subject
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
function file_end(
|
|
struct_subject_file $subject
|
|
) : void
|
|
{
|
|
$path = _file_get_path($subject->id);
|
|
\alveolata\file\remove($path);
|
|
}
|
|
|
|
|
|
/**
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
class implementation_file implements interface_session {
|
|
|
|
/**
|
|
* @var struct_subject_file
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
private $subject;
|
|
|
|
|
|
/**
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
private function __construct(struct_subject_file $subject) {$this->subject = $subject;}
|
|
|
|
|
|
/**
|
|
* implementations
|
|
*
|
|
* @author Christian Fraß <frass@greenscale.de>
|
|
*/
|
|
public static function begin() : interface_session {return (new implementation_file(file_begin()));}
|
|
public static function get(string $id) : interface_session {return (new implementation_file(file_get($id)));}
|
|
public function id() : string {return file_id($this->subject);}
|
|
public function read(string $key) : string {return file_read($this->subject, $key);}
|
|
public function write(string $key, string $value) : void {file_write($this->subject, $key, $value);}
|
|
public function remove(string $key) : void {file_remove($this->subject, $key);}
|
|
public function end() : void {file_end($this->subject);}
|
|
|
|
}
|
|
|
|
?>
|