rosavox/lib/alveolata/session/implementation-file.php
2025-05-23 07:33:29 +00:00

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);}
}
?>