FRED™  3.0
FRED™: Framework for Rapid and Easy Development
Alive.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Rsi\Fred;
4 
5 class Alive extends Component{
6 
7  public $maxSessionTime = null; //!< Maximum duration of a session (minutes; empty = infinite).
8  public $maxInactiveTime = null; //!< Maximum period of inactivity (minutes; empty = infinite).
9 
10  public $journalPath = null; //!< Path for journal files (empty = do not save).
11  public $journalExt = '.log';
12  public $journalFormat = 'H:i:s';
13  public $journalMaxSize = 10240; //!< Max filesize in bytes.
14  public $journalTimout = 3600; //!< Max idle time in seconds.
15  public $journalGarbageChance = 100;
16 
17  protected $_lastAlive = null;
18  protected $_journalFilename = null;
19 
20  public function clientConfig(){
21  return array_merge(parent::clientConfig(),['interval' => $this->interval]);
22  }
23 
24  protected function init(){
25  parent::init();
26  if(!$this->session->start){
27  $this->session->start = time();
28  $this->journal('Session start from remote address ' . $this->component('security')->remoteAddr);
29  }
30  $this->_lastAlive = $this->session->alive;
31  $this->session->alive = time();
32  }
33  /**
34  * Register a component to be pinged.
35  * @param string $name Name of the component.
36  */
37  public function register($name){
38  if(!in_array($name,$ping = $this->session->ping ?: [])) $ping[] = $name;
39  $this->session->ping = $ping;
40  }
41  /**
42  * Ping the session to see its status.
43  * @return string URL to navigate to (empty = no action required).
44  */
45  public function ping(){
46  $this->session->alive = $this->_lastAlive; //restore - ignore this call
47  if(
48  (!$this->maxSessionTime || (time() - $this->session->start <= $this->maxSessionTime * 60)) &&
49  (!$this->maxInactiveTime || (time() - $this->session->alive <= $this->maxInactiveTime * 60))
50  ){
51  if($ping = $this->session->ping) foreach($ping as $name) $this->_fred->component($name)->ping();
52  $this->journalGarbage();
53  return null;
54  }
55  $this->component('user')->invalidate();
56  $this->session->start = false;
57  return $this->router->reverse($this->front->defaultControllerName);
58  }
59  /**
60  * Add a message to the journal.
61  * @param string $message Message to add.
62  */
63  public function journal($message){
64  if($filename = $this->journalFilename) try{
65  return \Rsi\File::write($filename,date($this->journalFormat) . ": $message\n",0666,true);
66  }
67  catch(\Exception $e){
68  $this->component('log')->error($e);
69  }
70  }
71  /**
72  * Clean-up the journals.
73  * @param bool $force Set to true to force a clean-up (otherwise the journalGarbageChance is used).
74  * @return int Number of active journals (null if not cleaned).
75  */
76  public function journalGarbage($force = false){
77  $count = null;
78  if($this->journalPath && ($force || !rand(0,$this->journalGarbageChance))) try{
79  $log = $this->component('log');
80  $time = time() - $this->journalTimout;
81  foreach((new \GlobIterator($this->journalPath . '*' . $this->journalExt)) as $filename => $file) try{
82  if(($file->getMTime() < $time) || ($file->getSize() > $this->journalMaxSize)) unlink($filename);
83  else $count++;
84  }
85  catch(\Exception $e){
86  $log->info($e);
87  error_clear_last();
88  }
89  }
90  catch(\Exception $e){
91  $log->error($e);
92  }
93  return $count;
94  }
95  /**
96  * List all active journals.
97  * @param string $filter Only journals with this string in one of the messages.
98  * @param string $order Order the journals by one of the properties.
99  * @return array Array with 'name','time', and 'size'.
100  */
101  public function journals($filter = null,$order = null){
102  $journals = [];
103  if($this->journalPath){
104  $this->journalGarbage(true);
105  foreach((new \GlobIterator($this->journalPath . '*' . $this->journalExt)) as $filename => $file)
106  if(!$filter || (stripos(\Rsi\File::read($filename),$filter) !== false))
107  $journals[] = ['name' => $file->getFilename(),'time' => $file->getMTime(),'size' => $file->getSize()];
108  if($order && $journals && array_key_exists($order,$journals[0]))
109  usort($journals,function($a,$b) use ($order){ return strnatcmp($a[$order],$b[$order]); });
110  }
111  return $journals;
112  }
113  /**
114  * All messages from a journal.
115  * @param string $name Journal name.
116  * @return array Message lines.
117  */
118  public function journalMessages($name){
119  return $this->journalPath && !preg_match('/(\\/|\\\\|\\.\\.)/',$name) && \Rsi\Str::endsWith($name,$this->journalExt)
120  ? explode("\n",trim(\Rsi\File::read($this->journalPath . $name)))
121  : false;
122  }
123 
124  protected function getInterval(){
125  $interval = ini_get('session.gc_maxlifetime') / 90; //seconds -> minutes, and 2/3 of that
126  if($this->maxSessionTime) $interval = min($interval,$this->maxSessionTime / 10);
127  if($this->maxInactiveTime) $interval = min($interval,$this->maxInactiveTime / 10);
128  return max(1,$interval);
129  }
130 
131  protected function getJournalFilename(){
132  if(!$this->journalPath) return false;
133  if(!$this->_journalFilename) $this->_journalFilename = $this->journalPath . session_id() . $this->journalExt;
135  }
136 
137 }
ping()
Ping the session to see its status.
Definition: Alive.php:45
$maxInactiveTime
Maximum period of inactivity (minutes; empty = infinite).
Definition: Alive.php:8
journal($message)
Add a message to the journal.
Definition: Alive.php:63
$journalTimout
Max idle time in seconds.
Definition: Alive.php:14
journals($filter=null, $order=null)
List all active journals.
Definition: Alive.php:101
getJournalFilename()
Definition: Alive.php:131
$journalPath
Path for journal files (empty = do not save).
Definition: Alive.php:10
Basic component class.
Definition: Component.php:8
journalGarbage($force=false)
Clean-up the journals.
Definition: Alive.php:76
$maxSessionTime
Maximum duration of a session (minutes; empty = infinite).
Definition: Alive.php:7
clientConfig()
Definition: Alive.php:20
$journalMaxSize
Max filesize in bytes.
Definition: Alive.php:13
$journalGarbageChance
Definition: Alive.php:15
journalMessages($name)
All messages from a journal.
Definition: Alive.php:118
component($name)
Get a component (local or default).
Definition: Component.php:80