Files
tms/core/kimai.php
TMS eb299c9131 Initial commit: Kimai TMS
Kimai time management system (PHP 5.6 / MySQL) with custom extensions:
- Budget tracking (ki_budget)
- Change request form (ki_changerequest)
- Invoice generation (ki_invoice)
- Expense tracking (ki_expenses)
- Flexi time (ki_flexitime)
- Export, admin panel, timesheets, tasks, summary

Database: ~900K time entries, 2,000+ users, 439 projects.
Config: includes/autoconf.php — localhost/kimai/kimai
2026-06-18 21:20:26 +00:00

503 lines
18 KiB
PHP

<?php
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
/**
* This file is part of
* Kimai - Open Source Time Tracking // http://www.kimai.org
* (c) 2006-2009 Kimai-Development-Team
*
* Kimai is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; Version 3, 29 June 2007
*
* Kimai is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kimai; If not, see <http://www.gnu.org/licenses/>.
*/
if ($_POST['changebillable_submit']) {
foreach ($_POST as $key => $value) {
$con = new PDO('mysql:host=localhost;dbname=kimai', "kimai", "kimai");
$con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($key == "changebillable_submit") {
} else {
$sql = "UPDATE kimai15_pct SET `pct_billable`=$value WHERE `pct_ID`=$key;";
$result = $con->query($sql);
}
}
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
header('Location: ' . $actual_link);
}
// =============================
// = Smarty (initialize class) =
// =============================
require_once('../libraries/smarty/Smarty.class.php');
$tpl = new Smarty();
$tpl->template_dir = '../templates/';
$tpl->compile_dir = '../compile/';
// prevent IE from caching the response
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header('Access-Control-Allow-Origin: *');
// ==================================
// = implementing standard includes =
// ==================================
include('../includes/basics.php');
$usr = checkUser();
if ($_POST['selected_division']) {
$selected_division = $_POST['selected_division'];
$usrname = $usr['usr_name'];
$con = mysqli_connect("localhost", "kimai", "kimai", "kimai");
if (mysqli_connect_errno()) {
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$sql = "UPDATE kimai15_usr SET `reported_div`='$selected_division' WHERE `usr_name`='$usrname';";
mysqli_query($con, $sql);
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
header('Location: ' . $actual_link);
}
// Jedes neue update schreibt seine Versionsnummer in die Datenbank.
// Beim nächsten Update kommt dann in der Datei /includes/var.php die neue V-Nr. mit.
// der updater.php weiss dann welche Aenderungen an der Datenbank vorgenommen werden muessen.
checkDBversion("..");
$tpl->assign('browser', get_agent());
// =========================================
// = PARSE EXTENSION CONFIGS (ext_configs) =
// =========================================
if ($handle = opendir('../extensions/')) {
chdir("../extensions/");
$ext_configs = array();
$css_extension_files = array();
$js_extension_files = array();
$extensions = array();
$tab_change_trigger = array();
$tss_hooks = array();
$rec_hooks = array();
$stp_hooks = array();
$chu_hooks = array();
$chk_hooks = array();
$chp_hooks = array();
$che_hooks = array();
$lft_hooks = array(); // list filter hooks
$rsz_hooks = array(); // resize hooks
$timeouts = array();
while (false !== ($file = readdir($handle))) {
if (is_dir($file) AND ( $file != ".") AND ( $file != "..") AND ( substr($file, 0) != ".") AND ( substr($file, 0, 1) != "#")) {
if (file_exists($file . '/config.ini')) {
$settings = parse_ini_file($file . '/config.ini');
// Check if user has the correct rank to use this extension
if (isset($kga['usr']))
switch ($kga['usr']['usr_sts']) {
case 0:
if ($settings['ADMIN_ALLOWED'] == "1") {
$extensions[] = $settings;
}
break;
case 1:
if ($settings['GROUP_LEADER_ALLOWED'] == "1") {
$extensions[] = $settings;
}
break;
case 2:
if ($settings['USER_ALLOWED'] == "1") {
$extensions[] = $settings;
}
break;
} else if ($settings['CUSTOMER_ALLOWED'] == "1")
$extensions[] = $settings;
foreach ($settings as $key => $value) {
// add CSS files
if ($key == 'CSS_INCLUDE_FILES') {
if (is_array($value)) {
foreach ($value as $subvalue) {
if (!in_array($subvalue, $css_extension_files)) {
$css_extension_files[] = $subvalue;
}
}
} else {
if (!in_array($value, $css_extension_files)) {
$css_extension_files[] = $value;
}
}
}
// add JavaScript files
if ($key == 'JS_INCLUDE_FILES') {
if (is_array($value)) {
foreach ($value as $subvalue) {
if (!in_array($subvalue, $js_extension_files)) {
$js_extension_files[] = $subvalue;
}
}
} else {
if (!in_array($value, $js_extension_files)) {
$js_extension_files[] = $value;
}
}
}
// read trigger function for tab change
if ($key == 'TAB_CHANGE_TRIGGER') {
$tab_change_trigger[] = $value;
}
// read hook triggers
if ($key == 'TIMESPACE_CHANGE_TRIGGER') {
$tss_hooks[] = $value;
}
if ($key == 'BUZZER_RECORD_TRIGGER') {
$rec_hooks[] = $value;
}
if ($key == 'BUZZER_STOP_TRIGGER') {
$stp_hooks[] = $value;
}
if ($key == 'CHANGE_USR_TRIGGER') {
$chu_hooks[] = $value;
}
if ($key == 'CHANGE_KND_TRIGGER') {
$chk_hooks[] = $value;
}
if ($key == 'CHANGE_PCT_TRIGGER') {
$chp_hooks[] = $value;
}
if ($key == 'CHANGE_EVT_TRIGGER') {
$che_hooks[] = $value;
}
if ($key == 'LIST_FILTER_TRIGGER') {
$lft_hooks[] = $value;
}
if ($key == 'RESIZE_TRIGGER') {
$rsz_hooks[] = $value;
}
// add Timeout clearing
if ($key == 'REG_TIMEOUTS') {
if (is_array($value)) {
foreach ($value as $subvalue) {
if (!in_array($subvalue, $timeouts)) {
$timeouts[] = $subvalue;
}
}
} else {
if (!in_array($value, $timeouts)) {
$timeouts[] = $value;
}
}
}
}
}
}
}
closedir($handle);
}
// ============================================
// = initialize currently displayed timespace =
// ============================================
$timespace = get_timespace();
$in = $timespace[0];
$out = $timespace[1];
// ===============================================
// = get time for the probably running stopwatch =
// ===============================================
$current_timer = array();
if (isset($kga['customer'])) {
$current_timer['all'] = 0;
$current_timer['hour'] = 0;
$current_timer['min'] = 0;
$current_timer['sec'] = 0;
} else
$current_timer = get_current_timer();
// =======================================
// = Display date and time in the header =
// =======================================
$wd = $kga['lang']['weekdays_short'][date("w", time())];
$dp_start = 0;
if ($kga['calender_start'] != "")
$dp_start = $kga['calender_start'];
else if (isset($kga['usr']))
$dp_start = date("d/m/Y", getjointime($kga['usr']['usr_ID']));
$dp_today = date("d/m/Y", time());
$tpl->assign('dp_start', $dp_start);
$tpl->assign('dp_today', $dp_today);
if (isset($kga['customer']))
$tpl->assign('total', formatDuration(get_zef_time($in, $out, null, array($kga['customer']['knd_ID']))));
else
$tpl->assign('total', formatDuration(get_zef_time($in, $out, $kga['usr']['usr_ID'])));
// ===========================
// = DatePicker localization =
// ===========================
$localized_DatePicker = "";
$tpl->assign('weekdays_array', sprintf("['%s','%s','%s','%s','%s','%s','%s']\n"
, $kga['lang']['weekdays'][0], $kga['lang']['weekdays'][1], $kga['lang']['weekdays'][2], $kga['lang']['weekdays'][3], $kga['lang']['weekdays'][4], $kga['lang']['weekdays'][5], $kga['lang']['weekdays'][6]));
$tpl->assign('weekdays_short_array', sprintf("['%s','%s','%s','%s','%s','%s','%s']\n"
, $kga['lang']['weekdays_short'][0], $kga['lang']['weekdays_short'][1], $kga['lang']['weekdays_short'][2], $kga['lang']['weekdays_short'][3], $kga['lang']['weekdays_short'][4], $kga['lang']['weekdays_short'][5], $kga['lang']['weekdays_short'][6]));
$tpl->assign('months_array', sprintf("['%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s']\n", $kga['lang']['months'][0], $kga['lang']['months'][1], $kga['lang']['months'][2], $kga['lang']['months'][3], $kga['lang']['months'][4], $kga['lang']['months'][5], $kga['lang']['months'][6], $kga['lang']['months'][7], $kga['lang']['months'][8], $kga['lang']['months'][9], $kga['lang']['months'][10], $kga['lang']['months'][11]));
$tpl->assign('months_short_array', sprintf("['%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s']", $kga['lang']['months_short'][0], $kga['lang']['months_short'][1], $kga['lang']['months_short'][2], $kga['lang']['months_short'][3], $kga['lang']['months_short'][4], $kga['lang']['months_short'][5], $kga['lang']['months_short'][6], $kga['lang']['months_short'][7], $kga['lang']['months_short'][8], $kga['lang']['months_short'][9], $kga['lang']['months_short'][10], $kga['lang']['months_short'][11]));
// ==============================
// = assign smarty placeholders =
// ==============================
$tpl->assign('current_timer_hour', $current_timer['hour']);
$tpl->assign('current_timer_min', $current_timer['min']);
$tpl->assign('current_timer_sec', $current_timer['sec']);
$tpl->assign('current_timer_start', $current_timer['all'] ? $current_timer['all'] : time());
$tpl->assign('current_time', time());
$tpl->assign('timespace_in', $in);
$tpl->assign('timespace_out', $out);
$tpl->assign('kga', $kga);
$tpl->assign('extensions', $extensions);
$tpl->assign('css_extension_files', $css_extension_files);
$tpl->assign('js_extension_files', $js_extension_files);
if (isset($kga['usr']))
$tpl->assign('recstate', get_rec_state($kga['usr']['usr_ID']));
else
$tpl->assign('recstate', 0);
$tpl->assign('lang_checkUsername', $kga['lang']['checkUsername']);
$tpl->assign('lang_checkGroupname', $kga['lang']['checkGroupname']);
$knd_data = array('knd_ID' => false, 'knd_name' => '');
$pct_data = array('pct_ID' => false, 'pct_name' => '');
$evt_data = array('evt_ID' => false, 'evt_name' => '');
if (!isset($kga['customer'])) {
//$lastZefRecord = zef_get_data(false);
$last_pct = pct_get_data($kga['usr']['lastProject']);
$last_evt = evt_get_data($kga['usr']['lastEvent']);
if (!$last_pct['pct_trash']) {
$pct_data = $last_pct;
$knd_data = knd_get_data($last_pct['pct_kndID']);
}
if (!$last_evt['evt_trash'])
$evt_data = $last_evt;
}
$tpl->assign('knd_data', $knd_data);
$tpl->assign('pct_data', $pct_data);
$tpl->assign('evt_data', $evt_data);
// =========================================
// = INCLUDE EXTENSION PHP FILE =
// =========================================
$extDir = WEBROOT . 'extensions';
if ($handle = opendir($extDir)) {
chdir($extDir);
$ext_configs = array();
while (false !== ($file = readdir($handle))) {
if (is_dir($file) AND ( $file != ".") AND ( $file != "..") AND ( substr($file, 0) != ".") AND ( substr($file, 0, 1) != "#")) {
if ($subhandle = opendir($extDir . DIRECTORY_SEPARATOR . $file)) {
while (false !== ($phpfile = readdir($subhandle))) {
if ($phpfile == "kimai_include.php") {
require_once($extDir . DIRECTORY_SEPARATOR . $file . DIRECTORY_SEPARATOR . $phpfile);
}
}
closedir($subhandle);
}
}
}
closedir($handle);
}
// =======================
// = display user table =
// =======================
if (isset($kga['customer']))
$arr_usr = array();
else
$arr_usr = get_arr_watchable_users($kga['usr']['usr_ID']);
if (count($arr_usr) > 0) {
$tpl->assign('arr_usr', $arr_usr);
} else {
$tpl->assign('arr_usr', '0');
}
$tpl->assign('usr_display', $tpl->fetch("lists/usr.tpl"));
// ==========================
// = display customer table =
// ========================
if (isset($kga['customer']))
$arr_knd = array(array(
'knd_ID' => $kga['customer']['knd_ID'],
'knd_name' => $kga['customer']['knd_name'],
'knd_visible' => $kga['customer']['knd_visible']));
else
$arr_knd = get_arr_knd($kga['usr']['usr_grp']);
if (count($arr_knd) > 0) {
$tpl->assign('arr_knd', $arr_knd);
} else {
$tpl->assign('arr_knd', '0');
}
$tpl->assign('knd_display', $tpl->fetch("lists/knd.tpl"));
// =========================
// = display project table =
// =========================
if (isset($kga['customer']))
$arr_pct = get_arr_pct_by_knd("all", $kga['customer']['knd_ID']);
else
$arr_pct = get_arr_pct($kga['usr']['usr_grp']);
if (count($arr_pct) > 0) {
$tpl->assign('arr_pct', $arr_pct);
} else {
$tpl->assign('arr_pct', '0');
}
$tpl->assign('pct_display', $tpl->fetch("lists/pct.tpl"));
// ========================
// = display events table =
// ========================
if (isset($kga['customer']))
$arr_evt = get_arr_evt_by_knd($kga['customer']['knd_ID']);
else if ($pct_data['pct_ID'])
$arr_evt = get_arr_evt_by_pct($kga['usr']['usr_grp'], $pct_data['pct_ID']);
else
$arr_evt = get_arr_evt($kga['usr']['usr_grp']);
if (count($arr_evt) > 0) {
$tpl->assign('arr_evt', $arr_evt);
} else {
$tpl->assign('arr_evt', '0');
}
$tpl->assign('evt_display', $tpl->fetch("lists/evt.tpl"));
if (isset($kga['usr']))
$tpl->assign('showInstallWarning', $kga['usr']['usr_sts'] == 0 && file_exists(WEBROOT . 'installer'));
else
$tpl->assign('showInstallWarning', false);
// ========================
// = BUILD HOOK FUNCTIONS =
// ========================
$hook_tss = "";
if (is_array($tss_hooks)) {
foreach ($tss_hooks as $hook) {
$hook_tss .= $hook;
}
}
$hook_bzzRec = "";
if (is_array($rec_hooks)) {
foreach ($rec_hooks as $hook) {
$hook_bzzRec .= $hook;
}
}
$hook_bzzStp = "";
if (is_array($stp_hooks)) {
foreach ($stp_hooks as $hook) {
$hook_bzzStp .= $hook;
}
}
$hook_chgUsr = "";
if (is_array($chu_hooks)) {
foreach ($chu_hooks as $hook) {
$hook_chgUsr .= $hook;
}
}
$hook_chgKnd = "";
if (is_array($chk_hooks)) {
foreach ($chk_hooks as $hook) {
$hook_chgKnd .= $hook;
}
}
$hook_chgPct = "";
if (is_array($chp_hooks)) {
foreach ($chp_hooks as $hook) {
$hook_chgPct .= $hook;
}
}
$hook_chgEvt = "";
if (is_array($che_hooks)) {
foreach ($che_hooks as $hook) {
$hook_chgEvt .= $hook;
}
}
$hook_filter = "";
if (is_array($lft_hooks)) {
foreach ($lft_hooks as $hook) {
$hook_filter .= $hook;
}
}
$hook_resize = "";
if (is_array($rsz_hooks)) {
foreach ($rsz_hooks as $hook) {
$hook_resize .= $hook;
}
}
$tpl->assign('hook_tss', $hook_tss);
$tpl->assign('hook_bzzRec', $hook_bzzRec);
$tpl->assign('hook_bzzStp', $hook_bzzStp);
$tpl->assign('hook_chgUsr', $hook_chgUsr);
$tpl->assign('hook_chgKnd', $hook_chgKnd);
$tpl->assign('hook_chgPct', $hook_chgPct);
$tpl->assign('hook_chgEvt', $hook_chgEvt);
$tpl->assign('hook_filter', $hook_filter);
$tpl->assign('hook_resize', $hook_resize);
$timeoutlist = "";
foreach ($timeouts as $timeout) {
$timeoutlist .= "kill_timeout('" . $timeout . "');";
}
$tpl->assign('timeoutlist', $timeoutlist);
$tpl->display('core/main.tpl');
?>