Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature store sessions in database #143

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions WEB-INF/config.php.dist
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ define('WEEKEND_START_DAY', 6);
// define('PHP_SESSION_PATH', '/tmp/timetracker'); // Directory must exist and be writable.


// SESSION_HANDLER
// Set session storage.
// 'file' : file stroage. Default value
// 'db' : db stroage
define('SESSION_HANDLER', 'file');


// LOGIN_COOKIE_NAME
//
// Cookie name for user login to remember it between browser sessions.
Expand Down
80 changes: 80 additions & 0 deletions WEB-INF/lib/ttSession.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

// ttSession classe is used to store sessions in databse
class ttSession {
private $id = null; // session id
private $expire = 0; // session expires
private $data = null; // session datas
private $db = null; // db connection

// Constructor.
public function __construct() {
// Set handler to overide SESSION
session_set_save_handler(
array($this, "_open"),
array($this, "_close"),
array($this, "_read"),
array($this, "_write"),
array($this, "_destroy"),
array($this, "_gc")
);
}

public function _open() {
$this->db = getConnection();
$this->_gc(PHPSESSID_TTL);
return true;
}

public function _close() {
$this->db = null;
return true;
}

public function _read($id) {
$id = preg_replace('/[^a-zA-Z0-9,\-]/', '', $id);
$sql = "SELECT data FROM tt_sessions WHERE id = '".$id."'";
$res = $this->db->query($sql);
if (is_a($res, 'PEAR_Error')) {
return ""; // Return an empty string
}
$row = $res->fetchRow();
if (empty($row['data'])) {
return ""; // Return an empty string
}
else {
return $row['data'];
}
}

public function _write($id, $data) {
$id = preg_replace('/[^a-zA-Z0-9,\-]/', '', $id);
$expire = time(); // Create time stamp
$sql = "REPLACE INTO tt_sessions (id, expire, data) VALUES ('".$id."', $expire, '".$data."')";
$affected = $this->db->exec($sql);
if (is_a($affected, 'PEAR_Error')) {
return false;
}
return true;
}

public function _destroy($id) {
$id = preg_replace('/[^a-zA-Z0-9,\-]/', '', $id);
$sql = "DELETE FROM tt_sessions WHERE id = '".$id."'";
$affected = $this->db->exec($sql);
if (is_a($affected, 'PEAR_Error')) {
return false;
}
return true;
}

public function _gc($lifetime) {
$old = time() - intval($lifetime);
$sql = "DELETE FROM tt_sessions WHERE expire < $old";
$affected = $this->db->exec($sql);
if (is_a($affected, 'PEAR_Error')) {
return false;
}
return true;
}
}
63 changes: 37 additions & 26 deletions dbinstall.php
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,12 @@ function ttGenerateKeys() {
ttExecute("UPDATE `tt_site_config` SET param_value = '1.22.3', modified = now() where param_name = 'version_db' and param_value = '1.21.7'");
}

if (array_key_exists('convert12203to12204', $_POST)) {
// Feature store sessions in database
ttExecute("CREATE TABLE `tt_sessions` (`id` varchar(32) NOT NULL, `expire` int(10) unsigned, `data` text NOT NULL, PRIMARY KEY (`id`))");
ttExecute("UPDATE `tt_site_config` SET param_value = '1.22.4', modified = now() where param_name = 'version_db' and param_value = '1.22.3'");
}

