artabro/wire/modules/Session/SessionHandlerDB/ProcessSessionDB.module
2024-08-27 11:35:37 +02:00

178 lines
4.9 KiB
Text

<?php namespace ProcessWire;
/**
* ProcessWire Session Viewer
*
* This module accompanies installation of the SessionHandlerDB module
*
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* https://processwire.com
*
*/
class ProcessSessionDB extends Process {
public static function getModuleInfo() {
return array(
'title' => __('Sessions', __FILE__), // getModuleInfo title
'summary' => __('Enables you to browse active database sessions.', __FILE__), // getModuleInfo summary
'version' => 5,
'permanent' => false,
'icon' => 'dashboard',
'requires' => array('SessionHandlerDB'),
'page' => array(
'name' => self::pageName,
'parent' => 'access',
'title' => 'Sessions',
));
}
const pageName = 'sessions-db';
/**
* Execute display of sessions
*
* @return string
*
*/
public function ___execute() {
// clean out any stray sessions that may have not yet hit the gc probability
// because we don't want them in the list that we display
$modules = $this->wire()->modules;
$config = $this->wire()->config;
$session = $this->wire()->session;
$database = $this->wire()->database;
$input = $this->wire()->input;
$pages = $this->wire()->pages;
$users = $this->wire()->users;
/** @var SessionHandlerDB $sessionHandlerDB */
$sessionHandlerDB = $this->modules->get('SessionHandlerDB');
$sessionHandlerDB->gc($config->sessionExpireSeconds);
$useIP = $sessionHandlerDB->useIP;
$useUA = $sessionHandlerDB->useUA;
$mins = (int) $input->post('mins');
if(!$mins) $mins = (int) $session->get('ProcessSessionDB_mins');
if(!$mins) $mins = 5;
$session->set('ProcessSessionDB_mins', $mins);
/** @var InputfieldForm $form */
$form = $modules->get('InputfieldForm');
/** @var InputfieldInteger $field */
$field = $modules->get('InputfieldInteger');
$field->attr('name', 'mins');
$field->attr('value', $mins);
$field->label = sprintf($this->_n('Sessions active in last minute', 'Sessions active in last %d minutes', $mins), $mins);
$field->description = $this->_('Number of minutes');
$field->collapsed = Inputfield::collapsedYes;
$form->add($field);
$pagePaths = array();
$userNames = array();
$table = SessionHandlerDB::dbTableName;
$limit = 500;
$seconds = $mins * 60;
$sql = "SELECT user_id, pages_id, ip, ua, UNIX_TIMESTAMP(ts) " .
"FROM `$table` " .
"WHERE ts > DATE_SUB(NOW(), INTERVAL $seconds SECOND) " .
"ORDER BY ts DESC LIMIT $limit";
$query = $database->prepare($sql);
$query->execute();
$numRows = $query->rowCount();
if($numRows) {
if($numRows == $limit) {
// if more than 500, get an accurate count
$numRows = $sessionHandlerDB->getNumSessions($mins * 60);
}
/** @var MarkupAdminDataTable $table */
$table = $modules->get('MarkupAdminDataTable');
$table->setSortable(false);
$header = array(
$this->_('Time'),
$this->_('User'),
$this->_('Page'),
);
if($useIP) $header[] = $this->_('IP Addr');
if($useUA) $header[] = $this->_('User Agent');
$table->headerRow($header);
// for first iteration
$row = $query->fetch(\PDO::FETCH_NUM);
while($row) {
list($user_id, $pages_id, $ip, $ua, $ts) = $row;
$pages_id = (int) $pages_id;
$user_id = (int) $user_id;
if(isset($userNames[$user_id])) {
$userName = $userNames[$user_id];
} else {
$user = $users->get($user_id);
$userName = $user && $user->id ? $user->name : '.';
if($userName !== '.') $userNames[$user_id] = $userName;
}
if(isset($pagePaths[$pages_id])) {
$pagePath = $pagePaths[$pages_id];
} else {
$page = $pages->get($pages_id);
$pagePath = $page->id ? $page->path : '.';
if($pagePath !== '.') $pagePaths[$pages_id] = $pagePath;
}
$tr = array(wireRelativeTimeStr($ts), $userName, $pagePath);
if($useIP) $tr[] = long2ip($ip);
if($useUA) $tr[] = strip_tags($ua); // note MarkupAdminDataTable already entity encodes all output
$table->row($tr);
// for next iteration
$row = $query->fetch(\PDO::FETCH_NUM);
}
$tableOut = $table->render();
} else {
$tableOut = "<p class='description'>" . $this->_('No active sessions') . "</p>";
}
$query->closeCursor();
$out =
"<h2>" .
"<i id='SessionListIcon' class='fa fa-2x fa-fw fa-dashboard ui-priority-secondary'></i> " .
sprintf($this->_n('%d active session', '%d active sessions', $numRows), $numRows) .
"</h2>" .
$tableOut;
if($config->ajax) return $out;
/** @var InputfieldMarkup $markup */
$markup = $modules->get('InputfieldMarkup');
$markup->value = "<div id='SessionList'>$out</div>";
$form->add($markup);
/** @var InputfieldSubmit $submit */
$submit = $modules->get('InputfieldSubmit');
$submit->attr('value', $this->_('Refresh'));
$submit->icon = 'refresh';
$submit->attr('id+name', 'submit_session');
$submit->showInHeader();
$form->add($submit);
return $form->render();
}
}