diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist
index 6b6a68d8..b5f078d2 100644
--- a/WEB-INF/config.php.dist
+++ b/WEB-INF/config.php.dist
@@ -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.
diff --git a/WEB-INF/lib/ttSession.class.php b/WEB-INF/lib/ttSession.class.php
new file mode 100644
index 00000000..06e7078e
--- /dev/null
+++ b/WEB-INF/lib/ttSession.class.php
@@ -0,0 +1,80 @@
+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;
+ }
+}
\ No newline at end of file
diff --git a/dbinstall.php b/dbinstall.php
index 44fede0c..8eba7e9b 100644
--- a/dbinstall.php
+++ b/dbinstall.php
@@ -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();
@@ -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.
\n";
@@ -1258,7 +1265,7 @@ function ttGenerateKeys() {
Create database structure (v1.22.3) + | Create database structure (v1.22.4)
(applies only to new installations, do not execute when updating) |