if (array_key_exists('cleanup', $_POST)) {
$mdb2 = getConnection();
$inactive_orgs = ttOrgHelper::getInactiveOrgs();
Expand All @@ -1220,32 +1226,33 @@ function ttGenerateKeys() {
// ttExecute("delete from tt_custom_field_log where status is null");
// ttExecute("delete from tt_expense_items where status is null");

ttExecute("OPTIMIZE TABLE tt_client_project_binds");
ttExecute("OPTIMIZE TABLE tt_clients");
ttExecute("OPTIMIZE TABLE tt_config");
ttExecute("OPTIMIZE TABLE tt_cron");
ttExecute("OPTIMIZE TABLE tt_timesheets");
ttExecute("OPTIMIZE TABLE tt_custom_field_log");
ttExecute("OPTIMIZE TABLE tt_custom_field_options");
ttExecute("OPTIMIZE TABLE tt_custom_fields");
ttExecute("OPTIMIZE TABLE tt_expense_items");
ttExecute("OPTIMIZE TABLE tt_fav_reports");
ttExecute("OPTIMIZE TABLE tt_invoices");
ttExecute("OPTIMIZE TABLE tt_log"); // This locks the production table for 4 minutes. Impossible to login, etc.
ttExecute("OPTIMIZE TABLE `tt_client_project_binds`");
ttExecute("OPTIMIZE TABLE `tt_clients`");
ttExecute("OPTIMIZE TABLE `tt_config`");
ttExecute("OPTIMIZE TABLE `tt_cron`");
ttExecute("OPTIMIZE TABLE `tt_timesheets`");
ttExecute("OPTIMIZE TABLE `tt_custom_field_log`");
ttExecute("OPTIMIZE TABLE `tt_custom_field_options`");
ttExecute("OPTIMIZE TABLE `tt_custom_fields`");
ttExecute("OPTIMIZE TABLE `tt_expense_items`");
ttExecute("OPTIMIZE TABLE `tt_fav_reports`");
ttExecute("OPTIMIZE TABLE `tt_invoices`");
ttExecute("OPTIMIZE TABLE `tt_log`"); // This locks the production table for 4 minutes. Impossible to login, etc.
// TODO: what should we do about it?
ttExecute("OPTIMIZE TABLE tt_monthly_quotas");
ttExecute("OPTIMIZE TABLE tt_templates");
ttExecute("OPTIMIZE TABLE tt_project_template_binds");
ttExecute("OPTIMIZE TABLE tt_predefined_expenses");
ttExecute("OPTIMIZE TABLE tt_project_task_binds");
ttExecute("OPTIMIZE TABLE tt_projects");
ttExecute("OPTIMIZE TABLE tt_tasks");
ttExecute("OPTIMIZE TABLE tt_groups");
ttExecute("OPTIMIZE TABLE tt_tmp_refs");
ttExecute("OPTIMIZE TABLE tt_user_project_binds");
ttExecute("OPTIMIZE TABLE tt_users");
ttExecute("OPTIMIZE TABLE tt_roles");
ttExecute("OPTIMIZE TABLE tt_files");
ttExecute("OPTIMIZE TABLE `tt_monthly_quotas`");
ttExecute("OPTIMIZE TABLE `tt_templates`");
ttExecute("OPTIMIZE TABLE `tt_project_template_binds`");
ttExecute("OPTIMIZE TABLE `tt_predefined_expenses`");
ttExecute("OPTIMIZE TABLE `tt_project_task_binds`");
ttExecute("OPTIMIZE TABLE `tt_projects`");
ttExecute("OPTIMIZE TABLE `tt_tasks`");
ttExecute("OPTIMIZE TABLE `tt_groups`");
ttExecute("OPTIMIZE TABLE `tt_tmp_refs`");
ttExecute("OPTIMIZE TABLE `tt_user_project_binds`");
ttExecute("OPTIMIZE TABLE `tt_users`");
ttExecute("OPTIMIZE TABLE `tt_roles`");
ttExecute("OPTIMIZE TABLE `tt_files`");
ttExecute("OPTIMIZE TABLE `tt_sessions`");
}

print "Done.<br>\n";
Expand All @@ -1258,7 +1265,7 @@ function ttGenerateKeys() {
<h2>DB Install</h2>
<table width="80%" border="1" cellpadding="10" cellspacing="0">
<tr>
<td width="80%"><b>Create database structure (v1.22.3)</b>
<td width="80%"><b>Create database structure (v1.22.4)</b>
<br>(applies only to new installations, do not execute when updating)</br></td><td><input type="submit" name="crstructure" value="Create"></td>
</tr>
</table>
Expand Down Expand Up @@ -1310,6 +1317,10 @@ function ttGenerateKeys() {
<td>Update database structure (v1.19 to v1.22.3)</td>
<td><input type="submit" name="convert11900to12203" value="Update"></td>
</tr>
<tr valign="top">
<td>Update database structure (v1.22.3 to v1.22.4)</td>
<td><input type="submit" name="convert12203to12204" value="Update"></td>
</tr>
</table>

<h2>DB Maintenance</h2>
Expand Down
27 changes: 20 additions & 7 deletions initialize.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@
// Change http cache expiration time to 1 minute.
session_cache_expire(1);

$phpsessid_ttl = defined('PHPSESSID_TTL') ? PHPSESSID_TTL : 60*60*24;
// Set lifetime for garbage collection.
ini_set('session.gc_maxlifetime', $phpsessid_ttl);
if (!defined('PHPSESSID_TTL')) define('PHPSESSID_TTL', 60*60*24);
ini_set('session.gc_maxlifetime', PHPSESSID_TTL);

// Set PHP session path, if defined to avoid garbage collection interference from other scripts.
if (defined('PHP_SESSION_PATH') && realpath(PHP_SESSION_PATH)) {
ini_set('session.save_path', realpath(PHP_SESSION_PATH));
Expand All @@ -80,14 +81,21 @@
if (!defined('LOGIN_COOKIE_NAME')) define('LOGIN_COOKIE_NAME', 'tt_login');

// Set session cookie lifetime.
session_set_cookie_params($phpsessid_ttl);
session_set_cookie_params(PHPSESSID_TTL);
if (isset($_COOKIE[SESSION_COOKIE_NAME])) {
// Extend PHP session cookie lifetime by PHPSESSID_TTL (if defined, otherwise 24 hours)
// so that users don't have to re-login during this period from now.
setcookie(SESSION_COOKIE_NAME, $_COOKIE[SESSION_COOKIE_NAME], time() + $phpsessid_ttl, '/');
setcookie(SESSION_COOKIE_NAME, $_COOKIE[SESSION_COOKIE_NAME], time() + PHPSESSID_TTL, '/');
}

// Set session storage
if (!defined('SESSION_HANDLER')) define('SESSION_HANDLER', 'file');
if (SESSION_HANDLER === 'db') {
import('ttSession');
$ttSession = new ttSession();
}

// Start or resume PHP session.
// Start session
session_name(SESSION_COOKIE_NAME);
@session_start();

Expand Down Expand Up @@ -136,8 +144,13 @@
import('ttUser');
$user = new ttUser(null, $auth->getUserId());
if ($user->custom_logo) {
$smarty->assign('custom_logo', 'img/'.$user->group_id.'.png');
$smarty->assign('mobile_custom_logo', '../img/'.$user->group_id.'.png');
if (file_exists('img/'.$user->group_id.'.png')) {
$smarty->assign('custom_logo', 'img/'.$user->group_id.'.png');
$smarty->assign('mobile_custom_logo', '../img/'.$user->group_id.'.png');
}
else {
$user->custom_logo = 0;
}
}
$smarty->assign('user', $user);

Expand Down
14 changes: 13 additions & 1 deletion mysql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -623,4 +623,16 @@ CREATE TABLE `tt_site_config` (
PRIMARY KEY (`param_name`)
);

INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.22.3', now()); # TODO: change when structure changes.
INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.22.4', now()); # TODO: change when structure changes.


#
# Structure for table tt_sessions.
# This table stores sessions data
#
CREATE TABLE `tt_sessions` (
`id` varchar(32) NOT NULL, # session id
`expire` int(10) unsigned, # session expire
`data` text NOT NULL, # session
PRIMARY KEY (`id`)
)