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() {

DB Install

-
Create database structure (v1.22.3) + Create database structure (v1.22.4)
(applies only to new installations, do not execute when updating)
@@ -1310,6 +1317,10 @@ function ttGenerateKeys() { Update database structure (v1.19 to v1.22.3) + + Update database structure (v1.22.3 to v1.22.4) + +

DB Maintenance

diff --git a/initialize.php b/initialize.php index 18946798..f19456a1 100644 --- a/initialize.php +++ b/initialize.php @@ -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)); @@ -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(); @@ -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); diff --git a/mysql.sql b/mysql.sql index f614d0ac..6b9e4da6 100644 --- a/mysql.sql +++ b/mysql.sql @@ -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`) +)