*/ class _state_file { /** * @var string * @author Christian Fraß */ public static $directory = '/tmp/sessions'; /** * @var int * @author Christian Fraß */ public static $time_to_live_in_seconds = 3600; } /** * @author Christian Fraß */ class struct_subject_file { /** * @var string * @author Christian Fraß */ public $id; /** * @author Christian Fraß */ public function __construct( string $id ) { $this->id = $id; } } /** * @author Christian Fraß */ function file_set_directory( string $directory ) : void { _state_file::$directory = $directory; } /** * @author Christian Fraß */ 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ß */ 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 * @author Christian Fraß */ 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ß */ 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ß */ 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ß */ function file_id( struct_subject_file $subject ) : string { return $subject->id; } /** * @param struct_subject_file $subject * @return string * @author Christian Fraß */ 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ß */ 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ß */ function file_end( struct_subject_file $subject ) : void { $path = _file_get_path($subject->id); \alveolata\file\remove($path); } /** * @author Christian Fraß */ class implementation_file implements interface_session { /** * @var struct_subject_file * @author Christian Fraß */ private $subject; /** * @author Christian Fraß */ private function __construct(struct_subject_file $subject) {$this->subject = $subject;} /** * implementations * * @author Christian Fraß */ 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);} } ?>