From f78244d64bb38fd5e147d20413f1bf13f1ad0dc2 Mon Sep 17 00:00:00 2001 From: jadrian-abramovitch <48164570+jadrian-abramovitch@users.noreply.github.com> Date: Fri, 10 Jul 2020 16:12:47 -0400 Subject: [PATCH 001/652] Update Calendar.class.php (#97) Days now turn purple instead of red until they are complete (default 8 hours) at which point they turn red as usual --- WEB-INF/lib/form/Calendar.class.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 447a45e02..74f52895d 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -28,6 +28,7 @@ import('form.FormElement'); import('DateAndTime'); +import('ttTimeHelper'); class Calendar extends FormElement { var $holidays = array(); @@ -183,8 +184,20 @@ function toString($date="") { // Entries exist. if($active_dates) { - if( in_array(strftime(DB_DATEFORMAT, $date), $active_dates) ) - $stl_link = ' class="CalendarLinkRecordsExist"'; + $day_total_minutes = ttTimeHelper::toMinutes(ttTimeHelper::getTimeForDay($date_to_check)); + global $user; + $workday_minutes = $user->getWorkdayMinutes(); + + //check for any entries in the day + if( in_array(strftime(DB_DATEFORMAT, $date), $active_dates) ){ + //check if entries total to a complete work day + if ($day_total_minutes >= $workday_minutes){ + $stl_link = ' class="CalendarLinkRecordsExist"'; + } + else { + $stl_link = ' class="CalendarLinkNonCompleteDay"'; + } + } } $str .= "controlName."=".strftime(DB_DATEFORMAT, $date)."\" tabindex=\"-1\">".date("d",$date).""; @@ -242,6 +255,7 @@ function _genStyles() { $str .= ".CalendarLinkWeekend {color: #999999;}\n"; $str .= ".CalendarLinkHoliday {color: #999999;}\n"; $str .= ".CalendarLinkRecordsExist {color: #FF0000;}\n"; + $str .= ".CalendarLinkNonCompleteDay {color: #800080;}\n"; $str .= "\n"; return $str; } From 80e8cc371b87d8a29863085ec3307d5a789e4659 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 13:34:07 +0000 Subject: [PATCH 002/652] Some refactoring and fixes on mobile time.php. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/time.tpl | 29 ++++---- mobile/time.php | 107 ++++++++++++++++++++---------- time.php | 12 ++-- 4 files changed, 97 insertions(+), 53 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7486f21e1..71d4fc489 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} -{if $user->isPluginEnabled('cl')} +{if $show_client} {/if} -{if $user->isPluginEnabled('iv')} +{if $show_billable} {/if} {if $custom_fields && $custom_fields->timeFields} @@ -68,22 +68,23 @@ {/foreach} {/if} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_project} {/if} -{if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} +{if $show_task} {/if} -{if (($smarty.const.TYPE_START_FINISH == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))} +{if $show_start} - +{/if} +{if $show_finish} {/if} -{if (($smarty.const.TYPE_DURATION == $user->record_type) || ($smarty.const.TYPE_ALL == $user->record_type))} +{if $show_duration} {/if} diff --git a/mobile/time.php b/mobile/time.php index e51e00bdc..f1c4e4d84 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -68,6 +68,16 @@ $group_id = $user->getGroup(); $config = new ttConfigHelper($user->getConfig()); +$showClient = $user->isPluginEnabled('cl'); +$showBillable = $user->isPluginEnabled('iv'); +$trackingMode = $user->getTrackingMode(); +$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; +$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +$recordType = $user->getRecordType(); +$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; +$showFinish = $showStart; +$showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; + // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); $selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); @@ -94,7 +104,7 @@ $cl_duration = trim($request->getParameter('duration')); $cl_note = trim($request->getParameter('note')); $cl_billable = 1; -if ($user->isPluginEnabled('iv')) { +if ($showBillable) { if ($request->isPost()) { $cl_billable = $request->getParameter('billable'); $_SESSION['billable'] = (int) $cl_billable; @@ -150,7 +160,8 @@ } // Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $user->getTrackingMode() && $user->isPluginEnabled('cl')) { +// Note: for other tracking modes the control is added further below. +if (MODE_TIME == $trackingMode && $showClient) { $active_clients = ttGroupHelper::getActiveClients(true); $form->addInput(array('type'=>'combobox', 'onchange'=>'fillProjectDropdown(this.value);', @@ -163,7 +174,28 @@ // Note: in other modes the client list is filtered to relevant clients only. See below. } -if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { +// Billable checkbox. +if ($showBillable) + $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); + +// If we have time custom fields - add controls for them. +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $field_name = 'time_field_'.$timeField['id']; + if ($timeField['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); + } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>$field_name, + 'style'=>'width: 250px;', + 'data'=>CustomFields::getOptions($timeField['id']), + 'value'=>$timeCustomFields[$timeField['id']]['value'], + 'empty'=>array(''=>$i18n->get('dropdown.select')))); + } + } +} + +// If we show project dropdown, add controls for project and client. +if ($showProject) { // Dropdown for projects assigned to user. $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); $project_list = $user->getAssignedProjects($options); @@ -176,8 +208,8 @@ 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { + // Client dropdown. + if ($showClient) { $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) @@ -205,7 +237,8 @@ } } -if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { +// Task dropdown. +if ($showTask) { $task_list = ttGroupHelper::getActiveTasks(); $form->addInput(array('type'=>'combobox', 'name'=>'task', @@ -215,7 +248,9 @@ 'datakeys'=>array('id','name'), 'empty'=>array(''=>$i18n->get('dropdown.select')))); } -if ((TYPE_START_FINISH == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) { + +// Start and finish controls. +if ($showStart) { $form->addInput(array('type'=>'text','name'=>'start','value'=>$cl_start,'onchange'=>"formDisable('start');")); $form->addInput(array('type'=>'text','name'=>'finish','value'=>$cl_finish,'onchange'=>"formDisable('finish');")); if ($user->punch_mode && !$user->canOverridePunchMode()) { @@ -224,29 +259,10 @@ $form->getElement('finish')->setEnabled(false); } } -if ((TYPE_DURATION == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) - $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); -$form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height: 60px;','value'=>$cl_note)); -if ($user->isPluginEnabled('iv')) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); -// If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} +// Duration control. +if ($showDuration) + $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); // If we have templates, add a dropdown to select one. if ($user->isPluginEnabled('tp')){ @@ -266,12 +282,20 @@ } } -// Submit. +// Note control. +$form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 250px; height: 60px;','value'=>$cl_note)); + +// A hidden control for today's date from user's browser. +$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. + +// Submit button. +$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); + if ($request->isPost()) { if ($request->getParameter('btn_submit')) { - + // Submit button clicked. // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) + if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) $err->add($i18n->get('error.client')); // Validate input in time custom fields. if ($custom_fields && $custom_fields->timeFields) { @@ -280,12 +304,14 @@ if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); } } - if (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) { + if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if (MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && $user->task_required) { + if ($showTask && $user->task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } + + // TODO: refactoring going on down from here... if (strlen($cl_duration) == 0) { if ($cl_start || $cl_finish) { if (!ttTimeHelper::isValidTime($cl_start)) @@ -368,6 +394,19 @@ $smarty->assign('next_date', $next_date); $smarty->assign('prev_date', $prev_date); $smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); + +$smarty->assign('show_client', $showClient); +$smarty->assign('show_billable', $showBillable); +$smarty->assign('show_project', $showProject); +$smarty->assign('show_task', $showTask); +$smarty->assign('show_start', $showStart); +$smarty->assign('show_finish', $showFinish); +$smarty->assign('show_duration', $showDuration); + + + + + $smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); diff --git a/time.php b/time.php index b1c0c4dba..1055470d0 100644 --- a/time.php +++ b/time.php @@ -138,7 +138,7 @@ $cl_duration = trim($request->getParameter('duration')); $cl_note = trim($request->getParameter('note')); $cl_billable = 1; -if ($user->isPluginEnabled('iv')) { +if ($showBillable) { if ($request->isPost()) { $cl_billable = $request->getParameter('billable'); $_SESSION['billable'] = (int) $cl_billable; @@ -293,9 +293,11 @@ $form->getElement('finish')->setEnabled(false); } } + // Duration control. if ($showDuration) $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); + // File upload control. if ($showFiles) $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); @@ -322,10 +324,13 @@ if (!defined('NOTE_INPUT_HEIGHT')) define('NOTE_INPUT_HEIGHT', 40); $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 600px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); + // Calendar. $form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar + // A hidden control for today's date from user's browser. $form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. + // Submit button. $form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); @@ -342,10 +347,10 @@ if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); } } - if (MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode) { + if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if (MODE_PROJECTS_AND_TASKS == $trackingMode && $user->task_required) { + if ($showTask && $user->task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { @@ -480,7 +485,6 @@ $smarty->assign('show_start', $showStart); $smarty->assign('show_finish', $showFinish); $smarty->assign('show_duration', $showDuration); -$smarty->assign('show_templates', $showTemplates); $smarty->assign('show_note_column', $showNoteColumn); $smarty->assign('show_note_row', $showNoteRow); $smarty->assign('show_files', $showFiles); From 1a8bb88c2b59660be6d55da2816af800191a95b4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 14:32:23 +0000 Subject: [PATCH 003/652] Finished refactoring mobile time.php and template. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/time.tpl | 105 +++++++++++++++--------------- WEB-INF/templates/time.tpl | 96 +++++++++++++-------------- mobile/time.php | 14 +--- time.php | 4 +- 5 files changed, 105 insertions(+), 116 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 71d4fc489..3c0845777 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
 Anuko Time Tracker 1.19.18.5216 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5217 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl index 79398703b..b14e4d456 100644 --- a/WEB-INF/templates/mobile/time.tpl +++ b/WEB-INF/templates/mobile/time.tpl @@ -17,18 +17,18 @@
- {if $time_records} - - {foreach $time_records as $record} +{if $time_records} +
+ {foreach $time_records as $record} -{if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + {if $show_project} -{/if} + {/if} - {/foreach} + {/foreach}
{$record.project|escape}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{$record.duration}{if ($record.duration == '0:00' && $record.start <> '')}{/if} {if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.edit}{/if} {if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.delete}{/if}
@@ -36,7 +36,7 @@
{$day_total}
- {/if} +{/if}
@@ -53,11 +53,11 @@
{$i18n.label.user}:
{$forms.timeRecordForm.user.control}
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$forms.timeRecordForm.task.control}
{$i18n.label.start}:
{$forms.timeRecordForm.start.control} 
{$i18n.label.finish}:
{$forms.timeRecordForm.finish.control} 
{$i18n.label.duration}:
{$forms.timeRecordForm.duration.control}
-
 Anuko Time Tracker 1.19.18.5217 | Copyright © Anuko | +  Anuko Time Tracker 1.19.18.5218 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl index b14e4d456..038d6790d 100644 --- a/WEB-INF/templates/mobile/time.tpl +++ b/WEB-INF/templates/mobile/time.tpl @@ -15,94 +15,91 @@
- - +
+
{if $time_records} - +
{foreach $time_records as $record} - + {if $show_project} - + {/if} - - - - + + + + {/foreach} -
{$record.project|escape}{$record.project|escape}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{$record.duration}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.edit}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.delete}{/if}
{if ($record.duration == '0:00' && $record.start <> '')}{/if}{$record.duration}{if ($record.duration == '0:00' && $record.start <> '')}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.edit}{/if}{if $record.approved || $record.timesheet_id || $record.invoice_id} {else}{$i18n.label.delete}{/if}
- - - - - -
{$i18n.label.day_total}:{$day_total}
+
+ + + + + +
{$i18n.label.day_total}:{$day_total}
{/if} - - + + {$forms.timeRecordForm.open} - - -
- - - - - -
- + + + +
+ + + + +
+ {if $user_dropdown} - - + + {/if} {if $show_client} - - + + {/if} {if $show_billable} - + {/if} {if $custom_fields && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - + + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + + {/foreach} {/if} {if $show_project} - - + + {/if} {if $show_task} - - + + {/if} {if $show_start} - - + + {/if} {if $show_finish} - - + + {/if} {if $show_duration} - - + + {/if} {if $template_dropdown} - - + + {/if} - - - -
{$i18n.label.user}:
{$forms.timeRecordForm.user.control}
{$i18n.label.user}:
{$forms.timeRecordForm.user.control}
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$forms.timeRecordForm.task.control}
{$i18n.label.task}:
{$forms.timeRecordForm.task.control}
{$i18n.label.start}:
{$forms.timeRecordForm.start.control} 
{$i18n.label.start}:
{$forms.timeRecordForm.start.control} 
{$i18n.label.finish}:
{$forms.timeRecordForm.finish.control} 
{$i18n.label.finish}:
{$forms.timeRecordForm.finish.control} 
{$i18n.label.duration}:
{$forms.timeRecordForm.duration.control}
{$i18n.label.duration}:
{$forms.timeRecordForm.duration.control}
{$i18n.label.template}:
{$forms.timeRecordForm.template.control}
{$i18n.label.template}:
{$forms.timeRecordForm.template.control}
{$i18n.label.note}:
{$forms.timeRecordForm.note.control}
+
{$i18n.label.note}:
{$forms.timeRecordForm.note.control}
+
{$forms.timeRecordForm.btn_submit.control}
{$forms.timeRecordForm.btn_submit.control}
-
{$forms.timeRecordForm.close} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index d153dc96d..0b78b1788 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -38,11 +38,11 @@ {/if} {if $custom_fields && $custom_fields->timeFields} {foreach $custom_fields->timeFields as $timeField} - - {$timeField['label']|escape}{if $timeField['required']} (*){/if}: - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - {$forms.timeRecordForm.$control_name.control} - + + {$timeField['label']|escape}{if $timeField['required']} (*){/if}: + {assign var="control_name" value='time_field_'|cat:$timeField['id']} + {$forms.timeRecordForm.$control_name.control} + {/foreach} {/if} {if $show_project} @@ -108,96 +108,96 @@ - - +
+
{if $time_records} - + {if $show_client} - + {/if} {if $show_project} - + {/if} {if $show_task} - + {/if} {if $show_start} - + {/if} {if $show_finish} - + {/if} - + {if $show_note_column} - + {/if} {if $show_files} - + {/if} - - - + + + {foreach $time_records as $record} - + {if $show_client} - + {/if} {if $show_project} - + {/if} {if $show_task} - + {/if} {if $show_start} - + {/if} {if $show_finish} - + {/if} - + {if $show_note_column} - + {/if} {if $show_files} {if $record.has_files} - + {else} - + {/if} {/if} - - + - + + {if $show_note_row && $record.comment} - - - - + + + + {/if} {/foreach} -
{$i18n.label.client}{$i18n.label.client}{$i18n.label.project}{$i18n.label.project}{$i18n.label.task}{$i18n.label.task}{$i18n.label.start}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.duration}{$i18n.label.note}{$i18n.label.note}
{$record.client|escape}{$record.client|escape}{$record.project|escape}{$record.project|escape}{$record.task|escape}{$record.task|escape}{if $record.start}{$record.start}{else} {/if}{if $record.start}{$record.start}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if $record.comment}{$record.comment|escape}{else} {/if}{if $record.comment}{$record.comment|escape}{else} {/if}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files} + {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.edit} + {$i18n.label.edit} {if ($record.duration == '0:00' && $record.start <> '')} - - - - + + + + {/if} {/if} - + {if $record.approved || $record.timesheet_id || $record.invoice_id} -   +   {else} - {$i18n.label.delete} + {$i18n.label.delete} {/if} -
{$i18n.label.note}:{$record.comment|escape}
{$i18n.label.note}:{$record.comment|escape}
+
{/if} - - + + diff --git a/mobile/time.php b/mobile/time.php index f1c4e4d84..233f1d16f 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -310,8 +310,6 @@ if ($showTask && $user->task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } - - // TODO: refactoring going on down from here... if (strlen($cl_duration) == 0) { if ($cl_start || $cl_finish) { if (!ttTimeHelper::isValidTime($cl_start)) @@ -323,11 +321,11 @@ $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { - if ((TYPE_START_FINISH == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) { + if ($showStart) { $err->add($i18n->get('error.empty'), $i18n->get('label.start')); $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } - if ((TYPE_DURATION == $user->getRecordType()) || (TYPE_ALL == $user->getRecordType())) + if ($showDuration) $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { @@ -393,8 +391,8 @@ $smarty->assign('next_date', $next_date); $smarty->assign('prev_date', $prev_date); +$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); - $smarty->assign('show_client', $showClient); $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); @@ -402,12 +400,6 @@ $smarty->assign('show_start', $showStart); $smarty->assign('show_finish', $showFinish); $smarty->assign('show_duration', $showDuration); - - - - - -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('client_list', $client_list); $smarty->assign('project_list', $project_list); $smarty->assign('task_list', $task_list); diff --git a/time.php b/time.php index 1055470d0..9f85d5981 100644 --- a/time.php +++ b/time.php @@ -364,11 +364,11 @@ $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); } } else { - if (TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType) { + if ($showStart) { $err->add($i18n->get('error.empty'), $i18n->get('label.start')); $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); } - if (TYPE_DURATION == $recordType || TYPE_ALL == $recordType) + if ($showDuration) $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); } } else { From bf36e82b0af62613d2826ef793e199eddaaa0ac6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 15:11:09 +0000 Subject: [PATCH 004/652] Some html fixes. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 1 + WEB-INF/templates/mobile/header.tpl | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3c0845777..0390d8a25 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- diff --git a/initialize.php b/initialize.php index 42b94a865..4e41c7ea3 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5382"); +define("APP_VERSION", "1.19.23.5383"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/client_add.php b/mobile/client_add.php deleted file mode 100644 index 2050204a6..000000000 --- a/mobile/client_add.php +++ /dev/null @@ -1,94 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_address = trim($request->getParameter('address')); - $cl_tax = $request->getParameter('tax'); - $cl_projects = $request->getParameter('projects'); -} else { - // Do not assign all projects to a new client by default. This should help to reduce clutter. - // foreach ($projects as $project_item) - // $cl_projects[] = $project_item['id']; -} - -$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; - -$form = new Form('clientForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','class'=>'mobile-textarea','value'=>$cl_address)); -$form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -if ($show_projects) - $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); - - if ($err->no()) { - if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array('name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'projects' => $cl_projects, - 'status' => ACTIVE))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); -$smarty->assign('show_projects',$show_projects); -$smarty->assign('title', $i18n->get('title.add_client')); -$smarty->assign('content_page_name', 'mobile/client_add.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/client_delete.php b/mobile/client_delete.php deleted file mode 100644 index 8e05ccde8..000000000 --- a/mobile/client_delete.php +++ /dev/null @@ -1,78 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -$id = (int)$request->getParameter('id'); -$client = ttClientHelper::getClient($id); -if (!$client) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$client_to_delete = $client['name']; - -$form = new Form('clientDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$id)); -$form->addInput(array('type'=>'combobox','name'=>'delete_client_entries', - 'data'=>array('0'=>$i18n->get('dropdown.do_not_delete'),'1'=>$i18n->get('dropdown.delete')))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if (ttClientHelper::delete($id, $request->getParameter('delete_client_entries'))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - - if ($request->getParameter('btn_cancel')) { - header('Location: clients.php'); - exit(); - } -} // isPost - -$smarty->assign('client_to_delete', $client_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.delete_client')); -$smarty->assign('content_page_name', 'mobile/client_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/client_edit.php b/mobile/client_edit.php deleted file mode 100644 index ab8686509..000000000 --- a/mobile/client_edit.php +++ /dev/null @@ -1,135 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -$client = ttClientHelper::getClient($cl_id, true); -if (!$client) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_address = trim($request->getParameter('address')); - $cl_tax = trim($request->getParameter('tax')); - $cl_status = $request->getParameter('status'); - $cl_projects = $request->getParameter('projects'); -} else { - $cl_name = $client['name']; - $cl_address = $client['address']; - $cl_tax = $client['tax']; - $cl_status = $client['status']; - $assigned_projects = ttClientHelper::getAssignedProjects($cl_id); - foreach($assigned_projects as $project_item) { - $cl_projects[] = $project_item['id']; - } -} - -$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; - -$form = new Form('clientForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'text','name'=>'name','maxlength'=>'100','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','class'=>'mobile-textarea','value'=>$cl_address)); -$form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -if ($show_projects) - $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $client = ttClientHelper::getClientByName($cl_name); - if (($client && ($cl_id == $client['id'])) || !$client) { - if (ttClientHelper::update(array('id' => $cl_id, - 'name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array('name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_delete')) { - header("Location: client_delete.php?id=$cl_id"); - exit(); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.edit_client')); -$smarty->assign('content_page_name', 'mobile/client_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/clients.php b/mobile/clients.php deleted file mode 100644 index d1e6b38f3..000000000 --- a/mobile/clients.php +++ /dev/null @@ -1,54 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -if($user->can('manage_clients')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $inactive_clients = ttGroupHelper::getInactiveClients(true); -} else - $active_clients = $user->getAssignedClients(); - -$smarty->assign('active_clients', $active_clients); -$smarty->assign('inactive_clients', $inactive_clients); -$smarty->assign('title', $i18n->get('title.clients')); -$smarty->assign('content_page_name', 'mobile/clients.tpl'); -$smarty->display('mobile/index.tpl'); From fa0a08caa353fd5e2667780c7bb42eb763ad1b02 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Nov 2020 16:36:43 +0000 Subject: [PATCH 195/652] Cosmetic changes in translation files. --- README.md | 2 +- WEB-INF/resources/ca.lang.php | 34 +++++------------------------- WEB-INF/resources/cs.lang.php | 34 +++++------------------------- WEB-INF/resources/da.lang.php | 34 +++++------------------------- WEB-INF/resources/de.lang.php | 28 ++----------------------- WEB-INF/resources/en.lang.php | 34 +++++------------------------- WEB-INF/resources/es.lang.php | 36 ++++++-------------------------- WEB-INF/resources/et.lang.php | 28 ++----------------------- WEB-INF/resources/fa.lang.php | 34 +++++------------------------- WEB-INF/resources/fi.lang.php | 33 +++++------------------------ WEB-INF/resources/fr.lang.php | 32 ++++------------------------ WEB-INF/resources/gr.lang.php | 28 ++----------------------- WEB-INF/resources/he.lang.php | 28 ++----------------------- WEB-INF/resources/hu.lang.php | 28 ++----------------------- WEB-INF/resources/it.lang.php | 28 ++----------------------- WEB-INF/resources/ja.lang.php | 28 ++----------------------- WEB-INF/resources/ko.lang.php | 28 ++----------------------- WEB-INF/resources/nl.lang.php | 28 ++----------------------- WEB-INF/resources/no.lang.php | 28 ++----------------------- WEB-INF/resources/pl.lang.php | 28 ++----------------------- WEB-INF/resources/pt-br.lang.php | 28 ++----------------------- WEB-INF/resources/pt.lang.php | 28 ++----------------------- WEB-INF/resources/ro.lang.php | 28 ++----------------------- WEB-INF/resources/ru.lang.php | 28 ++----------------------- WEB-INF/resources/sk.lang.php | 28 ++----------------------- WEB-INF/resources/sl.lang.php | 28 ++----------------------- WEB-INF/resources/sr.lang.php | 28 ++----------------------- WEB-INF/resources/sv.lang.php | 28 ++----------------------- WEB-INF/resources/tr.lang.php | 28 ++----------------------- WEB-INF/resources/zh-cn.lang.php | 28 ++----------------------- WEB-INF/resources/zh-tw.lang.php | 34 +++++------------------------- initialize.php | 2 +- mobile/index.php | 5 ++--- 33 files changed, 91 insertions(+), 811 deletions(-) diff --git a/README.md b/README.md index f3b7987ef..cf2f8601f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Anuko Time Tracker ## About -Anuko [Time Tracker](https://www.anuko.com/time-tracker/index.htm) is a simple, easy to use, open source, web-based time tracking application written in PHP. It allows you to track the time that employees or colleagues spend working on projects and tasks. It needs a web server such as Apache, IIS, etc. to run on, and a database to keep the data in, such as MySQL. +Anuko [Time Tracker](https://www.anuko.com/time-tracker/index.htm) is an open source, web-based time tracking application written in PHP. It allows you to track the time that employees or colleagues spend working on projects and tasks. It needs a web server such as Apache, IIS, etc. to run on, and a database to keep the data in, such as MySQL. ## Free Hosting [Anuko](https://www.anuko.com) provides [free hosting](https://www.anuko.com/time-tracker/free-hosting/index.htm) of Time Tracker to individuals and small groups up to 5 users. To start using Time Tracker immediately, create a group at https://timetracker.anuko.com diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index de6e0df96..34421e73d 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -1,30 +1,6 @@ '¿Ha oblidat la seva paraula de pas?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'S\\\'ha enviat la petició de restablir paraula de pas.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Sol·licitud de restabliment de la paraula de pas de Anuko Time Tracker', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Per restablir la paraula de pas, si us plau escrigui-la i faci clic en guardar.', @@ -649,7 +625,7 @@ 'form.mail.to' => 'Per a', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Factura enviada.', diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 92411b33b..199a96faf 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -1,30 +1,6 @@ 'Zapomenuté heslo?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Zaslán požadavek k vymazání hesla.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker požadavek na vymazání hesla', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. @@ -662,7 +638,7 @@ 'form.mail.to' => 'Komu', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Faktura odeslána.', diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 3ab49c39e..88b5324fb 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -1,30 +1,6 @@ 'Nulstilling af adgangskode er sendt på email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker - Anmodning om nulstilling af adgangskode', // TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Hej\n\nNogen, IP %s, har bedt om at få nulstillet din adgangskode. Tryk på linket hvis du vil have nulstillet din adgangskode.\n\n%s\n\nAnuko Time Tracker er et nemt, let at bruge, open source tidsregistrerings system. Besøg https://www.anuko.com for mere information.\n\n", +'form.reset_password.email_body' => "Hej\n\nNogen, IP %s, har bedt om at få nulstillet din adgangskode. Tryk på linket hvis du vil have nulstillet din adgangskode.\n\n%s\n\nAnuko Time Tracker er et open source tidsregistrerings system. Besøg https://www.anuko.com for mere information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Skriv en ny adgangskode og tryk Gem.', @@ -626,7 +602,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Til', 'form.mail.report_subject' => 'Tidsregistrerings Rapport', -'form.mail.footer' => 'Anuko Time Tracker er et simpelt, let at bruge, open source
tidsregistrerings system. Besøg www.anuko.com for mere information.', +'form.mail.footer' => 'Anuko Time Tracker er et open source
tidsregistrerings system. Besøg www.anuko.com for mere information.', 'form.mail.report_sent' => 'Rapport sendt.', 'form.mail.invoice_sent' => 'Faktura sendt.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 7db6f93bb..be1ede828 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -1,30 +1,6 @@ 'Forgot password?', -'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Password reset request sent by email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', -'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Type new password and click on Save.', @@ -587,7 +563,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'To', 'form.mail.report_subject' => 'Time Tracker Report', -'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Invoice sent.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 0c1d2c6b9..e7df23ad6 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -1,30 +1,6 @@ '¿Olvido su contraseña?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: check / improve translation of form.reset_password.message. @@ -486,9 +462,9 @@ 'form.reset_password.email_subject' => 'Solicitud de reestablecimiento de la contraseña de Anuko Time Tracker', // Note to translators: the ending of this string needs to be translated. // TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Querido usuario, Alguien, IP %s, solicitó reestablecer su contraseña de Anuko Time Tracker. Por favor visite este enlace si quiere reestablecer su contraseña.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Querido usuario, Alguien, IP %s, solicitó reestablecer su contraseña de Anuko Time Tracker. Por favor visite este enlace si quiere reestablecer su contraseña.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: improve translation of form.change_password.tip. @@ -664,7 +640,7 @@ // TODO: translate form.mail.report_subject. // 'form.mail.report_subject' => 'Time Tracker Report', // Note to translators: the following strings need to be translated. -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Factura enviada.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index b6b442441..e2c63ef91 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -1,30 +1,6 @@ 'بازیابی رمز عبور؟', // TODO: translate form.login.about. -'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'درخواست بازیابی رمزعبور به ایمیل فرستاده شد.', @@ -481,7 +457,7 @@ // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', 'form.reset_password.email_subject' => 'درخواست بازیابی رمزعبور فرستاده شد', // TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Older translation is below. // 'form.reset_password.email_body' => "کاربران گرامی\n\n یک نفر، شاید خودتان، درخواست بازیابی رمزعبور نرم افزار رهگیری زمان شما را داشته است.لطفا برای تغییر رمزعبور روی لینک زیر کلیک کنید: \n\n%s\n\n", @@ -649,7 +625,7 @@ 'form.mail.to' => 'به', 'form.mail.report_subject' => 'گزارش تایم شیت', // TODO: translate form.mail.footer. -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.report_sent' => 'گزارش ارسال شد.', 'form.mail.invoice_sent' => 'فاکتور ارسال شد.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 753dcf8ce..42af8047e 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -1,30 +1,6 @@ 'Salasanan nollauspyyntöviesti lähetetty.', 'form.reset_password.email_subject' => 'Anuko Time Tracker -salasanan nollauspyyntö', -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Hyvä käyttäjä,\n\nJoku, IP %s, on pyytänyt nollaamaan Anuko Time Tracker -ohjelman salasanasi. Jos haluat nollata salasanasi, käy sivulla \n\n%s\n\nAnuko Time Tracker on yksinkertainen ja helppokäyttöinen vapaan koodin tuntiseurantaohjelmisto. Lisätietoja sivulla https://www.anuko.com.\n\n", @@ -631,6 +607,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Vastaanottaja', 'form.mail.report_subject' => 'Time Tracker -raportti', +// TODO: English string for form.mail.footer changed. Re-translate. 'form.mail.footer' => 'Anuko Time Tracker on yksinkertainen ja helppokäyttöinen vapaan koodin tuntiseurantaohjelmisto. Lisätietoja sivulla www.anuko.com.', 'form.mail.report_sent' => 'Raportti lähetetty.', 'form.mail.invoice_sent' => 'Lasku lähetetty.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index ca00e9471..46116db12 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -1,30 +1,6 @@ 'Une demande de réinitialisation du mot de passe a été envoyé par courriel.', 'form.reset_password.email_subject' => 'Demande de réinitialisation de mot de passe Anuko Time Tracker', -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Cher utilisateur,\n\nQuelqu\'un, IP %s, avez demandé une réinitialisation de votre mot de passe. Veuillez de suivre ce lien pour le réinitialiser\n\n%s\n\nAnuko Time Tracker est un système de gestion du temps, open source, simple et facile à utiliser. Visitez https://www.anuko.com pour plus d\'informations.\n\n", diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index ba630f269..5e3ee8ee8 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -1,30 +1,6 @@ '忘記密碼?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '密碼重設請求已經發送。', // TODO: Add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko時間追蹤器密碼重設請求', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. @@ -647,7 +623,7 @@ 'form.mail.to' => '到', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '發票已送出。', diff --git a/initialize.php b/initialize.php index 4e41c7ea3..ae59bd0db 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5383"); +define("APP_VERSION", "1.19.23.5384"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/index.php b/mobile/index.php index fa3f04c46..8fc64b35e 100644 --- a/mobile/index.php +++ b/mobile/index.php @@ -44,10 +44,9 @@ From 6f4cf24936570945a4809d8cfc33acb42c952813 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Nov 2020 17:17:34 +0000 Subject: [PATCH 196/652] Cosmetic improvements in translation files. --- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 3 ++- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 ++ WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 ++ initialize.php | 2 +- 25 files changed, 32 insertions(+), 19 deletions(-) diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 88b5324fb..040405503 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -431,7 +431,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Har du glemt din adgangskode?', -'form.login.about' => 'Anuko Time Tracker er et nemt, let at bruge, open source tidsregistrerings system.', +'form.login.about' => 'Anuko Time Tracker er et open source tidsregistrerings system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Nulstilling af adgangskode er sendt på email.', diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index be1ede828..2268692bb 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -422,7 +422,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Passwort vergessen?', -'form.login.about' => 'Anuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source Zeiterfassungssystem.', +'form.login.about' => 'Anuko Time Tracker ist ein Open-Source Zeiterfassungssystem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Anfrage zur Zurücksetzung des Passwortes wurde per E-mail gesendet.', diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index e2c63ef91..30f697cbd 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -439,7 +439,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Unustasid salasõna?', -'form.login.about' => 'Anuko Time Tracker on lihtne, lihtsalt kasutatav ja avatud lähtekoodiga ajaarvestussüsteem.', +'form.login.about' => 'Anuko Time Tracker on avatud lähtekoodiga ajaarvestussüsteem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Salasõna tühistamise teade on saadetud e-postile.', diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 42af8047e..034ea6ae0 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -436,7 +436,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Salasana unohtunut?', -'form.login.about' => 'Anuko Time Tracker on yksinkertainen ja helppokäyttöinen vapaan koodin tuntiseurantaohjelmisto.', + // TODO: check translation of form.login.about - is open source "vapaan koodin"? +'form.login.about' => 'Anuko Time Tracker on vapaan koodin tuntiseurantaohjelmisto.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Salasanan nollauspyyntöviesti lähetetty.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 46116db12..44ba9b2bb 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -428,7 +428,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Mot de passe oublié?', -'form.login.about' => 'Anuko Time Tracker est un système de gestion du temps, open source, simple et facile à utiliser.', +'form.login.about' => 'Anuko Time Tracker est un système de gestion du temps, open source.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Une demande de réinitialisation du mot de passe a été envoyé par courriel.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 5e3ee8ee8..29404a831 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -428,7 +428,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Ξεχάσατε τον κωδικό πρόσβασης;', -'form.login.about' => 'Anuko Time Tracker είναι ένα απλό, εύχρηστο, ανοικτού κώδικα σύστημα παρακολούθησης χρόνου.', +'form.login.about' => 'Anuko Time Tracker είναι ένα ανοικτού κώδικα σύστημα παρακολούθησης χρόνου.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Το αίτημα επαναφοράς κωδικού πρόσβασης αποστέλλεται μέσω ηλεκτρονικού ταχυδρομείου.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 1460943e2..2bc6129d9 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -453,6 +453,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'שכחת סיסמה?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker הינה מערכת פשוטה, קלה לשימוש וחינמית לניהול זמן.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 509034524..98a566d10 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -450,7 +450,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Elfelejtetted a jelszót?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 1626913ec..1b7f56e46 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -438,7 +438,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Password dimenticata?', -'form.login.about' => 'Anuko Time Tracker è un sistema semplice e open source per registrare i tempi di lavoro.', +'form.login.about' => 'Anuko Time Tracker è un sistema open source per registrare i tempi di lavoro.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Richiesta di reset password inviata via mail.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index b73f3ea83..aae1528cc 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -451,7 +451,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'パスワードを忘れましたか?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '送信したパスワードの初期化の要求。', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index e7430b6ee..6794c57e7 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -455,7 +455,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '암호를 잊으셨습니까?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => '송신한 암호 재설정 요청.', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 959822057..8b2e557ea 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -390,6 +390,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Wachtwoord vergeten?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index ed392d932..77d43637f 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -450,6 +450,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Glemt passordet?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker er et enkelt, brukervennlig tidsregistreringssystem basert på åpen kildekode.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 5f67ff40f..b617314db 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -439,7 +439,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Nie pamiętasz hasła?', -'form.login.about' => 'Anuko Time Tracker jest prostym, łatwym w użyciu, otwartoźródłowym systemem śledzenia czasu.', +'form.login.about' => 'Anuko Time Tracker jest otwartoźródłowym systemem śledzenia czasu.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Instrukcje zmiany hasła zostały wysłane na adres e-mail połączony z kontem.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 3fb2f3aed..95e9d1060 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -434,7 +434,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Esqueceu a senha?', -'form.login.about' => 'Anuko Time Tracker é um sistema, simples, de fácil uso, de código aberto, de rastreamento do tempo.', +'form.login.about' => 'Anuko Time Tracker é um sistema de código aberto de rastreamento do tempo.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Pedido para resetar a senha enviado por e-mail.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index fab8af4cf..dd72ab4b6 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -434,7 +434,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Esqueceu a senha?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 32edb49e9..55731aa05 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -454,7 +454,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parola pierduta?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Cererea de resetare a parolei a fost trimisa.', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 3268f0878..dd6c1e1c8 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -391,7 +391,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Забыли пароль?', -'form.login.about' => 'Anuko Time Tracker - это открытая (open source), простая и лёгкая в использовании система трекинга рабочего времени.', +'form.login.about' => 'Anuko Time Tracker - это открытая (open source) система трекинга рабочего времени.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Запрос на сброс пароля отослан по e-mail.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 90f500e0c..95a025a7a 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -443,7 +443,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zabudnuté heslo?', -'form.login.about' => 'Anuko Time Tracker je jednoduchý a ľahko použiteľný systém na sledovanie času s otvoreným zdrojovým kódom.', +'form.login.about' => 'Anuko Time Tracker je systém na sledovanie času s otvoreným zdrojovým kódom.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Žiadosť o obnovenie hesla bola odoslaná e-mailom.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 2e1004810..eb8bd99dd 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -426,7 +426,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. // TODO: translate the following. // 'form.login.forgot_password' => 'Forgot password?', -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Zahteva za razveljavitev gesla je bila poslana.', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index f67e81334..a80f0e67a 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -437,6 +437,8 @@ // Forma prijave. Pogledajte primer na https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Zaboravili ste lozinku?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker je jednostavan i lak za korišćenje za praćenje radnog vremena.', // Izmena forme za lozinku. Pogledajte primer na https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index fc1c7bd62..6bae583a7 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -436,6 +436,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Glömt lösenordet?', + // TODO: re-translate form.login.about as it has changed. + // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker är en lättanvänd applikation byggd med öppen källkod som enkelt låter dig spåra och hålla koll på arbetstider.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index f1c164c62..3ba51a116 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -462,7 +462,7 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Parolanızı unuttunuz mu?', // TODO: translate the following. -// 'form.login.about' => 'Anuko Time Tracker is a simple, easy to use, open source time tracking system.', +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Parola sıfırlama talebi yollandı.', // TODO: add "by email" to match the English string. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index c10942223..7eb54073a 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -442,6 +442,8 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => '忘记密码?', +// TODO: re-translate form.login.about as it has changed. +// 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', 'form.login.about' => 'Anuko Time Tracker 是一种简单、易用、开放源代码的实时跟踪系统。', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. diff --git a/initialize.php b/initialize.php index ae59bd0db..1f219134f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5384"); +define("APP_VERSION", "1.19.23.5385"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2de5567b129e8190b9c1f9d80d9cedc5b6c5d37d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Nov 2020 18:10:00 +0000 Subject: [PATCH 197/652] Some more refactoring in translation files. --- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fa.lang.php | 2 +- WEB-INF/resources/fi.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 4 ++-- WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/ja.lang.php | 6 +++--- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 4 ++-- WEB-INF/resources/pl.lang.php | 4 ++-- WEB-INF/resources/pt-br.lang.php | 4 ++-- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 6 +++--- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 4 ++-- WEB-INF/resources/sl.lang.php | 6 +++--- WEB-INF/resources/sr.lang.php | 4 ++-- WEB-INF/resources/sv.lang.php | 4 ++-- WEB-INF/resources/tr.lang.php | 6 +++--- WEB-INF/resources/zh-cn.lang.php | 2 +- initialize.php | 2 +- 25 files changed, 41 insertions(+), 39 deletions(-) diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 2268692bb..13626d9e6 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -427,7 +427,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Anfrage zur Zurücksetzung des Passwortes wurde per E-mail gesendet.', 'form.reset_password.email_subject' => 'Anuko Time Tracker Anfrage zur Zurücksetzung des Passwortes', -'form.reset_password.email_body' => "Sehr geehrter Nutzer,\n\nEin Benutzer mit der IP %s hat vor Kurzem die Zurücksetzung Ihres Passworts für Anuko Time Tracker Passwort angefordert. Bitte rufen Sie diesen Link auf wenn Sie Ihr Passwort zurücksetzen möchten.\n\n%s\n\nAnuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source Zeiterfassungs-System. Besuchen Sie https://www.anuko.com für weitere Informationen.\n\n", +'form.reset_password.email_body' => "Sehr geehrter Nutzer,\n\nEin Benutzer mit der IP %s hat vor Kurzem die Zurücksetzung Ihres Passworts für Anuko Time Tracker Passwort angefordert. Bitte rufen Sie diesen Link auf wenn Sie Ihr Passwort zurücksetzen möchten.\n\n%s\n\nAnuko Time Tracker ist ein Open-Source Zeiterfassungs-System. Besuchen Sie https://www.anuko.com für weitere Informationen.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Um das Passwort zurückzusetzen, geben Sie ein Neues ein und klicken dann auf Speichern.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index e7df23ad6..05c24948c 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -461,7 +461,7 @@ 'form.reset_password.message' => 'Se ha enviado la petición de reestablecer contraseña.', 'form.reset_password.email_subject' => 'Solicitud de reestablecimiento de la contraseña de Anuko Time Tracker', // Note to translators: the ending of this string needs to be translated. -// TODO: English string has changed. "from IP added. Re-translate the beginning. +// TODO: English string has changed. "from IP added. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Querido usuario, Alguien, IP %s, solicitó reestablecer su contraseña de Anuko Time Tracker. Por favor visite este enlace si quiere reestablecer su contraseña.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 30f697cbd..d938cf079 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -444,7 +444,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Salasõna tühistamise teade on saadetud e-postile.', 'form.reset_password.email_subject' => 'Anuko Time Tracker, parooli tühistamise nõue', -'form.reset_password.email_body' => "Lugupeetud Kasutaja,\n\nIP-lt %s on nõutud Teie salasõna lähtestamist. Palun avage allolev link, kui soovite oma parooli lähtestada.\n\n%s\n\nAnuko Time Tracker on lihtne, lihtsalt kasutatav ja avatud lähtekoodiga ajaarvestussüsteem. Lisainfo saamiseks külastage https://www.anuko.com lehekülge.\n\n", +'form.reset_password.email_body' => "Lugupeetud Kasutaja,\n\nIP-lt %s on nõutud Teie salasõna lähtestamist. Palun avage allolev link, kui soovite oma parooli lähtestada.\n\n%s\n\nAnuko Time Tracker on avatud lähtekoodiga ajaarvestussüsteem. Lisainfo saamiseks külastage https://www.anuko.com lehekülge.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Kirjuta siia oma uus parool ja salvesta.', diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index 0d578b64c..0fca34586 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -456,7 +456,7 @@ // TODO: check translation of form.reset_password.email_subject. This is the subject for email message for password reset. Below is the English original. // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', 'form.reset_password.email_subject' => 'درخواست بازیابی رمزعبور فرستاده شد', -// TODO: English string has changed. "from IP added. Re-translate the beginning. +// TODO: English string has changed. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Older translation is below. // 'form.reset_password.email_body' => "کاربران گرامی\n\n یک نفر، شاید خودتان، درخواست بازیابی رمزعبور نرم افزار رهگیری زمان شما را داشته است.لطفا برای تغییر رمزعبور روی لینک زیر کلیک کنید: \n\n%s\n\n", diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 034ea6ae0..eaad8a293 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -445,7 +445,7 @@ // TODO: English string has changed. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Hyvä käyttäjä,\n\nJoku, IP %s, on pyytänyt nollaamaan Anuko Time Tracker -ohjelman salasanasi. Jos haluat nollata salasanasi, käy sivulla \n\n%s\n\nAnuko Time Tracker on yksinkertainen ja helppokäyttöinen vapaan koodin tuntiseurantaohjelmisto. Lisätietoja sivulla https://www.anuko.com.\n\n", +'form.reset_password.email_body' => "Hyvä käyttäjä,\n\nJoku, IP %s, on pyytänyt nollaamaan Anuko Time Tracker -ohjelman salasanasi. Jos haluat nollata salasanasi, käy sivulla \n\n%s\n\nAnuko Time Tracker on vapaan koodin tuntiseurantaohjelmisto. Lisätietoja sivulla https://www.anuko.com.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Syötä uusi salasana ja osoita Tallenna.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 44ba9b2bb..3d4845cc0 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -436,7 +436,7 @@ // TODO: English string has changed. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Cher utilisateur,\n\nQuelqu\'un, IP %s, avez demandé une réinitialisation de votre mot de passe. Veuillez de suivre ce lien pour le réinitialiser\n\n%s\n\nAnuko Time Tracker est un système de gestion du temps, open source, simple et facile à utiliser. Visitez https://www.anuko.com pour plus d\'informations.\n\n", +'form.reset_password.email_body' => "Cher utilisateur,\n\nQuelqu\'un, IP %s, avez demandé une réinitialisation de votre mot de passe. Veuillez de suivre ce lien pour le réinitialiser\n\n%s\n\nAnuko Time Tracker est un système de gestion du temps, open source. Visitez https://www.anuko.com pour plus d\'informations.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Saisissez votre nouveau mot de passe et cliquez sur Sauvegarder.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 29404a831..61b06f6bd 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -433,7 +433,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Το αίτημα επαναφοράς κωδικού πρόσβασης αποστέλλεται μέσω ηλεκτρονικού ταχυδρομείου.', 'form.reset_password.email_subject' => 'Αίτημα επαναφοράς κωδικού Anuko Time Tracker', -'form.reset_password.email_body' => "Αγαπητέ χρήστη,\n\nΚάποιος από την IP %s ζήτησε επαναφορά του κωδικού πρόσβασης στο Anuko Time Tracker. Πατήστε στον ακόλουθο σύνδεσμο για επαναφορά του κωδικού σας.\n\n%s\n\nΤο Anuko Time Tracker είναι ένα απλό, εύχρηστο, ανοικτού κώδικα σύστημα παρακολούθησης χρόνου. Επισκεφθείτε τη διεύθυνση https://www.anuko.com για περισσότερες πληροφορίες.\n\n", +'form.reset_password.email_body' => "Αγαπητέ χρήστη,\n\nΚάποιος από την IP %s ζήτησε επαναφορά του κωδικού πρόσβασης στο Anuko Time Tracker. Πατήστε στον ακόλουθο σύνδεσμο για επαναφορά του κωδικού σας.\n\n%s\n\nΤο Anuko Time Tracker είναι ένα ανοικτού κώδικα σύστημα παρακολούθησης χρόνου. Επισκεφθείτε τη διεύθυνση https://www.anuko.com για περισσότερες πληροφορίες.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Πληκτρολογήστε νέο κωδικό πρόσβασης και κάντε κλικ στην επιλογή Αποθήκευση.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 2bc6129d9..b8459e8b7 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -460,8 +460,8 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'הבקשה לאיפוס בסיסמה נשלחה בדואר אלקטרוני.', 'form.reset_password.email_subject' => 'בקשה לאיפוס סיסמה למערכת Anuko Time Tracker', -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Older translation is below. // 'form.reset_password.email_body' => "משתמש יקר,\n\n התקבלה בקשה לאיפוס סיסמתך. נא ללחוץ על קישור זה אם ברצונך לאפס את הסיסמה.\n\n%s\n\n. Anuko Time Tracker הינה מערכת לניהול זמן פשוטה וחינמית. בקר באתרנו בכתובת https://www.anuko.com לפרטים נוספים.\n\n", diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 98a566d10..a4fe12023 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -456,7 +456,7 @@ // TODO: translate the following. // 'form.reset_password.message' => 'Password reset request sent by email.', // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index aae1528cc..07db51091 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -457,10 +457,10 @@ 'form.reset_password.message' => '送信したパスワードの初期化の要求。', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Trackerのパスワードの初期化の要求', // TODO: translate the ending of this string. -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Older translation is below. -// 'form.reset_password.email_body' => "尊敬なるお客様、\n\n誰から(多分あなた)あなたのAnuko Time Trackerのパスワードの初期化が要求されました。あなたのパスワードを初期化しようとこのリンクを押してください。\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "尊敬なるお客様、\n\n誰から(多分あなた)あなたのAnuko Time Trackerのパスワードの初期化が要求されました。あなたのパスワードを初期化しようとこのリンクを押してください。\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 6794c57e7..975719ebd 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -461,7 +461,7 @@ 'form.reset_password.message' => '송신한 암호 재설정 요청.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker 암호 재설정 요청', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 8b2e557ea..ac8431264 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -397,6 +397,8 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Het verzoek om het wachtwoord te herstellen is verzonden per email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker wachtwoord herstel verzoek', +// TODO: retranslate form.reset_password.email_body as the string has changed. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", 'form.reset_password.email_body' => "Geachte medewerker,\n\nIemand, met IP adres %s, heeft verzocht uw wachtwoord in Anuko Time Tracker te herstellen. Klik op deze link als u uw wachtwoord wil wijzigen.\n\n%s\n\nAnuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek https://www.anuko.com voor meer informatie.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 77d43637f..eb406d0f9 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -458,8 +458,8 @@ // TODO: translate the following. // 'form.reset_password.message' => 'Password reset request sent by email.', // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Kjære bruker,\n\nNoen, IP %s, bad om å få ditt Anuko Time Tracker password resatt. Vær vennlig å besøk denne lenken dersom du ønsker at passordet ditt skal resettes.\n\n%s\n\nAnuko Time Tracker er et enkelt og brukervennlig system for tidsregistrering basert på åpen kildekode. Les mer på https://www.anuko.com.\n\n", diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index b617314db..79952ff56 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -445,9 +445,9 @@ 'form.reset_password.message' => 'Instrukcje zmiany hasła zostały wysłane na adres e-mail połączony z kontem.', 'form.reset_password.email_subject' => 'Anuko Time Tracker - żądanie zmiany hasła', // TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Drogi Użytkowniku,\n\nktoś, IP %s, poprosił o zmianę hasła w aplikacji Anuko Time Tracker. Aby ustawić nowe hasło, proszę kliknąć na poniższy link lub go skopiować i otworzyć w oknie przeglądarki WWW.\n\n%s\n\nJeśli to nie Ty poprosiłeś o zmianę hasła, zignoruj tą wiadomość.\n\nAnuko Time Tracker jest prostym, łatwym w użyciu, otwartoźródłowym systemem do śledzenia czasu. Odwiedź https://www.anuko.com aby uzyskać więcej informacji.\n\n", +'form.reset_password.email_body' => "Drogi Użytkowniku,\n\nktoś, IP %s, poprosił o zmianę hasła w aplikacji Anuko Time Tracker. Aby ustawić nowe hasło, proszę kliknąć na poniższy link lub go skopiować i otworzyć w oknie przeglądarki WWW.\n\n%s\n\nJeśli to nie Ty poprosiłeś o zmianę hasła, zignoruj tą wiadomość.\n\nAnuko Time Tracker jest otwartoźródłowym systemem do śledzenia czasu. Odwiedź https://www.anuko.com aby uzyskać więcej informacji.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Wpisz nowe hasło i kliknij Zapisz.', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 95e9d1060..9f446ce5f 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -440,9 +440,9 @@ 'form.reset_password.message' => 'Pedido para resetar a senha enviado por e-mail.', 'form.reset_password.email_subject' => 'Pedido de alteração de senha no Anuko Time Tracker', // TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Prezado usuário,\n\nAlguém, IP %s, solicitou o reset da sua senha do Anuko Time Tracker. Entre nete link para resetar a sua senha.\n\n%s\n\nAnuko Time Tracker é um sistema, simples, de fácil uso, de código abertois, de rastreamento do tempo. Visite https://www.anuko.com para mais informações.\n\n", +'form.reset_password.email_body' => "Prezado usuário,\n\nAlguém, IP %s, solicitou o reset da sua senha do Anuko Time Tracker. Entre nete link para resetar a sua senha.\n\n%s\n\nAnuko Time Tracker é um sistema de código abertois, de rastreamento do tempo. Visite https://www.anuko.com para mais informações.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Entre com a nova senha e clique em Salvar.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index dd72ab4b6..b0ae4794a 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -440,7 +440,7 @@ // TODO: translate the following. // 'form.reset_password.message' => 'Password reset request sent by email.', // 'form.reset_password.email_subject' => 'Anuko Time Tracker password reset request', -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 55731aa05..2ca785263 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -459,10 +459,10 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Cererea de resetare a parolei a fost trimisa.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker - cerere de resetare a parolei', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Draga Utilizator,\n\nCineva, IP %s, a cerut resetarea parolei pentru contul Anuko Time Tracker. Te rog, viziteaza acesta legatura daca doresti sa iti resetezi parola.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Draga Utilizator,\n\nCineva, IP %s, a cerut resetarea parolei pentru contul Anuko Time Tracker. Te rog, viziteaza acesta legatura daca doresti sa iti resetezi parola.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index dd6c1e1c8..53cb89b10 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -396,7 +396,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Запрос на сброс пароля отослан по e-mail.', 'form.reset_password.email_subject' => 'Сброс пароля к Anuko Time Tracker', -'form.reset_password.email_body' => "Уважаемый пользователь,\n\nКто-то c IP %s попросил сбросить ваш пароль к системе Anuko Time Tracker. Пройдите по данной ссылке для сброса пароля.\n\n%s\n\nAnuko Time Tracker - это открытая (open source), простая и лёгкая в использовании система трекинга рабочего времени. Подробности - на сайте https://www.anuko.com.", +'form.reset_password.email_body' => "Уважаемый пользователь,\n\nКто-то c IP %s попросил сбросить ваш пароль к системе Anuko Time Tracker. Пройдите по данной ссылке для сброса пароля.\n\n%s\n\nAnuko Time Tracker - это открытая (open source) система трекинга рабочего времени. Подробности - на сайте https://www.anuko.com.", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Впечатайте новый пароль и нажмите Cохранить.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 95a025a7a..56023db5a 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -449,9 +449,9 @@ 'form.reset_password.message' => 'Žiadosť o obnovenie hesla bola odoslaná e-mailom.', 'form.reset_password.email_subject' => 'Žiadosť o obnovenie hesla do Anuko Time Tracker', // TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Vážený používateľ,\n\nniekto, IP %s, si vyžiadal obnovenie vášho hesla do Anuko Time Tracker. Prosím kliknite na nasledujúcu linku, ak si prajete obnoviť heslo.\n\n%s\n\nAnuko Time Tracker je jednoduchý a ľahko použiteľný systém na sledovanie času s otvoreným zdrojovým kódom. Navštívte https://www.anuko.com pre viac informácií.\n\n", +'form.reset_password.email_body' => "Vážený používateľ,\n\nniekto, IP %s, si vyžiadal obnovenie vášho hesla do Anuko Time Tracker. Prosím kliknite na nasledujúcu linku, ak si prajete obnoviť heslo.\n\n%s\n\nAnuko Time Tracker je systém na sledovanie času s otvoreným zdrojovým kódom. Navštívte https://www.anuko.com pre viac informácií.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Zadajte nové heslo a kliknite na Uložiť.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index eb8bd99dd..ae6ec81c3 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -432,10 +432,10 @@ 'form.reset_password.message' => 'Zahteva za razveljavitev gesla je bila poslana.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker zahteva za razveljavitev gesla', // TODO: translate the ending of this string properly. -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. "from IP" added. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Spoštovani uporabnik,\n\nNekdo, IP %s, je zahteval razveljavitev vašega Anuko Time Tracker gesla. Prosimo obiščite to povezavo, če želite razveljaviti vaše geslo.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Spoštovani uporabnik,\n\nNekdo, IP %s, je zahteval razveljavitev vašega Anuko Time Tracker gesla. Prosimo obiščite to povezavo, če želite razveljaviti vaše geslo.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index a80f0e67a..abfb0d7bd 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -444,8 +444,8 @@ // Izmena forme za lozinku. Pogledajte primer na https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Zahtev za izmenu lozinke je poslat mejlom.', 'form.reset_password.email_subject' => 'Anuko Time Tracker zahtev za izmenu lozinke', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Poštovani korisniče,\n\nneko, IP %s, ste poslali zahtev za izmenu lozinke na Anuko Time Tracker nalogu. Molimo da pratite link ako želite da izmenite lozinku.\n\n%s\n\nAnuko Time Tracker je jednostavan i lak za korišćenje za praćenje radnog vremena. Posetite nas na https://www.anuko.com za više informacija.\n\n", diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 6bae583a7..17af93fd8 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -443,8 +443,8 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Begäran om att återställa lösenordet skickades via e-post.', 'form.reset_password.email_subject' => 'Återställning av lösenord för Anuko Time Tracker begärd', -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Kära användare,\n\Någon, IP %s, begärde att ditt lösenord för Anuko Time Tracker skulle återställas. Vänligen besök den här länken ifall du vill återställa ditt lösenord.\n\n%s\n\nAnuko Time Tracker är en lättanvänd applikation byggd med öppen källkod som enkelt låter dig spåra och hålla koll på arbetstider. Besök https://www.anuko.com för mer information.\n\n", diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 3ba51a116..3b98e0a50 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -468,10 +468,10 @@ 'form.reset_password.message' => 'Parola sıfırlama talebi yollandı.', // TODO: add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko Time Tracker parola sıfırlama talebi', // TODO: translate the ending of the following. -// TODO: English string has changed. "from IP" added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Sayın Kullanıcı,\n\nBirisi, IP %s, Anuko Time Tracker parolanızın sıfırlanmasını istedi. Parolanızı sıfırlamak isterseniz lütfen bu bağlantıyı takip edin.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +'form.reset_password.email_body' => "Sayın Kullanıcı,\n\nBirisi, IP %s, Anuko Time Tracker parolanızın sıfırlanmasını istedi. Parolanızı sıfırlamak isterseniz lütfen bu bağlantıyı takip edin.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 7eb54073a..5500155fc 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -450,7 +450,7 @@ 'form.reset_password.message' => '密码重设请求已经发送。', // TODO: Add "by email" to match the English string. 'form.reset_password.email_subject' => 'Anuko时间追踪器密码重设请求', // TODO: translate the following. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. // TODO: translate the following. diff --git a/initialize.php b/initialize.php index 1f219134f..6384b0dad 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5385"); +define("APP_VERSION", "1.19.23.5386"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ad140616820e9fae649e4adeef3663ddee6e48ea Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 26 Nov 2020 19:19:45 +0000 Subject: [PATCH 198/652] Minor improvements in translation files. --- WEB-INF/resources/da.lang.php | 2 +- WEB-INF/resources/de.lang.php | 2 +- WEB-INF/resources/es.lang.php | 2 +- WEB-INF/resources/et.lang.php | 2 +- WEB-INF/resources/fr.lang.php | 2 +- WEB-INF/resources/gr.lang.php | 2 +- WEB-INF/resources/he.lang.php | 2 ++ WEB-INF/resources/hu.lang.php | 2 +- WEB-INF/resources/it.lang.php | 8 ++++---- WEB-INF/resources/ja.lang.php | 2 +- WEB-INF/resources/ko.lang.php | 2 +- WEB-INF/resources/nl.lang.php | 2 ++ WEB-INF/resources/no.lang.php | 2 +- WEB-INF/resources/pl.lang.php | 2 +- WEB-INF/resources/pt-br.lang.php | 2 +- WEB-INF/resources/pt.lang.php | 2 +- WEB-INF/resources/ro.lang.php | 2 +- WEB-INF/resources/ru.lang.php | 2 +- WEB-INF/resources/sk.lang.php | 2 +- WEB-INF/resources/sl.lang.php | 2 +- WEB-INF/resources/sr.lang.php | 2 ++ WEB-INF/resources/sv.lang.php | 2 ++ WEB-INF/resources/tr.lang.php | 2 +- WEB-INF/resources/zh-cn.lang.php | 2 +- initialize.php | 2 +- 25 files changed, 32 insertions(+), 24 deletions(-) diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index 040405503..efdacc370 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -436,7 +436,7 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Nulstilling af adgangskode er sendt på email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker - Anmodning om nulstilling af adgangskode', -// TODO: English string has changed. "from IP added. Re-translate the beginning. +// TODO: English string has changed. Re-translate the beginning. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Hej\n\nNogen, IP %s, har bedt om at få nulstillet din adgangskode. Tryk på linket hvis du vil have nulstillet din adgangskode.\n\n%s\n\nAnuko Time Tracker er et open source tidsregistrerings system. Besøg https://www.anuko.com for mere information.\n\n", diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index 13626d9e6..e41d92b09 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -580,7 +580,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'An', 'form.mail.report_subject' => 'Time Tracker Bericht', -'form.mail.footer' => 'Anuko Time Tracker ist ein einfaches, leicht zu bedienendes, Open-Source
Zeitverwaltungs-System. Besuchen Sie www.anuko.com für weitere Informationen.', +'form.mail.footer' => 'Anuko Time Tracker ist ein Open-Source
Zeitverwaltungs-System. Besuchen Sie www.anuko.com für weitere Informationen.', 'form.mail.report_sent' => 'Der Bericht wurde gesendet.', 'form.mail.invoice_sent' => 'Die Rechnung wurde gesendet.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 05c24948c..9df814845 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -461,7 +461,7 @@ 'form.reset_password.message' => 'Se ha enviado la petición de reestablecer contraseña.', 'form.reset_password.email_subject' => 'Solicitud de reestablecimiento de la contraseña de Anuko Time Tracker', // Note to translators: the ending of this string needs to be translated. -// TODO: English string has changed. "from IP added. Re-translate. +// TODO: English string has changed. Re-translate. // 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. 'form.reset_password.email_body' => "Querido usuario, Alguien, IP %s, solicitó reestablecer su contraseña de Anuko Time Tracker. Por favor visite este enlace si quiere reestablecer su contraseña.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index d938cf079..7638ade63 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -610,7 +610,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Kellele', 'form.mail.report_subject' => 'Time Tracker raport', -'form.mail.footer' => 'Anuko Time Tracker on lihtne, lihtsalt kasutatav ja avatud lähtekoodiga
ajaarvestussüsteem. Lisainfo saamiseks külastage www.anuko.com lehekülge.', +'form.mail.footer' => 'Anuko Time Tracker on avatud lähtekoodiga
ajaarvestussüsteem. Lisainfo saamiseks külastage www.anuko.com lehekülge.', 'form.mail.report_sent' => 'Raport on saadetud.', 'form.mail.invoice_sent' => 'Arve on saadetud.', diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 3d4845cc0..771ed18e3 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -598,7 +598,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'À', 'form.mail.report_subject' => 'Rapport Time Tracker', -'form.mail.footer' => 'Anuko Time Tracker est un système de gestion du temps, open source, simple et facile à utiliser. Visitez www.anuko.com pour plus d\\\'informations.', +'form.mail.footer' => 'Anuko Time Tracker est un système de gestion du temps, open source. Visitez www.anuko.com pour plus d\\\'informations.', 'form.mail.report_sent' => 'Le rapport a été envoyé.', 'form.mail.invoice_sent' => 'La facture a été envoyée.', diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 61b06f6bd..e9003045c 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -590,7 +590,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Προς', 'form.mail.report_subject' => 'Time Tracker αναφορά', -'form.mail.footer' => 'Το Anuko Time Tracker είναι ένα απλό, εύχρηστο, ανοικτού κώδικα σύστημα παρακολούθησης χρόνου. Επισκεφθείτε τη διεύθυνση www.anuko.com για περισσότερες πληροφορίες.', +'form.mail.footer' => 'Το Anuko Time Tracker είναι ένα ανοικτού κώδικα σύστημα παρακολούθησης χρόνου. Επισκεφθείτε τη διεύθυνση www.anuko.com για περισσότερες πληροφορίες.', 'form.mail.report_sent' => 'Η αναφορά στάλθηκε.', 'form.mail.invoice_sent' => 'Το τιμολόγιο στάλθηκε.', diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index b8459e8b7..032e01bf0 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -628,6 +628,8 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'אל', 'form.mail.report_subject' => 'דוח Time Tracker', +// TODO: retranslate form.mail.footer as the English string has changed. +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.footer' => 'Anuko Time Tracker הינה מערכת פשוטה, קלה לשימוש וחינמית לניהול זמן. בקר באתר www.anuko.com לפרטים נוספים.', 'form.mail.report_sent' => 'הדוח נשלח.', 'form.mail.invoice_sent' => 'החשבונית נשלחה.', diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index a4fe12023..1909682fb 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -630,7 +630,7 @@ 'form.mail.to' => 'Címzett', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'A számla elküldve.', diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 1b7f56e46..35035d3e9 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -443,10 +443,10 @@ // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Richiesta di reset password inviata via mail.', 'form.reset_password.email_subject' => 'Richiesta reset password per Anuko Time Tracker', -// TODO: English string has changed. "from IP added. Re-translate the beginning. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is a simple, easy to use, open source time tracking system. Visit https://www.anuko.com for more information.\n\n", +// TODO: English string has changed. Re-translate the beginning. +// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", // "IP %s" probably sounds awkward. -'form.reset_password.email_body' => "Caro utente,\n\n qualcuno, IP %s, ha richiesto di reimpostare la tua password per Anuko Time Tracker. Per favore visita questo link per reimpostare la tua password.\n\n%s\n\nAnuko Time Tracker è un sistema semplice e open source per registrare i tempi di lavoro. Visita https://www.anuko.com per maggiori informazioni.\n\n", +'form.reset_password.email_body' => "Caro utente,\n\n qualcuno, IP %s, ha richiesto di reimpostare la tua password per Anuko Time Tracker. Per favore visita questo link per reimpostare la tua password.\n\n%s\n\nAnuko Time Tracker è un sistema open source per registrare i tempi di lavoro. Visita https://www.anuko.com per maggiori informazioni.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Digita una nuova password e clicca su Salva.', @@ -605,7 +605,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'A', 'form.mail.report_subject' => 'Rapporto Time Tracker', -'form.mail.footer' => 'Anuko Time Tracker è un sistema semplice e open source
per registrare i tempi di lavoro. Visita www.anuko.com per maggiori informazioni.', +'form.mail.footer' => 'Anuko Time Tracker è un sistema open source
per registrare i tempi di lavoro. Visita www.anuko.com per maggiori informazioni.', 'form.mail.report_sent' => 'Rapporto inviato.', 'form.mail.invoice_sent' => 'Fattura inviata.', diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 07db51091..0ba848ba0 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -633,7 +633,7 @@ 'form.mail.to' => 'まで', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '送信した送り状。', diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 975719ebd..975e42169 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -631,7 +631,7 @@ 'form.mail.to' => '까지', // TODO: is this correct? The meaning is that we send an email TO this person. // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '송신한 송장.', diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index ac8431264..6d51082c7 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -546,6 +546,8 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Aan', 'form.mail.report_subject' => 'Time Tracker rapport', +// TODO: retranslate form.mail.footer as the English string has changed. +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.footer' => 'Anuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek www.anuko.com voor meer informatie.', 'form.mail.report_sent' => 'Rapport is verzonden.', 'form.mail.invoice_sent' => 'Factuur is verzonden.', diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index eb406d0f9..cfaf305b5 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -632,7 +632,7 @@ 'form.mail.to' => 'Til', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', // 'form.mail.invoice_sent' => 'Invoice sent.', diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 79952ff56..24664d693 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -610,7 +610,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Do', 'form.mail.report_subject' => 'Raport Time Tracker', -'form.mail.footer' => 'Anuko Time Tracker jest prostym, łatwym w użyciu, otwartoźródłowym
systemem śledzenia czasu. Odwiedź www.anuko.com, aby uzyskać więcej informacji.', +'form.mail.footer' => 'Anuko Time Tracker jest otwartoźródłowym
systemem śledzenia czasu. Odwiedź www.anuko.com, aby uzyskać więcej informacji.', 'form.mail.report_sent' => 'Wysłano raport', 'form.mail.invoice_sent' => 'Wysłano fakturę', diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 9f446ce5f..e41cf26c3 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -605,7 +605,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Para', 'form.mail.report_subject' => 'Relatório do Time Tracker', -'form.mail.footer' => 'Anuko Time Tracker é um sistema, simples, de fácil uso, de código aberto,
de rastreamento do tempo. Visite www.anuko.com para mais informações.', +'form.mail.footer' => 'Anuko Time Tracker é um sistema de código aberto,
de rastreamento do tempo. Visite www.anuko.com para mais informações.', 'form.mail.report_sent' => 'Relatório enviado.', 'form.mail.invoice_sent' => 'Fatura enviada.', diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index b0ae4794a..13912a44d 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -612,7 +612,7 @@ 'form.mail.to' => 'Para', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', // 'form.mail.invoice_sent' => 'Invoice sent.', diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index 2ca785263..0c531ad11 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -633,7 +633,7 @@ 'form.mail.to' => 'Catre', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Factura trimisa.', diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 53cb89b10..835b90048 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -543,7 +543,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Кому', 'form.mail.report_subject' => 'Time Tracker отчёт', -'form.mail.footer' => 'Anuko Time Tracker - это открытая (open source), простая и лёгкая в использовании система трекинга рабочего времени. Подробности на сайте www.anuko.com.', +'form.mail.footer' => 'Anuko Time Tracker - это открытая (open source) система трекинга рабочего времени. Подробности на сайте www.anuko.com.', 'form.mail.report_sent' => 'Отчёт отправлен.', 'form.mail.invoice_sent' => 'Счёт отправлен.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index 56023db5a..57c14a7db 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -615,7 +615,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Komu', 'form.mail.report_subject' => 'Time Tracker zostava', -'form.mail.footer' => 'Anuko Time Tracker je jednoduchý a ľahko použiteľný systém na sledovanie času s otvoreným zdrojovým kódom.
Navštívte www.anuko.com pre viac informácií.', +'form.mail.footer' => 'Anuko Time Tracker je systém na sledovanie času s otvoreným zdrojovým kódom.
Navštívte www.anuko.com pre viac informácií.', 'form.mail.report_sent' => 'Zostava odoslaná.', 'form.mail.invoice_sent' => 'Faktúra odoslaná.', diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index ae6ec81c3..32e200f81 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -606,7 +606,7 @@ 'form.mail.to' => 'Za', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', // 'form.mail.invoice_sent' => 'Invoice sent.', diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index abfb0d7bd..38cf8565b 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -610,6 +610,8 @@ // Forma mejla. Pogledajte primer na https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Za', 'form.mail.report_subject' => 'Evidencija vremena', +// TODO: retranslate form.mail.footer as the English string has changed. +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.footer' => 'Anuko Time Tracker je jednostavan i lak za korišćenje za praćenje
radnog vremena. Posetite www.anuko.com za više informacija.', 'form.mail.report_sent' => 'Izveštaj poslat.', 'form.mail.invoice_sent' => 'Račun poslat.', diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 17af93fd8..fe05e89a7 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -609,6 +609,8 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Till', 'form.mail.report_subject' => 'Tidsrapport', +// TODO: retranslate form.mail.footer as the English string has changed. +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', 'form.mail.footer' => 'Anuko Time Tracker är en lättanvänd applikation byggd med öppen källkod för att enkelt spåra och hålla koll på arbetstider. Besök www.anuko.com för mer information.', 'form.mail.report_sent' => 'Rapporten skickades.', 'form.mail.invoice_sent' => 'Fakturan skickades.', diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index 3b98e0a50..777440e88 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -646,7 +646,7 @@ 'form.mail.to' => 'Kime', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => 'Fatura yollandı.', diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 5500155fc..01e639bdd 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -620,7 +620,7 @@ 'form.mail.to' => '到', // TODO: translate the following. // 'form.mail.report_subject' => 'Time Tracker Report', -// 'form.mail.footer' => 'Anuko Time Tracker is a simple, easy to use, open source
time tracking system. Visit www.anuko.com for more information.', +// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', // 'form.mail.report_sent' => 'Report sent.', 'form.mail.invoice_sent' => '发票已送出。', diff --git a/initialize.php b/initialize.php index 6384b0dad..52148e8b1 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5386"); +define("APP_VERSION", "1.19.23.5387"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 0ac7c8645b11b61d51a1da55685112c8ba7d97b5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 15:29:40 +0000 Subject: [PATCH 199/652] Added separators on some forms to improve UI. --- WEB-INF/templates/client_add2.tpl | 1 + WEB-INF/templates/client_edit2.tpl | 1 + WEB-INF/templates/project_add2.tpl | 2 ++ WEB-INF/templates/project_edit2.tpl | 2 ++ WEB-INF/templates/task_add2.tpl | 1 + WEB-INF/templates/task_edit2.tpl | 1 + initialize.php | 2 +- 7 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/client_add2.tpl b/WEB-INF/templates/client_add2.tpl index 5fe001b23..2704a133c 100644 --- a/WEB-INF/templates/client_add2.tpl +++ b/WEB-INF/templates/client_add2.tpl @@ -24,6 +24,7 @@ License: See license.txt *}
{if $show_projects} + diff --git a/WEB-INF/templates/client_edit2.tpl b/WEB-INF/templates/client_edit2.tpl index 91f2b1c39..67b79ecdf 100644 --- a/WEB-INF/templates/client_edit2.tpl +++ b/WEB-INF/templates/client_edit2.tpl @@ -30,6 +30,7 @@ License: See license.txt *} {if $show_projects} + diff --git a/WEB-INF/templates/project_add2.tpl b/WEB-INF/templates/project_add2.tpl index 4f2c14286..cd900cf36 100644 --- a/WEB-INF/templates/project_add2.tpl +++ b/WEB-INF/templates/project_add2.tpl @@ -24,6 +24,7 @@ License: See license.txt *} {/if} {if $show_users} + @@ -32,6 +33,7 @@ License: See license.txt *} {/if} {if $show_tasks} + diff --git a/WEB-INF/templates/project_edit2.tpl b/WEB-INF/templates/project_edit2.tpl index 8ce9ae9c7..f7b23a9ac 100644 --- a/WEB-INF/templates/project_edit2.tpl +++ b/WEB-INF/templates/project_edit2.tpl @@ -22,6 +22,7 @@ License: See license.txt *} {if $show_users} + @@ -30,6 +31,7 @@ License: See license.txt *} {/if} {if $show_tasks} + diff --git a/WEB-INF/templates/task_add2.tpl b/WEB-INF/templates/task_add2.tpl index 534c9525e..1b1c4e42e 100644 --- a/WEB-INF/templates/task_add2.tpl +++ b/WEB-INF/templates/task_add2.tpl @@ -16,6 +16,7 @@ License: See license.txt *} {if $show_projects} + diff --git a/WEB-INF/templates/task_edit2.tpl b/WEB-INF/templates/task_edit2.tpl index e66a93e10..9292ad151 100644 --- a/WEB-INF/templates/task_edit2.tpl +++ b/WEB-INF/templates/task_edit2.tpl @@ -22,6 +22,7 @@ License: See license.txt *} {if $show_projects} + diff --git a/initialize.php b/initialize.php index 52148e8b1..2d5f9964d 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5387"); +define("APP_VERSION", "1.19.23.5388"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1a9ec2adbc3adb32a857f2300ade94da1af8a37f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 16:19:46 +0000 Subject: [PATCH 200/652] Styles client address field. --- default.css | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/default.css b/default.css index 820382bdf..40d085f01 100644 --- a/default.css +++ b/default.css @@ -243,14 +243,14 @@ input[type="file"] { width: 237px; } -#description { +#description, #address { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; padding: .4rem; } -#description:focus { +#description:focus, #address:focus { background-color: yellow; border: 1px solid black; outline: none; diff --git a/initialize.php b/initialize.php index 2d5f9964d..472e4f37f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5388"); +define("APP_VERSION", "1.19.23.5389"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 706fa5628098a513ab667ed8f3261e89310ad3b1 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 16:25:15 +0000 Subject: [PATCH 201/652] Styled item_name field for expenses. --- default.css | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/default.css b/default.css index 40d085f01..fea2e8da5 100644 --- a/default.css +++ b/default.css @@ -243,14 +243,14 @@ input[type="file"] { width: 237px; } -#description, #address { +#description, #address, #item_name { width: 220px; border-radius: 4px; border: 1px solid #c9c9c9; padding: .4rem; } -#description:focus, #address:focus { +#description:focus, #address:focus, #item_name:focus { background-color: yellow; border: 1px solid black; outline: none; diff --git a/initialize.php b/initialize.php index 472e4f37f..837759f2b 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5389"); +define("APP_VERSION", "1.19.23.5390"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From fef326c0478e77feff6a5b14dad4450b172e8017 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 16:58:05 +0000 Subject: [PATCH 202/652] Improved x-scrollable-table styles to alternate rows background. --- WEB-INF/templates/entity_files2.tpl | 3 ++- default.css | 6 ++++-- initialize.php | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/WEB-INF/templates/entity_files2.tpl b/WEB-INF/templates/entity_files2.tpl index d6b892b38..07a46443d 100644 --- a/WEB-INF/templates/entity_files2.tpl +++ b/WEB-INF/templates/entity_files2.tpl @@ -23,6 +23,7 @@ License: See license.txt *} {/if} {if $can_edit} +
{$forms.fileUploadForm.open}
 Anuko Time Tracker 1.19.18.5218 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5219 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 837ef05b3..55d047caa 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -1,3 +1,4 @@ + diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index ec0b05926..054c75363 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -1,3 +1,4 @@ + From 07c9f1d30e074481292412cda209f1516550ec1e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 15:28:35 +0000 Subject: [PATCH 005/652] Starting refactoring Calendar.class.php. --- WEB-INF/lib/form/Calendar.class.php | 8 +------- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 74f52895d..61b393cba 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -31,9 +31,7 @@ import('ttTimeHelper'); class Calendar extends FormElement { - var $holidays = array(); - var $showHolidays = true; - var $weekStartDay = 0; + var $weekStartDay = 0; // Defaults to Sunday. var $mHeader = "padding: 5px; font-size: 8pt; color: #333333; background-color: #d9d9d9;"; var $mDayCell = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #333333; background-color: #ffffff;"; @@ -72,10 +70,6 @@ function setCellStyle($style) { $this->mCellStyle = $style; } function setACellStyle($style) { $this->mACellStyle = $style; } function setLinkStyle($style) { $this->mLinkStyle = $style; } - function setShowHolidays($value) { - $this->showHolidays = $value; - } - /** * @return void * @param date diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0390d8a25..2278dd082 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {/if} - + - +
Anuko Time Tracker 1.19.18.5219 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5220 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 20156f595b5b9716fa7e7ab4789ba838e52f1192 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 15:53:33 +0000 Subject: [PATCH 006/652] Work in progress moving styles out of Calendar class into css file. --- WEB-INF/lib/form/Calendar.class.php | 12 +++--------- WEB-INF/templates/footer.tpl | 2 +- default.css | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index 61b393cba..8ce99cc7e 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -33,9 +33,6 @@ class Calendar extends FormElement { var $weekStartDay = 0; // Defaults to Sunday. - var $mHeader = "padding: 5px; font-size: 8pt; color: #333333; background-color: #d9d9d9;"; - var $mDayCell = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #333333; background-color: #ffffff;"; - var $mDaySelected = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #666666; background-color: #a6ccf7;"; var $mDayWeekend = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #666666; background-color: #f7f7f7;"; var $mDayHoliday = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #666666; background-color: #f7f7f7;"; var $mDayHeader = "padding: 5px; border: 1px solid white; font-size: 8pt; color: #333333;"; @@ -106,7 +103,7 @@ function toString($date="") { $str = $this->_genStyles(); $str .= ' - {/if} - + - +
'. +
'. //'<< '. '<<< '. $this->mMonthNames[$thismonth-1].' '.$thisyear. @@ -159,7 +156,7 @@ function toString($date="") { $stl_cell = ' class="CalendarDayWeekend"'; $stl_link = ' class="CalendarLinkWeekend"'; } else { - $stl_cell = ' class="CalendarDay"'; + $stl_cell = ' class="calendarDay"'; } // holidays @@ -171,7 +168,7 @@ function toString($date="") { // selected day if ( $indate == strftime(DB_DATEFORMAT, $date)) - $stl_cell = ' class="CalendarDaySelected"'; + $stl_cell = ' class="calendarDaySelected"'; $str .= ''; @@ -238,9 +235,6 @@ function _getWeekDayBefore($year, $month) { function _genStyles() { $str = "\n"; - return $str; - } - // _getActiveDates returns an array of dates, for which entries exist for user. // Type of entries (time or expenses) is determined by $this->highlight value. function _getActiveDates($start, $end) { diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 2f8b120bf..369e61911 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- @@ -129,14 +120,14 @@ function toString($date="") { $str .= "\n"; - list($wkstart,$monthstart,$monthend,$start_date) = $this->_getWeekDayBefore( $thisyear, $thismonth ); + list($wkstart,$monthstart,$monthend,$start_date) = $this->_getWeekDayBefore( $selectedYear, $selectedMonth ); $active_dates = $this->_getActiveDates($monthstart, $monthend); - for ( $i = $wkstart; $i<=$monthend; $i=mktime(0,0,0,$thismonth,$start_date+=7,$thisyear) ) { + for ( $i = $wkstart; $i<=$monthend; $i=mktime(0,0,0,$selectedMonth,$start_date+=7,$selectedYear) ) { $str .= "\n"; for ( $j = 0; $j < 7; $j++ ) { - $date = mktime(0,0,0,$thismonth,$start_date+$j,$thisyear); + $date = mktime(0,0,0,$selectedMonth,$start_date+$j,$selectedYear); if (($date >= $monthstart) && ($date <= $monthend)) { $stl_cell = ""; @@ -151,14 +142,14 @@ function toString($date="") { } // holidays - $date_to_check = ttTimeHelper::dateInDatabaseFormat($thisyear, $thismonth, $start_date+$j); + $date_to_check = ttTimeHelper::dateInDatabaseFormat($selectedYear, $selectedMonth, $start_date+$j); if (ttTimeHelper::isHoliday($date_to_check)) { $stl_cell = ' class="calendarDayHoliday"'; $stl_link = ' class="calendarLinkHoliday"'; } // selected day - if ( $indate == strftime(DB_DATEFORMAT, $date)) + if ( $selectedDate == strftime(DB_DATEFORMAT, $date)) $stl_cell = ' class="calendarDaySelected"'; @@ -196,7 +187,7 @@ function toString($date="") { $str .= "\n"; $str .= "
Anuko Time Tracker 1.19.18.5222 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5223 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/default.css b/default.css index 7f138ed38..3eac29ec2 100644 --- a/default.css +++ b/default.css @@ -133,6 +133,22 @@ input[type=checkbox], label { font-size: 8pt; color: #999999; } + +.calendarLinkWeekend { + color: #999999; +} + +.calendarLinkHoliday { + color: #999999; +} + +.calendarLinkRecordsExist { + color: #ff0000; +} + +.calendarLinkNonCompleteDay { + color: #800080; +} /* end of calendar styles */ .tableHeader { From 8dd1f536714f1bc6f09d2176dc84871d33ab94a3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 11 Jul 2020 17:18:16 +0000 Subject: [PATCH 009/652] Some more refactoring in Calendar class. --- WEB-INF/lib/form/Calendar.class.php | 57 +++++++++++------------------ WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index e7db6bcfd..dee9fbc0c 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -58,37 +58,28 @@ function localize() { $this->weekStartDay = $user->getWeekStart(); } - // TODO: refactoring ongoing down from here... - - /** - * @return void - * @param date - * @desc Enter description here... - */ - function toString($date="") { - global $i18n; - - $indate = $this->value; - if (!$indate) $indate = strftime(DB_DATEFORMAT); - - //current year and month - if ( strlen ( $indate ) > 0 ) { - $indateObj = new DateAndTime(DB_DATEFORMAT, $indate); - $thismonth = $indateObj->getMonth(); - $thisyear = $indateObj->getYear(); - } else { - $thismonth = date("m"); - $thisyear = date("Y"); - } + // Generates html code for Calendar control. + function getHtml() { + global $i18n; // Needed to print Today. + + $selectedDate = $this->value; + if (!$selectedDate) $selectedDate = strftime(DB_DATEFORMAT); + + // Determine month and year for selected date. + $selectedDateObject = new DateAndTime(DB_DATEFORMAT, $selectedDate); + $selectedMonth = $selectedDateObject->getMonth(); + $selectedYear = $selectedDateObject->getYear(); + + // TODO: refactoring ongoing down from here... // next date, month, year - $next = mktime ( 2, 0, 0, $thismonth + 1, 1, $thisyear ); + $next = mktime ( 2, 0, 0, $selectedMonth + 1, 1, $selectedYear ); $nextyear = date ( "Y", $next ); $nextmonth = date ( "m", $next ); $nextdate = strftime (DB_DATEFORMAT, $next ); // prev date, month, year - $prev = mktime ( 2, 0, 0, $thismonth - 1, 1, $thisyear ); + $prev = mktime ( 2, 0, 0, $selectedMonth - 1, 1, $selectedYear ); $prevyear = date ( "Y", $prev ); $prevmonth = date ( "m", $prev ); $prevdate = strftime(DB_DATEFORMAT, $prev ); @@ -97,7 +88,7 @@ function toString($date="") {
'. //'<< '. '<<< '. - $this->monthNames[$thismonth-1].' '.$thisyear. + $this->monthNames[$selectedMonth-1].' '.$selectedYear. ' >>>'. //' >>'. '
name."=".strftime(DB_DATEFORMAT)."\" tabindex=\"-1\">".$i18n->get('label.today')."
\n"; - $str .= "name\" value=\"$indate\">\n"; + $str .= "name\" value=\"$selectedDate\">\n"; // Add script to adjust today link to match browser today, as PHP may run in a different timezone. $str .= "\n"; - - return $str; - } + // Add a hidden control for selected date. + $html .= "name\" value=\"$selectedDate\">\n"; - function _getWeekDayBefore($year, $month) { - $weekday = date ( "w", mktime ( 2, 0, 0, $month, 1 - $this->weekStartDay, $year ) ); - return array( - mktime ( 0, 0, 0, $month, 1 - $weekday, $year ), - mktime ( 0, 0, 0, $month, 1, $year ), - mktime ( 0, 0, 0, $month + 1, 0, $year ), - (1 - $weekday) - ); - } + // Add script to adjust today link to match browser today, as PHP may run in a different timezone. + $html .= "\n"; + + $html .= "\n\n\n\n\n\n\n"; + return $html; + } - // _getActiveDates returns an array of dates, for which entries exist for user. - // Type of entries (time or expenses) is determined by $this->highlight value. - function _getActiveDates($start, $end) { + // getActiveDates returns an array of dates, for which entries exist for user. + // Type of entries (time or expenses) is determined by $this->highlight value. + function getActiveDates($start, $end) { - global $user; - $user_id = $user->getUser(); + global $user; + $user_id = $user->getUser(); - $table = ($this->highlight == 'expenses') ? 'tt_expense_items' : 'tt_log'; + $table = ($this->highlight == 'expenses') ? 'tt_expense_items' : 'tt_log'; - $mdb2 = getConnection(); - - $start_date = date("Y-m-d", $start); - $end_date = date("Y-m-d", $end); - $sql = "SELECT date FROM $table WHERE date >= '$start_date' AND date <= '$end_date' AND user_id = $user_id AND status = 1"; - $res = $mdb2->query($sql); - if (!is_a($res, 'PEAR_Error')) { - while ($row = $res->fetchRow()) { - $out[] = date('Y-m-d', strtotime($row['date'])); - } - return @$out; + $mdb2 = getConnection(); + + $start_date = date("Y-m-d", $start); + $end_date = date("Y-m-d", $end); + $sql = "SELECT date FROM $table WHERE date >= '$start_date' AND date <= '$end_date' AND user_id = $user_id AND status = 1"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($row = $res->fetchRow()) { + $out[] = date('Y-m-d', strtotime($row['date'])); } - else - return false; + return @$out; } + else + return false; + } } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 7e4eb8f09..d6e3c31ac 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + + {/foreach}
Anuko Time Tracker 1.19.18.5225 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5226 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 6c7355065a9e027cc82979e6ea54c62a598a03a9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 12 Jul 2020 16:49:19 +0000 Subject: [PATCH 012/652] Cosmetic. --- WEB-INF/lib/form/Calendar.class.php | 6 +++--- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index e3bf05924..e80f87380 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -134,7 +134,7 @@ function getHtml() { // Iterate through week days. for ($j = 0; $j < 7; $j++) { $cellDate0am = mktime(0, 0, 0, $selectedMonth, $startDayIdx + $j, $selectedYear); - if (($cellDate0am >= $firstDayOfSelectedMonth0am) && ($cellDate0am <= $lastDayOfSelectedMonth0am)) { + if ($cellDate0am >= $firstDayOfSelectedMonth0am && $cellDate0am <= $lastDayOfSelectedMonth0am) { $cell_style = ""; $link_style = ""; @@ -157,9 +157,9 @@ function getHtml() { $cell_style = ' class="calendarDaySelected"'; $html .= ''; - if($active_dates) { + if ($active_dates) { // Entries exist. - if( in_array(strftime(DB_DATEFORMAT, $cellDate0am), $active_dates) ){ + if (in_array(strftime(DB_DATEFORMAT, $cellDate0am), $active_dates)) { // TODO: add a config option to eliminate these call for users not wanting this feature. $day_total_minutes = ttTimeHelper::toMinutes(ttTimeHelper::getTimeForDay($date_to_check)); // Check if entries total to a complete work day. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d6e3c31ac..9e70ecb45 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + + + + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9e70ecb45..3e158c480 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.18.5226 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5227 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 447afd69ce1a81cfaa2d17de1d050e418ffb68f2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 12 Jul 2020 18:52:07 +0000 Subject: [PATCH 013/652] Added a config option whether to show not complete days in calendar. --- WEB-INF/lib/form/Calendar.class.php | 19 +++-- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 2 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 2 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/display_options.tpl | 4 + WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/test.tpl | 17 +++++ display_options.php | 4 + test.php | 106 ++++++++++++++++++++++++++ 36 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 WEB-INF/templates/test.tpl create mode 100644 test.php diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index e80f87380..b624a8da2 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -126,6 +126,8 @@ function getHtml() { // Determine active dates where entries exist for user. $active_dates = $this->getActiveDates($firstDayOfSelectedMonth0am, $lastDayOfSelectedMonth0am); + $handleHolidays = $user->getHolidays() != null; + $handleNotCompleteDays = $user->isOptionEnabled('time_not_complete_days'); $workday_minutes = $user->getWorkdayMinutes(); // Print calendar cells one week row at a time. @@ -147,7 +149,7 @@ function getHtml() { // Handle holidays. $date_to_check = ttTimeHelper::dateInDatabaseFormat($selectedYear, $selectedMonth, $startDayIdx+$j); - if (ttTimeHelper::isHoliday($date_to_check)) { + if ($handleHolidays && ttTimeHelper::isHoliday($date_to_check)) { $cell_style = ' class="calendarDayHoliday"'; $link_style = ' class="calendarLinkHoliday"'; } @@ -157,16 +159,19 @@ function getHtml() { $cell_style = ' class="calendarDaySelected"'; $html .= ''; + // Handle days with existing entries. if ($active_dates) { // Entries exist. if (in_array(strftime(DB_DATEFORMAT, $cellDate0am), $active_dates)) { - // TODO: add a config option to eliminate these call for users not wanting this feature. - $day_total_minutes = ttTimeHelper::toMinutes(ttTimeHelper::getTimeForDay($date_to_check)); - // Check if entries total to a complete work day. - if ($day_total_minutes >= $workday_minutes) - $link_style = ' class="calendarLinkRecordsExist"'; + if ($handleNotCompleteDays && $this->highlight == 'time') { + $day_total_minutes = ttTimeHelper::toMinutes(ttTimeHelper::getTimeForDay($date_to_check)); + if ($day_total_minutes >= $workday_minutes) + $link_style = ' class="calendarLinkRecordsExist"'; + else + $link_style = ' class="calendarLinkNonCompleteDay"'; + } else - $link_style = ' class="calendarLinkNonCompleteDay"'; + $link_style = ' class="calendarLinkRecordsExist"'; } } $html .= "name."=".strftime(DB_DATEFORMAT, $cellDate0am)."\" tabindex=\"-1\">".date("d",$cellDate0am).""; diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 9893ad523..5260ecc1d 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -706,6 +706,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 59756d1b5..2ae8ed511 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -719,6 +719,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index a8a14b53d..f15a08b09 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -681,6 +681,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index a8f1d165a..fa0407b8f 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -657,6 +657,8 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Beschreibung in separater Zeile', +// TODO: translate the following. +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index 2beefaa1c..c96415300 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -637,6 +637,7 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Note on separate row', +'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Work item is not available.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index 1cf3ce768..fe77bf299 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -721,6 +721,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 5e2e78caa..9dc067415 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -688,6 +688,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index e078a0a34..a9a1d76f0 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -705,6 +705,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 575dc04f6..6e1787474 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -687,6 +687,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index 5fe0f76d7..a4a9a74f7 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -677,6 +677,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 5d0dd6bde..8137dbd58 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -670,6 +670,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 199e26533..5010087a8 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -706,6 +706,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index a4a4dd005..683636a67 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -711,6 +711,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index b10575302..4d3540592 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -684,6 +684,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index 8ebec5955..cfbeca196 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -714,6 +714,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 76c159472..2ed5c1bfc 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -712,6 +712,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 06f764d4c..6d815c746 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -640,6 +640,8 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', +// TODO: translate the following. +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index ad95bd7e3..8afcf5c17 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -711,6 +711,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index f988df4a4..4dbf608fe 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -690,6 +690,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index 5c9d89a32..cca28d179 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -685,6 +685,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 3043e8bba..57db2d012 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -693,6 +693,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index add70a4ea..eab6eb7a5 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -714,6 +714,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index fb050a1a0..1050013e0 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -618,6 +618,7 @@ // Display Options form. See example at https://timetracker.anuko.com/display_options.php. 'form.display_options.menu' => 'Меню', 'form.display_options.note_on_separate_row' => 'Комментарий в отдельном ряду', +'form.display_options.not_complete_days' => 'Незавершенные дни', // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Работа отсутствует.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index cf0b8432b..e0ae714fc 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -695,6 +695,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index f4aa21b58..0dd6f7206 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -687,6 +687,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index be5739b6e..b7b93ffbd 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -688,6 +688,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 43b0d92b6..24797672a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -686,6 +686,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index e241cace8..c2f30dfbb 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -727,6 +727,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index b1d81418b..9cbb47534 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -698,6 +698,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 05615586d..774b8024a 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -704,6 +704,7 @@ // TODO: translate the following. // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', +// 'form.display_options.not_complete_days' => 'Not complete days', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index d7bbdd57d..918a48f9e 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -5,6 +5,10 @@
{$forms.displayOptionsForm.time_note_on_separate_row.control} {$i18n.label.what_is_it}
{$forms.displayOptionsForm.time_not_complete_days.control} {$i18n.label.what_is_it}
- {/if} {if $u.group_id != $user->group_id || $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} - - {if $u.id != $user->id}{else}{/if} + + {if $u.id != $user->id}{else}{/if} {else} @@ -76,8 +76,8 @@ {/if} {if $u.group_id != $user->group_id || $u.rank < $user->rank} - - + + {else} diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl index 5ac3be85e..9d3ef0bf2 100644 --- a/WEB-INF/templates/week.tpl +++ b/WEB-INF/templates/week.tpl @@ -149,23 +149,23 @@ function fillDropdowns() { {if $show_files} {if $record.has_files} - + {else} - + {/if} {/if} diff --git a/WEB-INF/templates/work/admin_work.tpl b/WEB-INF/templates/work/admin_work.tpl index 39050ab3e..929b4d619 100644 --- a/WEB-INF/templates/work/admin_work.tpl +++ b/WEB-INF/templates/work/admin_work.tpl @@ -22,8 +22,8 @@ - - + + {/foreach}
Anuko Time Tracker 1.19.18.5227 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5228 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/test.tpl b/WEB-INF/templates/test.tpl new file mode 100644 index 000000000..325d686bc --- /dev/null +++ b/WEB-INF/templates/test.tpl @@ -0,0 +1,17 @@ + + +{$forms.timeRecordForm.open} + + + + +
+ + +
{$forms.timeRecordForm.date.control}
+
+{$forms.timeRecordForm.close} diff --git a/display_options.php b/display_options.php index d65f15ab3..7dd724d44 100644 --- a/display_options.php +++ b/display_options.php @@ -41,9 +41,11 @@ if ($request->isPost()) { $cl_time_note_on_separate_row = $request->getParameter('time_note_on_separate_row'); + $cl_time_not_complete_days = $request->getParameter('time_not_complete_days'); $cl_report_note_on_separate_row = $request->getParameter('report_note_on_separate_row'); } else { $cl_time_note_on_separate_row = $config->getDefinedValue('time_note_on_separate_row'); + $cl_time_not_complete_days = $config->getDefinedValue('time_not_complete_days'); $cl_report_note_on_separate_row = $config->getDefinedValue('report_note_on_separate_row'); } @@ -58,6 +60,7 @@ // $form->addInput(array('type'=>'checkbox','name'=>'time_duration','value'=>$cl_time_duration)); // $form->addInput(array('type'=>'checkbox','name'=>'time_note','value'=>$cl_time_note)); $form->addInput(array('type'=>'checkbox','name'=>'time_note_on_separate_row','value'=>$cl_time_note_on_separate_row)); +$form->addInput(array('type'=>'checkbox','name'=>'time_not_complete_days','value'=>$cl_time_not_complete_days)); // TODO: consider adding other fields (timesheet, work_units, invoice, approved, cost, paid)? // Reports. @@ -70,6 +73,7 @@ if ($err->no()) { // Update config. $config->setDefinedValue('time_note_on_separate_row', $cl_time_note_on_separate_row); + $config->setDefinedValue('time_not_complete_days', $cl_time_not_complete_days); $config->setDefinedValue('report_note_on_separate_row', $cl_report_note_on_separate_row); if ($user->updateGroup(array('config' => $config->getConfig()))) { header('Location: success.php'); diff --git a/test.php b/test.php new file mode 100644 index 000000000..971ebaf36 --- /dev/null +++ b/test.php @@ -0,0 +1,106 @@ +behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { + header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. + exit(); +} +if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { + header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. + exit(); +} +if ($request->isPost()) { + $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + header('Location: access_denied.php'); // User changed, but no right or wrong user id. + exit(); + } +} +// End of access checks. + +// Determine user for whom we display this page. +if ($request->isPost() && $userChanged) { + $user_id = $request->getParameter('user'); + $user->setOnBehalfUser($user_id); +} else { + $user_id = $user->getUser(); +} + +$group_id = $user->getGroup(); +$config = new ttConfigHelper($user->getConfig()); + +// Initialize and store date in session. +$cl_date = $request->getParameter('date', @$_SESSION['date']); +$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); +if($selected_date->isError()) + $selected_date = new DateAndTime(DB_DATEFORMAT); +if(!$cl_date) + $cl_date = $selected_date->toString(DB_DATEFORMAT); +$_SESSION['date'] = $cl_date; + +// Elements of timeRecordForm. +$form = new Form('timeRecordForm'); + +// Calendar. +$form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar + +// A hidden control for today's date from user's browser. +$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. + +if ($request->isPost()) { + if ($request->getParameter('btn_submit')) { + + } +} // isPost + + +$smarty->assign('selected_date', $selected_date); +$smarty->assign('week_total', $week_total); +$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); +$smarty->assign('forms', array($form->getName()=>$form->toArray())); +$smarty->assign('onload', 'onLoad="fillDropdowns();prepopulateNote();"'); +$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); +$smarty->assign('title', $i18n->get('title.time')); +$smarty->assign('content_page_name', 'test.tpl'); +$smarty->display('index.tpl'); + From 86ac2ba703cf3477f4cd5d28dd4ee55e09ee8671 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 12 Jul 2020 18:53:45 +0000 Subject: [PATCH 014/652] Removed test page. --- WEB-INF/templates/test.tpl | 17 ------ test.php | 106 ------------------------------------- 2 files changed, 123 deletions(-) delete mode 100644 WEB-INF/templates/test.tpl delete mode 100644 test.php diff --git a/WEB-INF/templates/test.tpl b/WEB-INF/templates/test.tpl deleted file mode 100644 index 325d686bc..000000000 --- a/WEB-INF/templates/test.tpl +++ /dev/null @@ -1,17 +0,0 @@ - - -{$forms.timeRecordForm.open} - - - - -
- - -
{$forms.timeRecordForm.date.control}
-
-{$forms.timeRecordForm.close} diff --git a/test.php b/test.php deleted file mode 100644 index 971ebaf36..000000000 --- a/test.php +++ /dev/null @@ -1,106 +0,0 @@ -behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { - header('Location: access_denied.php'); // User changed, but no right or wrong user id. - exit(); - } -} -// End of access checks. - -// Determine user for whom we display this page. -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -$group_id = $user->getGroup(); -$config = new ttConfigHelper($user->getConfig()); - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -// Elements of timeRecordForm. -$form = new Form('timeRecordForm'); - -// Calendar. -$form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar - -// A hidden control for today's date from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. - -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - - } -} // isPost - - -$smarty->assign('selected_date', $selected_date); -$smarty->assign('week_total', $week_total); -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="fillDropdowns();prepopulateNote();"'); -$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); -$smarty->assign('title', $i18n->get('title.time')); -$smarty->assign('content_page_name', 'test.tpl'); -$smarty->display('index.tpl'); - From 275fa15951ebfe27ba05572471de9e0ef914680c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 13 Jul 2020 13:28:47 +0000 Subject: [PATCH 015/652] Cosmetic. Removed some white space. --- WEB-INF/lib/form/Calendar.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index b624a8da2..1847b3fa8 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -80,7 +80,7 @@ function getHtml() { $firstOfPreviousMonth = strftime(DB_DATEFORMAT, $firstOfPreviousMonth2AM); // Print calendar header. - $html .= "\n\n\n\n\n\n\n"; + $html .= "\n\n\n"; $html .= ''."\n"; $html .= ' + {else} - + {/if} {/if} - - + + {/foreach}
'; $html .= '
'; @@ -201,7 +201,7 @@ function getHtml() { $html .= "adjustToday();\n"; $html .= "\n"; - $html .= "\n\n\n\n\n\n\n"; + $html .= "\n\n"; return $html; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 3e158c480..549a20384 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- +{if defined(CUSTOM_CSS_DEBUG)} + + + + + +{/if} + diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f0706ae07..0ae53d506 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.18.5228 | Copyright © Anuko | + Anuko Time Tracker 1.19.18.5229 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 28992336205e7e453226a26273b4e5743eb81da0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 14 Jul 2020 18:22:40 +0000 Subject: [PATCH 016/652] Starting to work on custom css. Introduced a database field. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 ++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 549a20384..f0706ae07 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
Anuko Time Tracker 1.19.18.5229 | Copyright © Anuko | + Anuko Time Tracker 1.19.19.5230 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index f596a05e6..242d57b84 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1161,7 +1161,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11917"]) { + if ($_POST["convert11900to11919"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1188,6 +1188,8 @@ function ttGenerateKeys() { ttExecute("create index template_idx on tt_project_template_binds(template_id)"); ttExecute("create unique index project_template_idx on tt_project_template_binds(project_id, template_id)"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.17', modified = now() where param_name = 'version_db' and param_value = '1.19.14'"); + ttExecute("ALTER TABLE `tt_groups` ADD `custom_css` text default NULL AFTER `config`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.19', modified = now() where param_name = 'version_db' and param_value = '1.19.17'"); } if ($_POST["cleanup"]) { @@ -1238,7 +1240,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.17) + Create database structure (v1.19.19)
(applies only to new installations, do not execute when updating)
@@ -1287,8 +1289,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.17)Update database structure (v1.19 to v1.19.19)
diff --git a/mysql.sql b/mysql.sql index ae31890b5..e3ccd7d2c 100644 --- a/mysql.sql +++ b/mysql.sql @@ -39,6 +39,7 @@ CREATE TABLE `tt_groups` ( `workday_minutes` smallint(4) default 480, # number of work minutes in a regular working day `custom_logo` tinyint(4) default 0, # whether to use a custom logo or not `config` text default NULL, # miscellaneous group configuration settings + `custom_css` text default NULL, # custom css for group `created` datetime default NULL, # creation timestamp `created_ip` varchar(45) default NULL, # creator ip `created_by` int(11) default NULL, # creator user_id @@ -655,4 +656,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.17', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.19', now()); # TODO: change when structure changes. From c6d062ac68917e6e08f0e9f0706c071a09fb04d4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 14 Jul 2020 19:58:59 +0000 Subject: [PATCH 017/652] Some more work in progress on custom css feature. --- WEB-INF/lib/ttUser.class.php | 12 ++++++++++-- WEB-INF/resources/ca.lang.php | 1 + WEB-INF/resources/cs.lang.php | 1 + WEB-INF/resources/da.lang.php | 1 + WEB-INF/resources/de.lang.php | 1 + WEB-INF/resources/en.lang.php | 1 + WEB-INF/resources/es.lang.php | 1 + WEB-INF/resources/et.lang.php | 1 + WEB-INF/resources/fa.lang.php | 1 + WEB-INF/resources/fi.lang.php | 1 + WEB-INF/resources/fr.lang.php | 1 + WEB-INF/resources/gr.lang.php | 1 + WEB-INF/resources/he.lang.php | 1 + WEB-INF/resources/hu.lang.php | 1 + WEB-INF/resources/it.lang.php | 1 + WEB-INF/resources/ja.lang.php | 1 + WEB-INF/resources/ko.lang.php | 1 + WEB-INF/resources/nl.lang.php | 1 + WEB-INF/resources/no.lang.php | 1 + WEB-INF/resources/pl.lang.php | 1 + WEB-INF/resources/pt-br.lang.php | 1 + WEB-INF/resources/pt.lang.php | 1 + WEB-INF/resources/ro.lang.php | 1 + WEB-INF/resources/ru.lang.php | 1 + WEB-INF/resources/sk.lang.php | 1 + WEB-INF/resources/sl.lang.php | 1 + WEB-INF/resources/sr.lang.php | 1 + WEB-INF/resources/sv.lang.php | 1 + WEB-INF/resources/tr.lang.php | 1 + WEB-INF/resources/zh-cn.lang.php | 1 + WEB-INF/resources/zh-tw.lang.php | 1 + WEB-INF/templates/display_options.tpl | 8 ++++++++ WEB-INF/templates/footer.tpl | 2 +- display_options.php | 1 + 34 files changed, 50 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 4ef5d26e0..ed3dc437b 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -74,6 +74,7 @@ class ttUser { // Refactoring ongoing. Towards using helper instead of config string? var $config = null; // Comma-separated list of miscellaneous config options. var $configHelper = null; // An instance of ttConfigHelper class. + var $custom_css = null; // Custom css. var $custom_logo = 0; // Whether to use a custom logo for group. var $lock_spec = null; // Cron specification for record locking. @@ -97,7 +98,7 @@ function __construct($login, $id = null) { $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id,". " u.quota_percent, u.email, g.org_id, g.group_key, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.task_required, g.record_type,". - " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.holidays, g.workday_minutes, g.custom_logo". + " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.custom_css, g.holidays, g.workday_minutes, g.custom_logo". " FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; if ($id) $sql .= "u.id = $id"; @@ -155,7 +156,9 @@ function __construct($login, $id = null) { $this->punch_mode = $this->configHelper->getDefinedValue('punch_mode'); $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); $this->future_entries = $this->configHelper->getDefinedValue('future_entries'); - + + $this->custom_css = $val['custom_css']; + // Set "on behalf" id and name (user). if (isset($_SESSION['behalf_id'])) { $this->behalf_id = $_SESSION['behalf_id']; @@ -304,6 +307,11 @@ function getConfigInt($name, $defaultVal) { return $config->getIntValue($name, $defaultVal); } + // getCustomCss returns custom css for active group. + function getCustomCss() { + return ($this->behalfGroup ? $this->behalfGroup->custom_css : $this->custom_css); + } + // can - determines whether user has a right to do something. function can($do_something) { return in_array($do_something, $this->rights); diff --git a/WEB-INF/resources/ca.lang.php b/WEB-INF/resources/ca.lang.php index 5260ecc1d..30efec063 100644 --- a/WEB-INF/resources/ca.lang.php +++ b/WEB-INF/resources/ca.lang.php @@ -707,6 +707,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/cs.lang.php b/WEB-INF/resources/cs.lang.php index 2ae8ed511..707b3dcbe 100644 --- a/WEB-INF/resources/cs.lang.php +++ b/WEB-INF/resources/cs.lang.php @@ -720,6 +720,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/da.lang.php b/WEB-INF/resources/da.lang.php index f15a08b09..9b061118f 100644 --- a/WEB-INF/resources/da.lang.php +++ b/WEB-INF/resources/da.lang.php @@ -682,6 +682,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/de.lang.php b/WEB-INF/resources/de.lang.php index fa0407b8f..a66723626 100644 --- a/WEB-INF/resources/de.lang.php +++ b/WEB-INF/resources/de.lang.php @@ -659,6 +659,7 @@ 'form.display_options.note_on_separate_row' => 'Beschreibung in separater Zeile', // TODO: translate the following. // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/en.lang.php b/WEB-INF/resources/en.lang.php index c96415300..4b17bc464 100644 --- a/WEB-INF/resources/en.lang.php +++ b/WEB-INF/resources/en.lang.php @@ -638,6 +638,7 @@ 'form.display_options.menu' => 'Menu', 'form.display_options.note_on_separate_row' => 'Note on separate row', 'form.display_options.not_complete_days' => 'Not complete days', +'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Work item is not available.', diff --git a/WEB-INF/resources/es.lang.php b/WEB-INF/resources/es.lang.php index fe77bf299..0bd854328 100644 --- a/WEB-INF/resources/es.lang.php +++ b/WEB-INF/resources/es.lang.php @@ -722,6 +722,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/et.lang.php b/WEB-INF/resources/et.lang.php index 9dc067415..0b4603566 100644 --- a/WEB-INF/resources/et.lang.php +++ b/WEB-INF/resources/et.lang.php @@ -689,6 +689,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fa.lang.php b/WEB-INF/resources/fa.lang.php index a9a1d76f0..ef7591192 100644 --- a/WEB-INF/resources/fa.lang.php +++ b/WEB-INF/resources/fa.lang.php @@ -706,6 +706,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fi.lang.php b/WEB-INF/resources/fi.lang.php index 6e1787474..2d91252ef 100644 --- a/WEB-INF/resources/fi.lang.php +++ b/WEB-INF/resources/fi.lang.php @@ -688,6 +688,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/fr.lang.php b/WEB-INF/resources/fr.lang.php index a4a9a74f7..a4452a4e2 100644 --- a/WEB-INF/resources/fr.lang.php +++ b/WEB-INF/resources/fr.lang.php @@ -678,6 +678,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/gr.lang.php b/WEB-INF/resources/gr.lang.php index 8137dbd58..d2d036ddf 100644 --- a/WEB-INF/resources/gr.lang.php +++ b/WEB-INF/resources/gr.lang.php @@ -671,6 +671,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/he.lang.php b/WEB-INF/resources/he.lang.php index 5010087a8..3f0cf5d66 100644 --- a/WEB-INF/resources/he.lang.php +++ b/WEB-INF/resources/he.lang.php @@ -707,6 +707,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/hu.lang.php b/WEB-INF/resources/hu.lang.php index 683636a67..82f1ff081 100644 --- a/WEB-INF/resources/hu.lang.php +++ b/WEB-INF/resources/hu.lang.php @@ -712,6 +712,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/it.lang.php b/WEB-INF/resources/it.lang.php index 4d3540592..15407a6b9 100644 --- a/WEB-INF/resources/it.lang.php +++ b/WEB-INF/resources/it.lang.php @@ -685,6 +685,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ja.lang.php b/WEB-INF/resources/ja.lang.php index cfbeca196..b116fb35b 100644 --- a/WEB-INF/resources/ja.lang.php +++ b/WEB-INF/resources/ja.lang.php @@ -715,6 +715,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ko.lang.php b/WEB-INF/resources/ko.lang.php index 2ed5c1bfc..6b17d47d2 100644 --- a/WEB-INF/resources/ko.lang.php +++ b/WEB-INF/resources/ko.lang.php @@ -713,6 +713,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 6d815c746..5881139e3 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -642,6 +642,7 @@ 'form.display_options.note_on_separate_row' => 'Notitie in aparte kolom', // TODO: translate the following. // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/no.lang.php b/WEB-INF/resources/no.lang.php index 8afcf5c17..3677fdda5 100644 --- a/WEB-INF/resources/no.lang.php +++ b/WEB-INF/resources/no.lang.php @@ -712,6 +712,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pl.lang.php b/WEB-INF/resources/pl.lang.php index 4dbf608fe..dff252c93 100644 --- a/WEB-INF/resources/pl.lang.php +++ b/WEB-INF/resources/pl.lang.php @@ -691,6 +691,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt-br.lang.php b/WEB-INF/resources/pt-br.lang.php index cca28d179..db5e0f17c 100644 --- a/WEB-INF/resources/pt-br.lang.php +++ b/WEB-INF/resources/pt-br.lang.php @@ -686,6 +686,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/pt.lang.php b/WEB-INF/resources/pt.lang.php index 57db2d012..b88fb9f18 100644 --- a/WEB-INF/resources/pt.lang.php +++ b/WEB-INF/resources/pt.lang.php @@ -694,6 +694,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ro.lang.php b/WEB-INF/resources/ro.lang.php index eab6eb7a5..c569adb7e 100644 --- a/WEB-INF/resources/ro.lang.php +++ b/WEB-INF/resources/ro.lang.php @@ -715,6 +715,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/ru.lang.php b/WEB-INF/resources/ru.lang.php index 1050013e0..5302c225b 100644 --- a/WEB-INF/resources/ru.lang.php +++ b/WEB-INF/resources/ru.lang.php @@ -619,6 +619,7 @@ 'form.display_options.menu' => 'Меню', 'form.display_options.note_on_separate_row' => 'Комментарий в отдельном ряду', 'form.display_options.not_complete_days' => 'Незавершенные дни', +'form.display_options.custom_css' => 'Пользовательская CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php 'work.error.work_not_available' => 'Работа отсутствует.', diff --git a/WEB-INF/resources/sk.lang.php b/WEB-INF/resources/sk.lang.php index e0ae714fc..53c5ee3dc 100644 --- a/WEB-INF/resources/sk.lang.php +++ b/WEB-INF/resources/sk.lang.php @@ -696,6 +696,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sl.lang.php b/WEB-INF/resources/sl.lang.php index 0dd6f7206..a3d350ca6 100644 --- a/WEB-INF/resources/sl.lang.php +++ b/WEB-INF/resources/sl.lang.php @@ -688,6 +688,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sr.lang.php b/WEB-INF/resources/sr.lang.php index b7b93ffbd..fe385a67c 100644 --- a/WEB-INF/resources/sr.lang.php +++ b/WEB-INF/resources/sr.lang.php @@ -689,6 +689,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/sv.lang.php b/WEB-INF/resources/sv.lang.php index 24797672a..221c39d4a 100644 --- a/WEB-INF/resources/sv.lang.php +++ b/WEB-INF/resources/sv.lang.php @@ -687,6 +687,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/tr.lang.php b/WEB-INF/resources/tr.lang.php index c2f30dfbb..0f0537325 100644 --- a/WEB-INF/resources/tr.lang.php +++ b/WEB-INF/resources/tr.lang.php @@ -728,6 +728,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-cn.lang.php b/WEB-INF/resources/zh-cn.lang.php index 9cbb47534..29422cc5f 100644 --- a/WEB-INF/resources/zh-cn.lang.php +++ b/WEB-INF/resources/zh-cn.lang.php @@ -699,6 +699,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/resources/zh-tw.lang.php b/WEB-INF/resources/zh-tw.lang.php index 774b8024a..d4720b341 100644 --- a/WEB-INF/resources/zh-tw.lang.php +++ b/WEB-INF/resources/zh-tw.lang.php @@ -705,6 +705,7 @@ // 'form.display_options.menu' => 'Menu', // 'form.display_options.note_on_separate_row' => 'Note on separate row', // 'form.display_options.not_complete_days' => 'Not complete days', +// 'form.display_options.custom_css' => 'Custom CSS', // Work plugin strings. See example at https://timetracker.anuko.com/work.php // TODO: translate the following. diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index 918a48f9e..0f78e082e 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -19,6 +19,14 @@
{$forms.displayOptionsForm.report_note_on_separate_row.control} {$i18n.label.what_is_it}
 
{$i18n.form.display_options.custom_css}
{$forms.displayOptionsForm.custom_css.control}
 
{$forms.displayOptionsForm.btn_save.control}
- -{if defined(CUSTOM_CSS_DEBUG)} -{/if} diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0ae53d506..50ff6f264 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.19.5230 | Copyright © Anuko | + Anuko Time Tracker 1.19.19.5231 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/display_options.php b/display_options.php index 7dd724d44..4430af38b 100644 --- a/display_options.php +++ b/display_options.php @@ -67,6 +67,7 @@ $form->addInput(array('type'=>'checkbox','name'=>'report_note_on_separate_row','value'=>$cl_report_note_on_separate_row)); // TODO: add PDF break controller here. +$form->addInput(array('type'=>'textarea','name'=>'custom_css','style'=>'width: 250px; height: 40px;','value'=>$cl_custom_css)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()){ From f33ed44a6703ba05d933c2b37d44900bca8cfd49 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 15 Jul 2020 01:08:39 +0000 Subject: [PATCH 018/652] Initial implementation of custom css for groups. --- WEB-INF/lib/ttUser.class.php | 3 ++- WEB-INF/templates/display_options.tpl | 2 -- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 3 +++ WEB-INF/templates/mobile/header.tpl | 3 +++ custom_css.php | 34 +++++++++++++++++++++++++++ display_options.php | 6 ++++- 7 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 custom_css.php diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index ed3dc437b..a62fc5809 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -716,6 +716,7 @@ function updateGroup($fields) { if (isset($fields['allow_ip'])) $allow_ip_part = ', allow_ip = '.$mdb2->quote($fields['allow_ip']); if (isset($fields['plugins'])) $plugins_part = ', plugins = '.$mdb2->quote($fields['plugins']); if (isset($fields['config'])) $config_part = ', config = '.$mdb2->quote($fields['config']); + if (isset($fields['custom_css'])) $custom_css_part = ', custom_css = '.$mdb2->quote($fields['custom_css']); if (isset($fields['lock_spec'])) $lock_spec_part = ', lock_spec = '.$mdb2->quote($fields['lock_spec']); if (isset($fields['holidays'])) $holidays_part = ', holidays = '.$mdb2->quote($fields['holidays']); if (isset($fields['workday_minutes'])) $workday_minutes_part = ', workday_minutes = '.$mdb2->quote($fields['workday_minutes']); @@ -723,7 +724,7 @@ function updateGroup($fields) { $parts = trim($name_part.$description_part.$currency_part.$lang_part.$decimal_mark_part.$date_format_part. $time_format_part.$week_start_part.$tracking_mode_part.$task_required_part.$project_required_part.$record_type_part. - $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); + $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$custom_css_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); $sql = "update tt_groups set $parts where id = $group_id and org_id = $this->org_id"; $affected = $mdb2->exec($sql); diff --git a/WEB-INF/templates/display_options.tpl b/WEB-INF/templates/display_options.tpl index 0f78e082e..f41bd6f58 100644 --- a/WEB-INF/templates/display_options.tpl +++ b/WEB-INF/templates/display_options.tpl @@ -19,13 +19,11 @@ {$forms.displayOptionsForm.report_note_on_separate_row.control} {$i18n.label.what_is_it}
 
{$i18n.form.display_options.custom_css}
{$forms.displayOptionsForm.custom_css.control}
 
- - + {/if} diff --git a/WEB-INF/templates/time_edit.tpl b/WEB-INF/templates/time_edit.tpl index f1eca33cf..45c9bc666 100644 --- a/WEB-INF/templates/time_edit.tpl +++ b/WEB-INF/templates/time_edit.tpl @@ -57,7 +57,7 @@ function confirmSave() { {/if} {if $show_task} - + {/if} diff --git a/group_edit.php b/group_edit.php index c4fdc2174..2196d280b 100644 --- a/group_edit.php +++ b/group_edit.php @@ -85,7 +85,6 @@ $cl_holidays = trim($request->getParameter('holidays')); $cl_tracking_mode = $request->getParameter('tracking_mode'); $cl_project_required = $request->getParameter('project_required'); - $cl_task_required = $request->getParameter('task_required'); $cl_record_type = $request->getParameter('record_type'); $cl_punch_mode = $request->getParameter('punch_mode'); $cl_allow_overlap = $request->getParameter('allow_overlap'); @@ -102,7 +101,6 @@ $cl_holidays = $group['holidays']; $cl_tracking_mode = $group['tracking_mode']; $cl_project_required = $group['project_required']; - $cl_task_required = $group['task_required']; $cl_record_type = $group['record_type']; $cl_punch_mode = $config->getDefinedValue('punch_mode'); $cl_allow_overlap = $config->getDefinedValue('allow_overlap'); @@ -177,9 +175,8 @@ $tracking_mode_options[MODE_TIME] = $i18n->get('form.group_edit.mode_time'); $tracking_mode_options[MODE_PROJECTS] = $i18n->get('form.group_edit.mode_projects'); $tracking_mode_options[MODE_PROJECTS_AND_TASKS] = $i18n->get('form.group_edit.mode_projects_and_tasks'); -$form->addInput(array('type'=>'combobox','name'=>'tracking_mode','style'=>'width: 150px;','data'=>$tracking_mode_options,'value'=>$cl_tracking_mode,'onchange'=>'handleTaskRequiredCheckbox()')); +$form->addInput(array('type'=>'combobox','name'=>'tracking_mode','style'=>'width: 150px;','data'=>$tracking_mode_options,'value'=>$cl_tracking_mode)); $form->addInput(array('type'=>'checkbox','name'=>'project_required','value'=>$cl_project_required)); -$form->addInput(array('type'=>'checkbox','name'=>'task_required','value'=>$cl_task_required)); // Prepare record type choices. $record_type_options = array(); @@ -241,7 +238,6 @@ 'holidays' => $cl_holidays, 'tracking_mode' => $cl_tracking_mode, 'project_required' => $cl_project_required, - 'task_required' => $cl_task_required, 'record_type' => $cl_record_type, 'uncompleted_indicators' => $cl_uncompleted_indicators, 'config' => $config->getConfig()))) { @@ -255,7 +251,7 @@ $smarty->assign('group_dropdown', count($groups) > 1); $smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="handleTaskRequiredCheckbox(); handlePluginCheckboxes();"'); +$smarty->assign('onload', 'onLoad="handlePluginCheckboxes();"'); $smarty->assign('title', $i18n->get('title.edit_group')); $smarty->assign('content_page_name', 'group_edit.tpl'); $smarty->display('index.tpl'); diff --git a/mobile/time.php b/mobile/time.php index 8f4ca0a32..58661632a 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -73,6 +73,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; @@ -306,7 +307,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { @@ -396,6 +397,7 @@ $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_start', $showStart); $smarty->assign('show_duration', $showDuration); $smarty->assign('client_list', $client_list); diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 1aa7dd1f4..fb3a918dc 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -58,6 +58,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; @@ -302,7 +303,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $task_required) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (!$cl_duration) { @@ -480,6 +481,7 @@ $smarty->assign('show_paid_status', $showPaidStatus); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_start', $showStart); $smarty->assign('show_duration', $showDuration); $smarty->assign('client_list', $client_list); diff --git a/tasks.php b/tasks.php index 7b5f99790..2e13ead5c 100644 --- a/tasks.php +++ b/tasks.php @@ -41,12 +41,35 @@ } // End of access checks. +$config = $user->getConfigHelper(); + +if ($request->isPost()) { + $cl_task_required = $request->getParameter('task_required'); +} else { + $cl_task_required = $config->getDefinedValue('task_required'); +} + if($user->can('manage_tasks')) { $active_tasks = ttGroupHelper::getActiveTasks(); $inactive_tasks = ttGroupHelper::getInactiveTasks(); } else $active_tasks = $user->getAssignedTasks(); +$form = new Form('tasksForm'); +$form->addInput(array('type'=>'checkbox','name'=>'task_required','value'=>$cl_task_required)); +$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); + +if ($request->isPost()) { + if ($request->getParameter('btn_save')) { + // Save button clicked. Update config. + $config->setDefinedValue('task_required', $cl_task_required); + if (!$user->updateGroup(array('config' => $config->getConfig()))) { + $err->add($i18n->get('error.db')); + } + } +} + +$smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('active_tasks', $active_tasks); $smarty->assign('inactive_tasks', $inactive_tasks); $smarty->assign('title', $i18n->get('title.tasks')); diff --git a/time.php b/time.php index bbd5d14a3..5e0dda153 100644 --- a/time.php +++ b/time.php @@ -74,6 +74,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; @@ -349,7 +350,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (strlen($cl_duration) == 0) { @@ -481,6 +482,7 @@ $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_start', $showStart); $smarty->assign('show_duration', $showDuration); $smarty->assign('show_note_column', $showNoteColumn); diff --git a/time_edit.php b/time_edit.php index 44f04253c..b672c41cb 100644 --- a/time_edit.php +++ b/time_edit.php @@ -58,6 +58,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); $recordType = $user->getRecordType(); $showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; $showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; @@ -302,7 +303,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } if (!$cl_duration) { @@ -480,6 +481,7 @@ $smarty->assign('show_paid_status', $showPaidStatus); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_start', $showStart); $smarty->assign('show_duration', $showDuration); $smarty->assign('client_list', $client_list); From c2306552c7c718337bb40f22642db073ac44d336 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 25 Jul 2020 20:24:01 +0000 Subject: [PATCH 050/652] Refactoring and some fixes for task_required config option. --- WEB-INF/lib/ttGroup.class.php | 4 +--- WEB-INF/lib/ttGroupExportHelper.class.php | 1 - WEB-INF/lib/ttGroupHelper.class.php | 3 +-- WEB-INF/lib/ttOrgImportHelper.class.php | 4 +--- WEB-INF/lib/ttUser.class.php | 7 ++----- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time_script.tpl | 2 +- WEB-INF/templates/week.tpl | 2 +- week.php | 4 +++- 9 files changed, 11 insertions(+), 18 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index 46ce5be56..bd0f944e3 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -44,7 +44,6 @@ class ttGroup { var $week_start = 0; // Week start day. var $tracking_mode = 0; // Tracking mode. var $project_required = 0; // Whether project selection is required on time entires. - var $task_required = 0; // Whether task selection is required on time entires. var $record_type = 0; // Record type (duration vs start and finish, or both). var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. @@ -92,8 +91,7 @@ function __construct($id, $org_id) { $this->tracking_mode = $val['tracking_mode']; /* TODO: initialize other things here. $this->project_required = $val['project_required']; - $this->task_required = $val['task_required']; - */ + */ $this->record_type = $val['record_type']; /* $this->bcc_email = $val['bcc_email']; diff --git a/WEB-INF/lib/ttGroupExportHelper.class.php b/WEB-INF/lib/ttGroupExportHelper.class.php index d6415daea..a510da274 100644 --- a/WEB-INF/lib/ttGroupExportHelper.class.php +++ b/WEB-INF/lib/ttGroupExportHelper.class.php @@ -152,7 +152,6 @@ function writeData() { $group_part .= " week_start=\"".$group['week_start']."\""; $group_part .= " tracking_mode=\"".$group['tracking_mode']."\""; $group_part .= " project_required=\"".$group['project_required']."\""; - $group_part .= " task_required=\"".$group['task_required']."\""; $group_part .= " record_type=\"".$group['record_type']."\""; $group_part .= " bcc_email=\"".$group['bcc_email']."\""; $group_part .= " allow_ip=\"".$group['allow_ip']."\""; diff --git a/WEB-INF/lib/ttGroupHelper.class.php b/WEB-INF/lib/ttGroupHelper.class.php index af8d55345..895fa1dc6 100644 --- a/WEB-INF/lib/ttGroupHelper.class.php +++ b/WEB-INF/lib/ttGroupHelper.class.php @@ -97,7 +97,7 @@ static function insertSubgroup($fields) { $attrs = ttGroupHelper::getGroupAttrs($parent_id); $columns = '(parent_id, org_id, group_key, name, description, currency, decimal_mark, lang, date_format,'. - ' time_format, week_start, tracking_mode, project_required, task_required, record_type, bcc_email,'. + ' time_format, week_start, tracking_mode, project_required, record_type, bcc_email,'. ' allow_ip, password_complexity, plugins, lock_spec,'. ' workday_minutes, config, created, created_ip, created_by)'; @@ -113,7 +113,6 @@ static function insertSubgroup($fields) { $values .= ', '.(int)$attrs['week_start']; $values .= ', '.(int)$attrs['tracking_mode']; $values .= ', '.(int)$attrs['project_required']; - $values .= ', '.(int)$attrs['task_required']; $values .= ', '.(int)$attrs['record_type']; $values .= ', '.$mdb2->quote($attrs['bcc_email']); $values .= ', '.$mdb2->quote($attrs['allow_ip']); diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index dbf838281..ac970426f 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -114,7 +114,6 @@ function startElement($parser, $name, $attrs) { 'week_start' => $attrs['WEEK_START'], 'tracking_mode' => $attrs['TRACKING_MODE'], 'project_required' => $attrs['PROJECT_REQUIRED'], - 'task_required' => $attrs['TASK_REQUIRED'], 'record_type' => $attrs['RECORD_TYPE'], 'bcc_email' => $attrs['BCC_EMAIL'], 'allow_ip' => $attrs['ALLOW_IP'], @@ -705,7 +704,7 @@ private function createGroup($fields) { $mdb2 = getConnection(); $columns = '(parent_id, org_id, group_key, name, description, currency, decimal_mark, lang, date_format, time_format,'. - ' week_start, tracking_mode, project_required, task_required, record_type, bcc_email,'. + ' week_start, tracking_mode, project_required, record_type, bcc_email,'. ' allow_ip, password_complexity, plugins, lock_spec,'. ' workday_minutes, config, custom_css, created, created_ip, created_by)'; @@ -723,7 +722,6 @@ private function createGroup($fields) { $values .= ', '.(int)$fields['week_start']; $values .= ', '.(int)$fields['tracking_mode']; $values .= ', '.(int)$fields['project_required']; - $values .= ', '.(int)$fields['task_required']; $values .= ', '.(int)$fields['record_type']; $values .= ', '.$mdb2->quote($fields['bcc_email']); $values .= ', '.$mdb2->quote($fields['allow_ip']); diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 8bf029921..58c51c632 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -60,7 +60,6 @@ class ttUser { var $week_start = 0; // Week start day. var $tracking_mode = 0; // Tracking mode. var $project_required = 0; // Whether project selection is required on time entires. - var $task_required = 0; // Whether task selection is required on time entires. var $record_type = 0; // Record type (duration vs start and finish, or both). var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. @@ -96,7 +95,7 @@ function __construct($login, $id = null) { $sql = "SELECT u.id, u.login, u.name, u.group_id, u.role_id, r.rank, r.name as role_name, r.rights, u.client_id,". " u.quota_percent, u.email, g.org_id, g.group_key, g.name as group_name, g.currency, g.lang, g.decimal_mark, g.date_format,". - " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.task_required, g.record_type,". + " g.time_format, g.week_start, g.tracking_mode, g.project_required, g.record_type,". " g.bcc_email, g.allow_ip, g.password_complexity, g.plugins, g.config, g.lock_spec, g.custom_css, g.holidays, g.workday_minutes, g.custom_logo". " FROM tt_users u LEFT JOIN tt_groups g ON (u.group_id = g.id) LEFT JOIN tt_roles r on (r.id = u.role_id) WHERE "; if ($id) @@ -134,7 +133,6 @@ function __construct($login, $id = null) { $this->week_start = $val['week_start']; $this->tracking_mode = $val['tracking_mode']; $this->project_required = $val['project_required']; - $this->task_required = $val['task_required']; $this->record_type = $val['record_type']; $this->bcc_email = $val['bcc_email']; $this->allow_ip = $val['allow_ip']; @@ -707,7 +705,6 @@ function updateGroup($fields) { if (isset($fields['tracking_mode'])) { $tracking_mode_part = ', tracking_mode = '.(int) $fields['tracking_mode']; $project_required_part = ' , project_required = '.(int) $fields['project_required']; - $task_required_part = ' , task_required = '.(int) $fields['task_required']; } if (isset($fields['record_type'])) $record_type_part = ', record_type = '.(int) $fields['record_type']; if (isset($fields['bcc_email'])) $bcc_email_part = ', bcc_email = '.$mdb2->quote($fields['bcc_email']); @@ -721,7 +718,7 @@ function updateGroup($fields) { $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$mdb2->quote($this->id); $parts = trim($name_part.$description_part.$currency_part.$lang_part.$decimal_mark_part.$date_format_part. - $time_format_part.$week_start_part.$tracking_mode_part.$task_required_part.$project_required_part.$record_type_part. + $time_format_part.$week_start_part.$tracking_mode_part.$project_required_part.$record_type_part. $bcc_email_part.$allow_ip_part.$plugins_part.$config_part.$custom_css_part.$lock_spec_part.$holidays_part.$workday_minutes_part.$modified_part, ','); $sql = "update tt_groups set $parts where id = $group_id and org_id = $this->org_id"; diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9a2f53491..9668dfc5c 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.19.5231 | Copyright © Anuko | + Anuko Time Tracker 1.19.20.5232 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 55d047caa..4d140ed3e 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -7,6 +7,9 @@ {if $i18n.language.rtl} +{/if} +{if $user->getCustomCss()} + {/if} Time Tracker{if $title} - {$title}{/if} diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index 054c75363..6290dd025 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -8,6 +8,9 @@ {if $i18n.language.rtl} +{/if} +{if $user->getCustomCss()} + {/if} Time Tracker{if $title} - {$title}{/if} diff --git a/custom_css.php b/custom_css.php new file mode 100644 index 000000000..979e9a5bd --- /dev/null +++ b/custom_css.php @@ -0,0 +1,34 @@ +getCustomCss(); diff --git a/display_options.php b/display_options.php index 4430af38b..37a584657 100644 --- a/display_options.php +++ b/display_options.php @@ -43,10 +43,12 @@ $cl_time_note_on_separate_row = $request->getParameter('time_note_on_separate_row'); $cl_time_not_complete_days = $request->getParameter('time_not_complete_days'); $cl_report_note_on_separate_row = $request->getParameter('report_note_on_separate_row'); + $cl_custom_css = trim($request->getParameter('custom_css')); } else { $cl_time_note_on_separate_row = $config->getDefinedValue('time_note_on_separate_row'); $cl_time_not_complete_days = $config->getDefinedValue('time_not_complete_days'); $cl_report_note_on_separate_row = $config->getDefinedValue('report_note_on_separate_row'); + $cl_custom_css = $user->getCustomCss(); } $form = new Form('displayOptionsForm'); @@ -76,7 +78,9 @@ $config->setDefinedValue('time_note_on_separate_row', $cl_time_note_on_separate_row); $config->setDefinedValue('time_not_complete_days', $cl_time_not_complete_days); $config->setDefinedValue('report_note_on_separate_row', $cl_report_note_on_separate_row); - if ($user->updateGroup(array('config' => $config->getConfig()))) { + if ($user->updateGroup(array( + 'config' => $config->getConfig(), + 'custom_css' => $cl_custom_css))) { header('Location: success.php'); exit(); } else From 1b2c65d92bb6a1afff12080cd9713ffa90e331a2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 15 Jul 2020 15:12:13 +0000 Subject: [PATCH 019/652] Added a user input validator for custom css. --- WEB-INF/lib/common.lib.php | 19 +++++++++++++++++++ WEB-INF/templates/footer.tpl | 2 +- display_options.php | 4 ++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 1f2829442..e01deeaa5 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -177,6 +177,25 @@ function ttValidString($val, $emptyValid = false) return true; } +// ttValidCss is used to check user input for custom css. +function ttValidCss($val) +{ + $val = trim($val); + if (strlen($val) == 0) + return true; + + // String must not contain any tags. + if (stristr($val, '<')) + return false; + + // Security note: the above may not be enough. + // Currently it is unclear how vulnerable we are assuming custom css is available only to a logged on user + // (one custom css per group). + // However, if abuse occurs or when the issue is better understood, we may have to rewrite this function, + // perhaps by specifying what exactly we allow to style. + return true; +} + // ttValidTemplateText is used to check template-based user input. // When templates are used, required input parts must be filled by user. // We identify these parts by 3 "stop sign" emojis (aka "octagonal sign" U+1F6D1). diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 50ff6f264..d10afc302 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
Anuko Time Tracker 1.19.20.5232 | Copyright © Anuko | + Anuko Time Tracker 1.19.20.5233 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/display_options.php b/display_options.php index 37a584657..a4d3deacb 100644 --- a/display_options.php +++ b/display_options.php @@ -73,6 +73,10 @@ $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()){ + // Validate user input. + if (!ttValidCss($cl_custom_css)) $err->add($i18n->get('error.field'), $i18n->get('form.display_options.custom_css')); + // Finished validating user input. + if ($err->no()) { // Update config. $config->setDefinedValue('time_note_on_separate_row', $cl_time_note_on_separate_row); From ddf4f8e805d3ae7c551ea86a55392af1db92b7d3 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 15 Jul 2020 16:06:22 +0000 Subject: [PATCH 020/652] Fixed future entries behaviour for subgroups. --- WEB-INF/lib/ttGroup.class.php | 4 +--- WEB-INF/lib/ttUser.class.php | 2 -- WEB-INF/lib/ttWeekViewHelper.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- expenses.php | 2 +- mobile/expense_edit.php | 2 +- mobile/expenses.php | 2 +- mobile/time.php | 2 +- mobile/time_edit.php | 2 +- mobile/timer.php | 2 +- time.php | 2 +- time_edit.php | 2 +- 12 files changed, 11 insertions(+), 15 deletions(-) diff --git a/WEB-INF/lib/ttGroup.class.php b/WEB-INF/lib/ttGroup.class.php index 5e1885af9..46ce5be56 100644 --- a/WEB-INF/lib/ttGroup.class.php +++ b/WEB-INF/lib/ttGroup.class.php @@ -34,7 +34,7 @@ class ttGroup { var $id = null; // Group id. var $group_key = null; // Group key. - var $parent_id = null; // Paerent group id. + var $parent_id = null; // Parent group id. var $org_id = null; // Organization id. var $name = null; // Group name. var $lang = null; // Language. @@ -48,7 +48,6 @@ class ttGroup { var $record_type = 0; // Record type (duration vs start and finish, or both). var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. - var $future_entries = 0; // Whether to allow creating future entries. var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -117,7 +116,6 @@ function __construct($id, $org_id) { // Set user config options. $this->punch_mode = $this->configHelper->getDefinedValue('punch_mode'); $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); - $this->future_entries = $this->configHelper->getDefinedValue('future_entries'); } // Determine active user count in a separate query. diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index a62fc5809..8bf029921 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -64,7 +64,6 @@ class ttUser { var $record_type = 0; // Record type (duration vs start and finish, or both). var $punch_mode = 0; // Whether punch mode is enabled for user. var $allow_overlap = 0; // Whether to allow overlapping time entries. - var $future_entries = 0; // Whether to allow creating future entries. var $bcc_email = null; // Bcc email. var $allow_ip = null; // Specification from where user is allowed access. var $password_complexity = null; // Password complexity example. @@ -155,7 +154,6 @@ function __construct($login, $id = null) { // Set user config options. $this->punch_mode = $this->configHelper->getDefinedValue('punch_mode'); $this->allow_overlap = $this->configHelper->getDefinedValue('allow_overlap'); - $this->future_entries = $this->configHelper->getDefinedValue('future_entries'); $this->custom_css = $val['custom_css']; diff --git a/WEB-INF/lib/ttWeekViewHelper.class.php b/WEB-INF/lib/ttWeekViewHelper.class.php index 05ec4e9d0..aee8c8d61 100644 --- a/WEB-INF/lib/ttWeekViewHelper.class.php +++ b/WEB-INF/lib/ttWeekViewHelper.class.php @@ -537,7 +537,7 @@ static function insertDurationFromWeekView($fields, $custom_fields, $err) { $objEntryDate = new DateAndTime(DB_DATEFORMAT, $entry_date); // Prohibit creating entries in future. - if (!$user->future_entries && $fields['browser_today']) { + if (!$user->isOptionEnabled('future_entries') && $fields['browser_today']) { $objBrowserToday = new DateAndTime(DB_DATEFORMAT, $fields['browser_today']); if ($objEntryDate->after($objBrowserToday)) { $err->add($i18n->get('error.future_date')); diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index d10afc302..687331f88 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + diff --git a/WEB-INF/templates/mobile/time.tpl b/WEB-INF/templates/mobile/time.tpl index 07e50fb39..a346ad6c6 100644 --- a/WEB-INF/templates/mobile/time.tpl +++ b/WEB-INF/templates/mobile/time.tpl @@ -73,7 +73,7 @@ {/if} {if $show_task} - + {/if} {if $show_start} diff --git a/WEB-INF/templates/mobile/time_edit.tpl b/WEB-INF/templates/mobile/time_edit.tpl index 5fd10ad15..3025a63f7 100644 --- a/WEB-INF/templates/mobile/time_edit.tpl +++ b/WEB-INF/templates/mobile/time_edit.tpl @@ -44,7 +44,7 @@ function confirmSave() { {/if} {if $show_task} - + {/if} {if $show_start} diff --git a/WEB-INF/templates/tasks.tpl b/WEB-INF/templates/tasks.tpl index 24fd04380..c5afab227 100644 --- a/WEB-INF/templates/tasks.tpl +++ b/WEB-INF/templates/tasks.tpl @@ -2,6 +2,7 @@ function chLocation(newLocation) { document.location = newLocation; } +{$forms.tasksForm.open}
Anuko Time Tracker 1.19.20.5233 | Copyright © Anuko | + Anuko Time Tracker 1.19.20.5234 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/expenses.php b/expenses.php index 2b7a15bc4..7959bb311 100644 --- a/expenses.php +++ b/expenses.php @@ -202,7 +202,7 @@ if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); // Prohibit creating entries in future. - if (!$user->getConfigOption('future_entries')) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php index 654d1698d..67813a6f1 100644 --- a/mobile/expense_edit.php +++ b/mobile/expense_edit.php @@ -167,7 +167,7 @@ $new_date = new DateAndTime($user->getDateFormat(), $cl_date); // Prohibit creating entries in future. - if (!$user->getConfigOption('future_entries')) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/expenses.php b/mobile/expenses.php index 3b229368e..05d469985 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -203,7 +203,7 @@ if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); // Prohibit creating entries in future. - if (!$user->getConfigOption('future_entries')) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/time.php b/mobile/time.php index 233f1d16f..1e5276cdf 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -340,7 +340,7 @@ // Finished validating user input. // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/time_edit.php b/mobile/time_edit.php index 6fefebd86..7e50731b6 100644 --- a/mobile/time_edit.php +++ b/mobile/time_edit.php @@ -305,7 +305,7 @@ $new_date = new DateAndTime($user->date_format, $cl_date); // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/mobile/timer.php b/mobile/timer.php index c7c1c2d40..0b513c235 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -218,7 +218,7 @@ // Finished validating user input. // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/time.php b/time.php index 9f85d5981..6664243a6 100644 --- a/time.php +++ b/time.php @@ -383,7 +383,7 @@ // Finished validating user input. // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($selected_date->after($browser_today)) $err->add($i18n->get('error.future_date')); diff --git a/time_edit.php b/time_edit.php index 83989404f..918ecea52 100644 --- a/time_edit.php +++ b/time_edit.php @@ -310,7 +310,7 @@ $new_date = new DateAndTime($user->date_format, $cl_date); // Prohibit creating entries in future. - if (!$user->future_entries) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); From bacffb8ff036d508d8004f6b169adda11696627a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 15 Jul 2020 16:09:40 +0000 Subject: [PATCH 021/652] Forgot to check in one file. --- expense_edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expense_edit.php b/expense_edit.php index 3cebac129..f736f2132 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -172,7 +172,7 @@ $new_date = new DateAndTime($user->getDateFormat(), $cl_date); // Prohibit creating entries in future. - if (!$user->getConfigOption('future_entries')) { + if (!$user->isOptionEnabled('future_entries')) { $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); if ($new_date->after($browser_today)) $err->add($i18n->get('error.future_date')); From b6a3fe7a3cf32bcfa0c20d57cf855cbbe670893f Mon Sep 17 00:00:00 2001 From: WizardStan Date: Thu, 16 Jul 2020 09:27:49 -0400 Subject: [PATCH 022/652] Replace cal_days_in_month with generic date call (#99) --- plugins/MonthlyQuota.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/MonthlyQuota.class.php b/plugins/MonthlyQuota.class.php index c8559ad46..0a8ee4e9b 100644 --- a/plugins/MonthlyQuota.class.php +++ b/plugins/MonthlyQuota.class.php @@ -133,7 +133,7 @@ private function getMany($year){ // getNumWorkdays returns a number of work days in a given month. private function getNumWorkdays($month, $year) { - $daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year); // Number of calendar days in month. + $daysInMonth = date('t', mktime(0, 0, 0, $month, 1, $year)); $workdaysInMonth = 0; // Iterate through the entire month. From 671b1a087c997ada7a9435a1ea8eb19e447e0f59 Mon Sep 17 00:00:00 2001 From: WizardStan Date: Thu, 16 Jul 2020 09:51:00 -0400 Subject: [PATCH 023/652] Create notifications that trigger based on hours (#98) --- WEB-INF/lib/common.lib.php | 3 ++- WEB-INF/lib/ttReportHelper.class.php | 30 +++++++++++++++++++--------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index e01deeaa5..725f343c0 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -343,7 +343,8 @@ function ttValidCondition($val, $emptyValid = true) if (stristr($val, ' {$forms.groupForm.open} @@ -74,7 +60,7 @@ function handleTaskRequiredCheckbox() {
{$i18n.form.group_edit.tracking_mode}:{$forms.groupForm.tracking_mode.control} {$forms.groupForm.task_required.control} {$forms.groupForm.tracking_mode.control}
{$i18n.form.group_edit.record_type}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
@@ -78,7 +79,20 @@ {/foreach} {/if}
- {/if} +{/if} +
+ + + + + + + + +
{$forms.tasksForm.task_required.control} {$i18n.label.what_is_it}
{$forms.tasksForm.btn_save.control}
+ +
+{$forms.tasksForm.close} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index 0cbf0caca..377b26c01 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -53,7 +53,7 @@ {/if} {if $show_task}
{$i18n.label.task}{if $user->task_required} (*){/if}:{$i18n.label.task}{if $task_required} (*){/if}: {$forms.timeRecordForm.task.control}
{$i18n.label.task}{if $user->task_required} (*){/if}:{$i18n.label.task}{if $task_required} (*){/if}: {$forms.timeRecordForm.task.control}
- - + {/if} diff --git a/week.php b/week.php index a1a579094..d86e0c99c 100644 --- a/week.php +++ b/week.php @@ -79,6 +79,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $user->getConfigOption('task_required'); $showWeekNote = $user->isOptionEnabled('week_note'); $showWeekNotes = $user->isOptionEnabled('week_notes'); $recordType = $user->getRecordType(); @@ -416,7 +417,7 @@ function render(&$table, $value, $row, $column, $selected = false) { if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } } @@ -567,6 +568,7 @@ function render(&$table, $value, $row, $column, $selected = false) { $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('show_week_note', $showWeekNote); $smarty->assign('show_week_list', $user->isOptionEnabled('week_list')); $smarty->assign('show_start', $showStart); From bfef42dbca33313493b40dfdd265ee55f47ab29e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 25 Jul 2020 20:34:38 +0000 Subject: [PATCH 051/652] Fixed mobile timer.php for subgroups regarding task_required. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/mobile/timer.tpl | 2 +- mobile/timer.php | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9668dfc5c..0109338fa 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.22.5256 | Copyright © Anuko | + Anuko Time Tracker 1.19.22.5257 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 65a691abe..977db3d6c 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -178,7 +178,7 @@ function fillTaskDropdown(id) { } // Select a task if user is required to do so and there is only one task available. - if ({$user->task_required} && dropdown.options.length == 2) { // 2 because of mandatory top option. + if ({$user->getConfigOption('task_required')} && dropdown.options.length == 2) { // 2 because of mandatory top option. dropdown.options[1].selected = true; } } diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl index 2ee2e68a5..5ac3be85e 100644 --- a/WEB-INF/templates/week.tpl +++ b/WEB-INF/templates/week.tpl @@ -68,7 +68,7 @@ function fillDropdowns() { {/if} {if $show_task}
{$i18n.label.task}:{$i18n.label.task}{if $task_required} (*){/if}: {$forms.weekTimeForm.task.control}
- {/if} {if $show_task} - + {/if}
Anuko Time Tracker 1.19.22.5257 | Copyright © Anuko | + Anuko Time Tracker 1.19.22.5258 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/mobile/timer.tpl b/WEB-INF/templates/mobile/timer.tpl index 65f267d40..1fee04af3 100644 --- a/WEB-INF/templates/mobile/timer.tpl +++ b/WEB-INF/templates/mobile/timer.tpl @@ -84,7 +84,7 @@ startTimer();
{$forms.timeRecordForm.project.control}
{$i18n.label.task}:
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
diff --git a/mobile/timer.php b/mobile/timer.php index ac43dc86d..e301716a4 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -46,6 +46,7 @@ $trackingMode = $user->getTrackingMode(); $showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; $showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; +if ($showTask) $taskRequired = $user->getConfigOption('task_required'); // Initialize and store date in session. $cl_date = $request->getParameter('date', @$_SESSION['date']); @@ -229,7 +230,7 @@ if ($showProject) { if (!$cl_project) $err->add($i18n->get('error.project')); } - if ($showTask && $user->task_required) { + if ($showTask && $taskRequired) { if (!$cl_task) $err->add($i18n->get('error.task')); } // Finished validating user input. @@ -318,6 +319,7 @@ $smarty->assign('show_billable', $showBillable); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); +$smarty->assign('task_required', $taskRequired); $smarty->assign('time_records', ttTimeHelper::getRecords($cl_date)); $smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); $smarty->assign('client_list', $client_list); From 889ae54eaa95a4a69e0a4da875e2a250ca18a713 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 25 Jul 2020 20:43:05 +0000 Subject: [PATCH 052/652] Dropped task_required field from tt_groups table as it is now a part of config field. --- WEB-INF/templates/footer.tpl | 2 +- dbinstall.php | 10 ++++++---- mysql.sql | 3 +-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 0109338fa..80cb8a906 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + +
Anuko Time Tracker 1.19.22.5258 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5259 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/dbinstall.php b/dbinstall.php index b6f831479..59d3923f8 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -1161,7 +1161,7 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.0', modified = now() where param_name = 'version_db' and param_value = '1.18.61'"); } - if ($_POST["convert11900to11922"]) { + if ($_POST["convert11900to11923"]) { ttExecute("CREATE TABLE `tt_work_currencies` (`id` int(10) unsigned NOT NULL,`name` varchar(10) NOT NULL,PRIMARY KEY (`id`))"); ttExecute("create unique index currency_idx on tt_work_currencies(`name`)"); ttExecute("INSERT INTO `tt_work_currencies` (`id`, `name`) VALUES ('1', 'USD'), ('2', 'CAD'), ('3', 'AUD'), ('4', 'EUR'), ('5', 'NZD')"); @@ -1192,6 +1192,8 @@ function ttGenerateKeys() { ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.19', modified = now() where param_name = 'version_db' and param_value = '1.19.17'"); ttExecute("ALTER TABLE `tt_cron` ADD `comment` text AFTER `subject`"); ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.22', modified = now() where param_name = 'version_db' and param_value = '1.19.19'"); + ttExecute("ALTER TABLE `tt_groups` drop `task_required`"); + ttExecute("UPDATE `tt_site_config` SET param_value = '1.19.23', modified = now() where param_name = 'version_db' and param_value = '1.19.22'"); } if ($_POST["cleanup"]) { @@ -1242,7 +1244,7 @@ function ttGenerateKeys() {

DB Install

-
Create database structure (v1.19.22) + Create database structure (v1.19.23)
(applies only to new installations, do not execute when updating)
@@ -1291,8 +1293,8 @@ function ttGenerateKeys() {
Update database structure (v1.19 to v1.19.22)Update database structure (v1.19 to v1.19.23)
diff --git a/mysql.sql b/mysql.sql index 1e37a59df..e9f4cc031 100644 --- a/mysql.sql +++ b/mysql.sql @@ -27,7 +27,6 @@ CREATE TABLE `tt_groups` ( `week_start` smallint(2) NOT NULL default 0, # Week start day, 0 == Sunday. `tracking_mode` smallint(2) NOT NULL default 1, # tracking mode ("time", "projects" or "projects and tasks") `project_required` smallint(2) NOT NULL default 0, # whether a project selection is required or optional - `task_required` smallint(2) NOT NULL default 0, # whether a task selection is required or optional `record_type` smallint(2) NOT NULL default 0, # time record type ("start and finish", "duration", or both) `bcc_email` varchar(100) default NULL, # bcc email to copy all reports to `allow_ip` varchar(255) default NULL, # specification from where users are allowed access @@ -657,4 +656,4 @@ CREATE TABLE `tt_site_config` ( PRIMARY KEY (`param_name`) ); -INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.22', now()); # TODO: change when structure changes. +INSERT INTO `tt_site_config` (`param_name`, `param_value`, `created`) VALUES ('version_db', '1.19.23', now()); # TODO: change when structure changes. From cdbd32b362368570f0627288bf5f83739a055d60 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 26 Jul 2020 11:56:46 +0000 Subject: [PATCH 053/652] Fixed behavior of Now buttons, broken in one of recent commits. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/time_script.tpl | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 80cb8a906..f752264da 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- + {else} - + {/if} {/if} diff --git a/WEB-INF/templates/timesheets.tpl b/WEB-INF/templates/timesheets.tpl index a5e893e59..237eb98be 100644 --- a/WEB-INF/templates/timesheets.tpl +++ b/WEB-INF/templates/timesheets.tpl @@ -40,13 +40,13 @@ {/if} {if $show_files} {if $timesheet.has_files} - + {else} - + {/if} {/if} - - + + {/foreach}
Anuko Time Tracker 1.19.23.5259 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5260 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 977db3d6c..3d2013832 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -177,10 +177,12 @@ function fillTaskDropdown(id) { } } +{if $user->getConfigOption('task_required')} // Select a task if user is required to do so and there is only one task available. - if ({$user->getConfigOption('task_required')} && dropdown.options.length == 2) { // 2 because of mandatory top option. + if (dropdown.options.length == 2) { // 2 because of mandatory top option. dropdown.options[1].selected = true; } +{/if} } } From 9304cf358161f2dd63b0b570d57e3d84343ca81b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 26 Jul 2020 13:24:37 +0000 Subject: [PATCH 054/652] Cosmetic. Updated a link to user guide. --- WEB-INF/config.php.dist | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index a288ec0bf..24dd5a266 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -86,7 +86,7 @@ define('WEEKEND_START_DAY', 6); // Forum and help links from the main menu. // define('FORUM_LINK', 'https://www.anuko.com/forum/viewforum.php?f=4'); -define('HELP_LINK', 'https://www.anuko.com/time_tracker/user_guide/index.htm'); +define('HELP_LINK', 'https://www.anuko.com/time-tracker/user-guide/index.htm'); // Default sender for mail. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index f752264da..b7e572713 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + + {/foreach}
Anuko Time Tracker 1.19.23.5260 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5261 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 9c45529c062bf66c7def4dc4d8624a7cefda0061 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 28 Jul 2020 14:45:30 +0000 Subject: [PATCH 055/652] Moved the Required checkbox on top of tasks.php page to make it more visible. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/tasks.tpl | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index b7e572713..50b48e893 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
-
Anuko Time Tracker 1.19.23.5261 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5262 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/tasks.tpl b/WEB-INF/templates/tasks.tpl index c5afab227..df502c7ae 100644 --- a/WEB-INF/templates/tasks.tpl +++ b/WEB-INF/templates/tasks.tpl @@ -7,6 +7,16 @@
{if $user->can('manage_tasks')} + + + + + + + + +
{$forms.tasksForm.task_required.control} {$i18n.label.what_is_it}
{$forms.tasksForm.btn_save.control}
+
{if $inactive_tasks} @@ -80,18 +90,6 @@ {/if}
{$i18n.form.tasks.active_tasks}
{/if} -
- - - - - - - - -
{$forms.tasksForm.task_required.control} {$i18n.label.what_is_it}
{$forms.tasksForm.btn_save.control}
- -
From b243785a17e90bb671058b092f390decbf20c149 Mon Sep 17 00:00:00 2001 From: kanfil Date: Thu, 30 Jul 2020 21:32:04 +0300 Subject: [PATCH 056/652] Save custom field values in session (#102) --- time.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/time.php b/time.php index 5e0dda153..a76b470d5 100644 --- a/time.php +++ b/time.php @@ -155,19 +155,21 @@ $timeCustomFields = array(); // If we have time custom fields - collect input. -if ($request->isPost()) { +#if ($request->isPost()) { if ($custom_fields && $custom_fields->timeFields) { foreach ($custom_fields->timeFields as $timeField) { $control_name = 'time_field_'.$timeField['id']; + $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); + $_SESSION[$control_name] = $cl_control_name; $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], 'control_name' => $control_name, 'label' => $timeField['label'], 'type' => $timeField['type'], 'required' => $timeField['required'], - 'value' => trim($request->getParameter($control_name))); + 'value' => trim($cl_control_name)); } } -} +#} // Elements of timeRecordForm. $form = new Form('timeRecordForm'); From ee4536e9f776191a95e1abd86ef873572a642961 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Thu, 30 Jul 2020 18:40:01 +0000 Subject: [PATCH 057/652] Added time custom fields storage in session to mobile time.php as in pr #102. --- WEB-INF/templates/footer.tpl | 2 +- mobile/time.php | 24 ++++++++++++------------ time.php | 28 +++++++++++++--------------- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 50b48e893..1aa8e7ba2 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {else} - + {/if}
Anuko Time Tracker 1.19.23.5262 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5263 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/mobile/time.php b/mobile/time.php index 58661632a..1cda7fb63 100644 --- a/mobile/time.php +++ b/mobile/time.php @@ -119,19 +119,19 @@ $cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; +// Handle time custom fields. $timeCustomFields = array(); -// If we have time custom fields - collect input. -if ($request->isPost()) { - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($request->getParameter($control_name))); - } +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); + $_SESSION[$control_name] = $cl_control_name; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($cl_control_name)); } } diff --git a/time.php b/time.php index a76b470d5..e375e8425 100644 --- a/time.php +++ b/time.php @@ -153,23 +153,21 @@ $cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); $_SESSION['task'] = $cl_task; +// Handle time custom fields. $timeCustomFields = array(); -// If we have time custom fields - collect input. -#if ($request->isPost()) { - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); - $_SESSION[$control_name] = $cl_control_name; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($cl_control_name)); - } +if ($custom_fields && $custom_fields->timeFields) { + foreach ($custom_fields->timeFields as $timeField) { + $control_name = 'time_field_'.$timeField['id']; + $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); + $_SESSION[$control_name] = $cl_control_name; + $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], + 'control_name' => $control_name, + 'label' => $timeField['label'], + 'type' => $timeField['type'], + 'required' => $timeField['required'], + 'value' => trim($cl_control_name)); } -#} +} // Elements of timeRecordForm. $form = new Form('timeRecordForm'); From 070846bb07629367d044a3affbea6f8135040c3f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 31 Jul 2020 15:00:29 +0000 Subject: [PATCH 058/652] Started to use relative values in css for better presentation. --- WEB-INF/templates/footer.tpl | 2 +- default.css | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 1aa8e7ba2..9027eee8e 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {else} - + {/if}
Anuko Time Tracker 1.19.23.5263 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5264 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/default.css b/default.css index 3eac29ec2..3b4921acf 100644 --- a/default.css +++ b/default.css @@ -63,17 +63,17 @@ input[type=checkbox], label { } .systemMenu { - font-size: 11pt; + font-size: 1rem; font-weight: bold; color: white; background-color: black; - margin: 2px 4px 2px 4px; + margin: .1rem .2rem .1rem .2rem; } .mainMenu { - font-size: 11pt; + font-size: 1rem; color: #444444; - margin: 2px 4px 2px 4px; + margin: .1rem .2rem .1rem .2rem; } .onBehalf { From 7f3061d5269131fea433dd6465565c93c9dcbb70 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 31 Jul 2020 15:47:40 +0000 Subject: [PATCH 059/652] Renamed tt_logo.png to just logo.png. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/header.tpl | 2 +- WEB-INF/templates/mobile/header.tpl | 2 +- WEB-INF/templates/work/header.tpl | 2 +- images/{tt_logo.png => logo.png} | Bin 5 files changed, 4 insertions(+), 4 deletions(-) rename images/{tt_logo.png => logo.png} (100%) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 9027eee8e..36d26a192 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {else} - + {/if}
Anuko Time Tracker 1.19.23.5264 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5265 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 4d140ed3e..4e89a8a20 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -45,7 +45,7 @@ {if $user->custom_logo} Time TrackerAnuko Time TrackerAnuko Time Tracker
diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index 6290dd025..e6d661d3a 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -46,7 +46,7 @@ {if $user->custom_logo}
Time TrackerAnuko Time TrackerAnuko Time Tracker
diff --git a/WEB-INF/templates/work/header.tpl b/WEB-INF/templates/work/header.tpl index 084870958..03f986885 100644 --- a/WEB-INF/templates/work/header.tpl +++ b/WEB-INF/templates/work/header.tpl @@ -41,7 +41,7 @@ {if $user->custom_logo}
Time TrackerAnuko Time TrackerAnuko Time Tracker
diff --git a/images/tt_logo.png b/images/logo.png similarity index 100% rename from images/tt_logo.png rename to images/logo.png From f534234e691f5b53ce6dccd3412c42d32f572c9a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 31 Jul 2020 16:33:39 +0000 Subject: [PATCH 060/652] Fixed language for for the login screen. --- WEB-INF/lib/ttUser.class.php | 2 +- WEB-INF/templates/footer.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 58c51c632..331633e11 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -53,7 +53,7 @@ class ttUser { var $group_name = null; // Group name. var $behalf_group_name = null;// Group name, on behalf of which we are working. var $email = null; // User email. - var $lang = 'en'; // Language. + var $lang = null; // Language. var $decimal_mark = '.'; // Decimal separator. var $date_format = null; // Date format. var $time_format = null; // Time format. diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 36d26a192..e1a6031d3 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- {if $can_edit} - - + + {/if} {/foreach} diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl index c064b13de..1e9476c3d 100644 --- a/WEB-INF/templates/expenses.tpl +++ b/WEB-INF/templates/expenses.tpl @@ -207,23 +207,23 @@ function recalculateCost() { {if $show_files} {if $item.has_files} - + {else} - + {/if} {/if} diff --git a/WEB-INF/templates/groups.tpl b/WEB-INF/templates/groups.tpl index 0289ef9ee..7b2a24017 100644 --- a/WEB-INF/templates/groups.tpl +++ b/WEB-INF/templates/groups.tpl @@ -22,8 +22,8 @@ - - + + {/foreach}
Anuko Time Tracker 1.19.23.5265 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5266 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} From 10c01f419f509827c240e46f80e495269c30a6da Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 1 Aug 2020 13:19:49 +0000 Subject: [PATCH 061/652] Fixed broken PDF reposrts after renaming logo image. --- WEB-INF/templates/footer.tpl | 2 +- group_edit.php | 2 +- topdf.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index e1a6031d3..dcf355e63 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - - + + {/foreach}
Anuko Time Tracker 1.19.23.5266 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5267 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/group_edit.php b/group_edit.php index 2196d280b..c8ad2e142 100644 --- a/group_edit.php +++ b/group_edit.php @@ -92,7 +92,7 @@ $cl_uncompleted_indicators = $request->getParameter('uncompleted_indicators'); $cl_confirm_save = $request->getParameter('confirm_save'); } else { - $cl_currency = ($group['currency'] == ''? CURRENCY_DEFAULT : $group['currency']); + $cl_currency = ($group['currency'] == '' ? CURRENCY_DEFAULT : $group['currency']); $cl_lang = $group['lang']; $cl_decimal_mark = $group['decimal_mark']; $cl_date_format = $group['date_format']; diff --git a/topdf.php b/topdf.php index 337a05a41..42c31e07f 100644 --- a/topdf.php +++ b/topdf.php @@ -460,7 +460,7 @@ // Extend TCPDF class so that we can use custom header and footer. class ttPDF extends TCPDF { - public $image_file = 'images/tt_logo.png'; // Image file for the logo in header. + public $image_file = 'images/logo.png'; // Image file for the logo in header. public $page_word = 'Page'; // Localized "Page" word in footer, ex: Page 1/2. // SetImageFile - sets image file name. From e650913e25f14120ac4510a740f4bbc3c19f0e98 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 2 Aug 2020 15:44:40 +0000 Subject: [PATCH 062/652] Added a link explaining tracking mode. --- WEB-INF/templates/footer.tpl | 2 +- WEB-INF/templates/group_edit.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index dcf355e63..53f5fb82a 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
- - + From 3094adc7be3492465d3b7336bdee3df4e0850ea9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 Aug 2020 16:15:17 +0000 Subject: [PATCH 063/652] Changed APP_NAME named constant to DIR_NAME to better reflect its meaning. --- WEB-INF/config.php.dist | 14 +++++++------- WEB-INF/lib/form/DateField.class.php | 4 ++-- WEB-INF/templates/footer.tpl | 2 +- password_reset.php | 4 ++-- readme.txt | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 24dd5a266..9583d59b3 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -50,13 +50,13 @@ define('DSN', 'mysqli://root:no@localhost/dbname?charset=utf8mb4'); define('MULTIORG_MODE', true); -// Application name. -// If you install time tracker into a sub-directory of your site reflect this in the APP_NAME parameter. -// For example, for http://localhost/timetracker/ define APP_NAME as 'timetracker'. +// Directory name. +// If you install time tracker into a sub-directory of your site reflect this in the DIR_NAME parameter. +// For example, for http://localhost/timetracker/ define DIR_NAME as 'timetracker'. // -// define('APP_NAME', 'timetracker'); +// define('DIR_NAME', 'timetracker'); // -define('APP_NAME', ''); +define('DIR_NAME', ''); // WEEKEND_START_DAY @@ -151,7 +151,7 @@ define('AUTH_MODULE', 'db'); // 'type' => 'openldap', // Type of server. openldap type should also work with Sun Directory Server when member_of is empty. // It may work with other (non Windows AD) LDAP servers. For Windows AD use the 'ad' type. // 'base_dn' => 'ou=People,dc=example,dc=com', // Path of user's base distinguished name in LDAP catalog. -// 'user_login_attribute' => 'uid', // LDAP attribute used for login +// 'user_login_attribute' => 'uid', // LDAP attribute used for login. // 'default_domain' => 'example.com', // Default domain. // 'member_of' => array()); // List of groups, membership in which is required for user to be authenticated. @@ -172,7 +172,7 @@ define('AUTH_MODULE', 'db'); // define('DEBUG', false); // Note: enabling DEBUG breaks redirects as debug output is printed before setting redirect header. Do not enable on production systems. -// Team managers can set monthly work hour quota for years between the following values. +// Group managers can set monthly work hour quota for years between the following values. // define('MONTHLY_QUOTA_YEAR_START', 2010); // If nothing is specified, it falls back to 2015. // define('MONTHLY_QUOTA_YEAR_END', 2025); // If nothing is specified, it falls back to 2030. diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php index a197126fb..73c68220a 100644 --- a/WEB-INF/lib/form/DateField.class.php +++ b/WEB-INF/lib/form/DateField.class.php @@ -406,8 +406,8 @@ function adjustiFrame(pickerDiv, iFrameDiv) { $html .= " value=\"".htmlspecialchars($this->getValue())."\""; $html .= ">"; - if (APP_NAME) - $app_root = '/'.APP_NAME; + if (DIR_NAME) + $app_root = '/'.DIR_NAME; $html .= " name."');\">\n"; } diff --git a/WEB-INF/templates/footer.tpl b/WEB-INF/templates/footer.tpl index 53f5fb82a..5a7521eeb 100644 --- a/WEB-INF/templates/footer.tpl +++ b/WEB-INF/templates/footer.tpl @@ -12,7 +12,7 @@
Anuko Time Tracker 1.19.23.5267 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5268 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/WEB-INF/templates/group_edit.tpl b/WEB-INF/templates/group_edit.tpl index c55663ceb..e9b6deb56 100644 --- a/WEB-INF/templates/group_edit.tpl +++ b/WEB-INF/templates/group_edit.tpl @@ -60,7 +60,7 @@ function chLocation(newLocation) { document.location = newLocation; }
{$i18n.form.group_edit.tracking_mode}:{$forms.groupForm.tracking_mode.control}{$forms.groupForm.tracking_mode.control} {$i18n.label.what_is_it}
{$i18n.form.group_edit.record_type}:
- - - + + {/foreach} {/if} diff --git a/WEB-INF/templates/cf_custom_fields.tpl b/WEB-INF/templates/cf_custom_fields.tpl index e64f18157..e056c606b 100644 --- a/WEB-INF/templates/cf_custom_fields.tpl +++ b/WEB-INF/templates/cf_custom_fields.tpl @@ -30,8 +30,8 @@ {/if} - - + + {/foreach} {/if} diff --git a/WEB-INF/templates/cf_dropdown_options.tpl b/WEB-INF/templates/cf_dropdown_options.tpl index b920d733e..d694a1ebc 100644 --- a/WEB-INF/templates/cf_dropdown_options.tpl +++ b/WEB-INF/templates/cf_dropdown_options.tpl @@ -16,8 +16,8 @@ {foreach $options as $key=>$val} - - + + {/foreach} {/if} diff --git a/WEB-INF/templates/clients.tpl b/WEB-INF/templates/clients.tpl index ca93b92f5..cba3256c3 100644 --- a/WEB-INF/templates/clients.tpl +++ b/WEB-INF/templates/clients.tpl @@ -20,8 +20,8 @@ - - + + {/foreach}
Anuko Time Tracker 1.19.23.5268 | Copyright © Anuko | + Anuko Time Tracker 1.19.23.5269 | Copyright © Anuko | {$i18n.footer.credits} | {$i18n.footer.license} | {$i18n.footer.improve} diff --git a/password_reset.php b/password_reset.php index 4d4e24867..bbb54adb5 100644 --- a/password_reset.php +++ b/password_reset.php @@ -100,8 +100,8 @@ $http = 'http'; $cl_subject = $user_i18n->get('form.reset_password.email_subject'); - if (APP_NAME) - $pass_edit_url = $http.'://'.$_SERVER['HTTP_HOST'].'/'.APP_NAME.'/password_change.php?ref='.$temp_ref; + if (DIR_NAME) + $pass_edit_url = $http.'://'.$_SERVER['HTTP_HOST'].'/'.DIR_NAME.'/password_change.php?ref='.$temp_ref; else $pass_edit_url = $http.'://'.$_SERVER['HTTP_HOST'].'/password_change.php?ref='.$temp_ref; diff --git a/readme.txt b/readme.txt index c8929fae4..421a18cdb 100644 --- a/readme.txt +++ b/readme.txt @@ -29,7 +29,7 @@ The general installation procedure looks like this: 5) Create a config file by coping WEB-INF/config.php.dist to WEB-INF/config.php. 6) Change $dsn value in /WEB-INF/config.php file to reflect your database connection parameters (user name and password). 7) If you are upgrading from earlier Time Tracker version run dbinstall.php from your browser and do only the required "Update database structure" steps. -8) If you install time tracker into a sub-directory of your site reflect this in the APP_NAME parameter in /WEB-INF/config.php file. For example, for http://localhost/timetracker/ set APP_NAME = "timetracker". +8) If you install time tracker into a sub-directory of your site reflect this in the DIR_NAME parameter in /WEB-INF/config.php file. For example, for http://localhost/timetracker/ set DIR_NAME = "timetracker". 9) Login to your time tracker site as admin with password "secret" without quotes and create at least one group. 10) Change admin password (on the admin "options" page). You can also use the following SQL console command: update tt_users set password = md5('new_password_here') where login='admin' From 469a150062dc321309af92cfb50f249a8d931d94 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 3 Aug 2020 17:46:26 +0000 Subject: [PATCH 064/652] Shortened images directory name to img to keep things a bit shorter. --- WEB-INF/lib/form/DateField.class.php | 2 +- WEB-INF/templates/admin_groups.tpl | 4 ++-- WEB-INF/templates/cf_custom_fields.tpl | 4 ++-- WEB-INF/templates/cf_dropdown_options.tpl | 4 ++-- WEB-INF/templates/clients.tpl | 8 ++++---- WEB-INF/templates/entity_files.tpl | 4 ++-- WEB-INF/templates/expenses.tpl | 8 ++++---- WEB-INF/templates/groups.tpl | 4 ++-- WEB-INF/templates/header.tpl | 10 +++++----- WEB-INF/templates/invoices.tpl | 2 +- WEB-INF/templates/mobile/header.tpl | 10 +++++----- WEB-INF/templates/mobile/time.tpl | 4 ++-- WEB-INF/templates/notifications.tpl | 4 ++-- WEB-INF/templates/predefined_expenses.tpl | 4 ++-- WEB-INF/templates/projects.tpl | 18 +++++++++--------- WEB-INF/templates/report.tpl | 4 ++-- WEB-INF/templates/roles.tpl | 8 ++++---- WEB-INF/templates/tasks.tpl | 8 ++++---- WEB-INF/templates/templates.tpl | 8 ++++---- WEB-INF/templates/time.tpl | 8 ++++---- WEB-INF/templates/timesheets.tpl | 16 ++++++++-------- WEB-INF/templates/users.tpl | 8 ++++---- WEB-INF/templates/week.tpl | 8 ++++---- WEB-INF/templates/work/admin_work.tpl | 8 ++++---- WEB-INF/templates/work/header.tpl | 10 +++++----- WEB-INF/templates/work/work.tpl | 8 ++++---- {images => img}/1x1.gif | Bin {images => img}/calendar.gif | Bin {images => img}/icon_delete.png | Bin {images => img}/icon_edit.png | Bin {images => img}/icon_file.png | Bin {images => img}/icon_files.png | Bin {images => img}/logo.png | Bin {images => img}/subm_bg.gif | Bin {images => img}/top_bg.gif | Bin initialize.php | 4 ++-- password_change.php | 4 ++-- topdf.php | 6 +++--- 38 files changed, 99 insertions(+), 99 deletions(-) rename {images => img}/1x1.gif (100%) rename {images => img}/calendar.gif (100%) rename {images => img}/icon_delete.png (100%) rename {images => img}/icon_edit.png (100%) rename {images => img}/icon_file.png (100%) rename {images => img}/icon_files.png (100%) rename {images => img}/logo.png (100%) rename {images => img}/subm_bg.gif (100%) rename {images => img}/top_bg.gif (100%) diff --git a/WEB-INF/lib/form/DateField.class.php b/WEB-INF/lib/form/DateField.class.php index 73c68220a..18a3ec475 100644 --- a/WEB-INF/lib/form/DateField.class.php +++ b/WEB-INF/lib/form/DateField.class.php @@ -409,7 +409,7 @@ function adjustiFrame(pickerDiv, iFrameDiv) { if (DIR_NAME) $app_root = '/'.DIR_NAME; - $html .= " name."');\">\n"; + $html .= " name."');\">\n"; } return $html; diff --git a/WEB-INF/templates/admin_groups.tpl b/WEB-INF/templates/admin_groups.tpl index 218fe77cd..9f2ecb6f4 100644 --- a/WEB-INF/templates/admin_groups.tpl +++ b/WEB-INF/templates/admin_groups.tpl @@ -22,8 +22,8 @@ {$group.name|escape} {$group.date} {$group.lang}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
{$i18n.label.type_dropdown} {$i18n.label.configure}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
{$val|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
{$client.name|escape} {$client.address|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
@@ -43,8 +43,8 @@
{$client.name|escape} {$client.address|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/entity_files.tpl b/WEB-INF/templates/entity_files.tpl index fc552b24b..fe5dc5445 100644 --- a/WEB-INF/templates/entity_files.tpl +++ b/WEB-INF/templates/entity_files.tpl @@ -16,8 +16,8 @@
{$file.name|escape} {$file.description|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
{$item.cost}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files} {if $item.approved || $item.invoice_id}   {else} - {$i18n.label.edit} + {$i18n.label.edit} {/if} {if $item.approved || $item.invoice_id}   {else} - {$i18n.label.delete} + {$i18n.label.delete} {/if}
{$subgroup.name|escape} {$subgroup.description|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/header.tpl b/WEB-INF/templates/header.tpl index 4e89a8a20..eaf163824 100644 --- a/WEB-INF/templates/header.tpl +++ b/WEB-INF/templates/header.tpl @@ -34,18 +34,18 @@ {if $user->custom_logo}
{else} - + {/if} - - + + {/foreach}
- + {if $user->custom_logo} {else} - + {/if} @@ -74,7 +74,7 @@ - - - + + {/foreach} {/if} @@ -60,8 +60,8 @@ - - + + {/foreach} diff --git a/WEB-INF/templates/templates.tpl b/WEB-INF/templates/templates.tpl index c1ffff729..fa3faac63 100644 --- a/WEB-INF/templates/templates.tpl +++ b/WEB-INF/templates/templates.tpl @@ -16,8 +16,8 @@
{$template['name']|escape} {$template['description']|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
@@ -37,8 +37,8 @@
{$template['name']|escape} {$template['description']|escape}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl index 377b26c01..d0121d0ee 100644 --- a/WEB-INF/templates/time.tpl +++ b/WEB-INF/templates/time.tpl @@ -155,16 +155,16 @@ {/if} {if $show_files} {if $record.has_files} -
{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files} {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.edit} + {$i18n.label.edit} {if ($record.duration == '0:00' && $record.start <> '')} @@ -177,7 +177,7 @@ {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.delete} + {$i18n.label.delete} {/if}
{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
@@ -86,13 +86,13 @@ {/if} {if $show_files} {if $timesheet.has_files} -
{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/users.tpl b/WEB-INF/templates/users.tpl index 401751fcb..d7d3e3aa7 100644 --- a/WEB-INF/templates/users.tpl +++ b/WEB-INF/templates/users.tpl @@ -35,8 +35,8 @@
{$u.quota_percent}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete} {$u.quota_percent}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete} {if $record.comment}{$record.comment|escape}{else} {/if}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files}{$i18n.label.files} {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.edit} + {$i18n.label.edit} {/if} {if $record.approved || $record.timesheet_id || $record.invoice_id}   {else} - {$i18n.label.delete} + {$i18n.label.delete} {/if}
{$work_item.description|escape} {$work_item.group_name|escape} ({$work_item.site_id}.{$work_item.group_id}) {$work_item.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
@@ -48,8 +48,8 @@
{$offer.description|escape} {$offer.group_name|escape} ({$offer.site_id}.{$offer.group_id}) {$offer.amount_with_currency}{$i18n.label.edit}{$i18n.label.delete}{$i18n.label.edit}{$i18n.label.delete}
diff --git a/WEB-INF/templates/work/header.tpl b/WEB-INF/templates/work/header.tpl index 03f986885..582e76144 100644 --- a/WEB-INF/templates/work/header.tpl +++ b/WEB-INF/templates/work/header.tpl @@ -30,18 +30,18 @@ {if $user->custom_logo}
{else} - + {/if} - + - + {if $show_projects} - + {/if} - +
- + {if $user->custom_logo} {else} - + {/if} @@ -70,7 +70,7 @@ - - + {if $show_projects} - + {/if} - + - + {$forms.taskForm.close} diff --git a/WEB-INF/templates/task_edit2.tpl b/WEB-INF/templates/task_edit2.tpl index 0ec709851..e0a15e693 100644 --- a/WEB-INF/templates/task_edit2.tpl +++ b/WEB-INF/templates/task_edit2.tpl @@ -11,23 +11,23 @@ {$forms.taskForm.description.control}
{$forms.taskForm.status.control}
{$i18n.label.projects}:
{$i18n.label.projects}: {$forms.taskForm.projects.control}
{$i18n.label.required_fields}
{$forms.taskForm.btn_save.control} {$forms.taskForm.btn_copy.control}
{$forms.taskForm.close} diff --git a/WEB-INF/templates/user_add2.tpl b/WEB-INF/templates/user_add2.tpl index 6adc5f7cd..dfb4bfa19 100644 --- a/WEB-INF/templates/user_add2.tpl +++ b/WEB-INF/templates/user_add2.tpl @@ -153,10 +153,10 @@ function handleClientRole() {
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
{$forms.userForm.close} diff --git a/WEB-INF/templates/user_edit2.tpl b/WEB-INF/templates/user_edit2.tpl index ecc0a838e..8a3507e7b 100644 --- a/WEB-INF/templates/user_edit2.tpl +++ b/WEB-INF/templates/user_edit2.tpl @@ -191,10 +191,10 @@ function handleClientRole() {
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
{$forms.userForm.close} diff --git a/initialize.php b/initialize.php index 1b0d371db..d50b940b3 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5375"); +define("APP_VERSION", "1.19.23.5376"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/register.php b/register.php index a036c26d4..3430d4366 100644 --- a/register.php +++ b/register.php @@ -1,30 +1,6 @@ Date: Wed, 25 Nov 2020 15:08:27 +0000 Subject: [PATCH 188/652] Improved styling of the description field. --- default.css | 13 +++++++++++++ initialize.php | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index 3873051e6..a1784c5bc 100644 --- a/default.css +++ b/default.css @@ -239,6 +239,19 @@ input.password-field { width: 237px; } +#description { + width: 220px; + border-radius: 4px; + border: 1px solid #c9c9c9; + padding: .4rem; +} + +#description:focus { + background-color: yellow; + border: 1px solid black; + outline: none; +} + .chart-image { width: 300px; height: 300px; diff --git a/initialize.php b/initialize.php index d50b940b3..3de6ba486 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5376"); +define("APP_VERSION", "1.19.23.5377"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ccd704eabdc20299faffe089feeb555b292ca7b4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 15:47:43 +0000 Subject: [PATCH 189/652] Improving style of file upload control. --- default.css | 7 +++++++ initialize.php | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index a1784c5bc..5e1334bc8 100644 --- a/default.css +++ b/default.css @@ -235,6 +235,13 @@ input.password-field { width: 220px; } +input[type=file] { + width: 220px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + .dropdown-field { width: 237px; } diff --git a/initialize.php b/initialize.php index 3de6ba486..092bf840f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5377"); +define("APP_VERSION", "1.19.23.5378"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1bbfcb4c137b50a8019151aeeef9b51c711409d4 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 16:25:29 +0000 Subject: [PATCH 190/652] Some more progress on styles. --- WEB-INF/lib/form/PasswordField.class.php | 28 ++---------------------- default.css | 13 +++++------ initialize.php | 2 +- 3 files changed, 8 insertions(+), 35 deletions(-) diff --git a/WEB-INF/lib/form/PasswordField.class.php b/WEB-INF/lib/form/PasswordField.class.php index 579be5edb..ff6802c90 100644 --- a/WEB-INF/lib/form/PasswordField.class.php +++ b/WEB-INF/lib/form/PasswordField.class.php @@ -1,30 +1,6 @@ Date: Wed, 25 Nov 2020 16:41:48 +0000 Subject: [PATCH 191/652] Improved style of the note field. --- default.css | 9 +++++++++ initialize.php | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index e2b634693..da21649f7 100644 --- a/default.css +++ b/default.css @@ -295,6 +295,15 @@ input[type="file"] { margin: 0; height: 4rem; resize: none; + border-radius: 4px; + border: 1px solid #c9c9c9; + padding: .4rem; +} + +#note:focus { + background-color: yellow; + border: 1px solid black; + outline: none; } .day-totals { diff --git a/initialize.php b/initialize.php index 5b6cc1cb3..c98543252 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5379"); +define("APP_VERSION", "1.19.23.5380"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 7322bce85707960781c50df141e1c78cac7b675f Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 17:26:45 +0000 Subject: [PATCH 192/652] Improved spacing between menu items on site-map.php. --- WEB-INF/templates/site_map.tpl | 76 +++++++++++++++++----------------- default.css | 9 ++++ initialize.php | 2 +- 3 files changed, 48 insertions(+), 39 deletions(-) diff --git a/WEB-INF/templates/site_map.tpl b/WEB-INF/templates/site_map.tpl index 48b8d40c1..c951f2b99 100644 --- a/WEB-INF/templates/site_map.tpl +++ b/WEB-INF/templates/site_map.tpl @@ -1,90 +1,90 @@ {if $authenticated} {if $user->can('administer_site')} {* sub menu for admin *} -

- {$i18n.menu.groups}
- {$i18n.menu.options}
+

+ + {if isTrue('WORK_SERVER_ADMINISTRATION')} - {$i18n.label.work}
+ {/if} -

+
{* end of sub menu for admin *} {* main menu for admin *} -

- {$i18n.menu.logout}
- {$i18n.menu.forum}
- {$i18n.menu.help}
-

+ {* end of main menu for admin *} {else} {* sub menu for authorized user *} -

+

{if $user->exists() && ($user->can('track_own_time') || $user->can('track_time'))} - {$i18n.menu.time}
+ {if $user->isPluginEnabled('wv') && $user->isOptionEnabled('week_menu')} - {$i18n.menu.week}
+ {/if} {/if} {if $user->exists() && $user->isPluginEnabled('ex') && ($user->can('track_own_expenses') || $user->can('track_expenses'))} - {$i18n.menu.expenses}
+ {/if} {if $user->exists() && ($user->can('view_own_reports') || $user->can('view_reports') || $user->can('view_all_reports') || $user->can('view_client_reports'))} - {$i18n.menu.reports}
+ {/if} {if $user->exists() && $user->isPluginEnabled('ts') && ($user->can('track_own_time') || $user->can('track_time'))} - {$i18n.menu.timesheets}
+ {/if} {if $user->exists() && $user->isPluginEnabled('iv') && ($user->can('manage_invoices') || $user->can('view_client_invoices'))} - {$i18n.title.invoices}
+ {/if} {if ($user->exists() && $user->isPluginEnabled('ch') && ($user->can('view_own_charts') || $user->can('view_charts'))) && (constant('MODE_PROJECTS') == $user->getTrackingMode() || constant('MODE_PROJECTS_AND_TASKS') == $user->getTrackingMode() || $user->isPluginEnabled('cl'))} - {$i18n.menu.charts}
+ {/if} {if ($user->can('view_own_projects') || $user->can('manage_projects')) && (constant('MODE_PROJECTS') == $user->getTrackingMode() || constant('MODE_PROJECTS_AND_TASKS') == $user->getTrackingMode())} - {$i18n.menu.projects}
+ {/if} {if (constant('MODE_PROJECTS_AND_TASKS') == $user->getTrackingMode() && ($user->can('view_own_tasks') || $user->can('manage_tasks')))} - {$i18n.menu.tasks}
+ {/if} {if $user->can('view_users') || $user->can('manage_users')} - {$i18n.menu.users}
+ {/if} {if $user->isPluginEnabled('cl') && ($user->can('view_own_clients') || $user->can('manage_clients'))} - {$i18n.menu.clients}
+ {/if} {if $user->can('export_data')} - {$i18n.menu.export}
+ {/if} -

+
{* end of sub menu for authorized user *} {* main menu for authorized user *} -

- {$i18n.menu.logout}
+

+ {if $user->exists() && $user->can('manage_own_settings')} - {$i18n.menu.profile}
+ {/if} {if $user->can('manage_basic_settings')} - {$i18n.menu.group}
+ {/if} {if $user->can('manage_features')} - {$i18n.menu.plugins}
+ {/if} - {$i18n.menu.forum}
- {$i18n.menu.help}
-

+ + +
{* end of main menu for authorized user *} {/if} {else} {* main menu for non authorized user *} -

- {$i18n.menu.login}
+

+ {if isTrue('MULTIORG_MODE') && constant('AUTH_MODULE') == 'db'} - {$i18n.menu.register}
+ {/if} - {$i18n.menu.forum}
- {$i18n.menu.help}
-

+ + +
{* end of main menu for non authorized user *} {/if} diff --git a/default.css b/default.css index da21649f7..820382bdf 100644 --- a/default.css +++ b/default.css @@ -358,6 +358,15 @@ input[type="file"] { margin-right: auto; } +.sitemap-item-group { + margin-top: 2rem; + margin-bottom: 2rem; +} + +.sitemap-item { + margin: .4rem; +} + @media screen and (max-width: 600px) { .large-screen-label { diff --git a/initialize.php b/initialize.php index c98543252..f2b193e74 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5380"); +define("APP_VERSION", "1.19.23.5381"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 56c1de5a9c853ad16a350c36669901f3acfa26c9 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 18:17:27 +0000 Subject: [PATCH 193/652] Cosmetic. Added copytight notices on refactored templates. --- WEB-INF/templates/client_add2.tpl | 3 +++ WEB-INF/templates/client_delete2.tpl | 3 +++ WEB-INF/templates/client_edit2.tpl | 3 +++ WEB-INF/templates/clients2.tpl | 3 +++ WEB-INF/templates/entity_files2.tpl | 3 +++ WEB-INF/templates/expense_delete2.tpl | 3 +++ WEB-INF/templates/expense_edit2.tpl | 3 +++ WEB-INF/templates/expenses2.tpl | 3 +++ WEB-INF/templates/login.db2.tpl | 3 +++ WEB-INF/templates/login.ldap2.tpl | 3 +++ WEB-INF/templates/login2.tpl | 3 +++ WEB-INF/templates/password_change2.tpl | 3 +++ WEB-INF/templates/password_reset2.tpl | 3 +++ WEB-INF/templates/project_add2.tpl | 3 +++ WEB-INF/templates/project_delete2.tpl | 3 +++ WEB-INF/templates/project_edit2.tpl | 3 +++ WEB-INF/templates/register2.tpl | 3 +++ WEB-INF/templates/swap_roles2.tpl | 3 +++ WEB-INF/templates/task_add2.tpl | 3 +++ WEB-INF/templates/task_delete2.tpl | 3 +++ WEB-INF/templates/task_edit2.tpl | 3 +++ WEB-INF/templates/tasks2.tpl | 3 +++ WEB-INF/templates/time2.tpl | 3 +++ WEB-INF/templates/time_delete2.tpl | 3 +++ WEB-INF/templates/time_edit2.tpl | 3 +++ WEB-INF/templates/user_add2.tpl | 3 +++ WEB-INF/templates/user_delete2.tpl | 3 +++ WEB-INF/templates/user_edit2.tpl | 3 +++ WEB-INF/templates/users2.tpl | 3 +++ initialize.php | 2 +- 30 files changed, 88 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/client_add2.tpl b/WEB-INF/templates/client_add2.tpl index e22081ef4..5fe001b23 100644 --- a/WEB-INF/templates/client_add2.tpl +++ b/WEB-INF/templates/client_add2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.clientForm.open} diff --git a/WEB-INF/templates/client_delete2.tpl b/WEB-INF/templates/client_delete2.tpl index bc583ea66..47506f79b 100644 --- a/WEB-INF/templates/client_delete2.tpl +++ b/WEB-INF/templates/client_delete2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.clientDeleteForm.open}
diff --git a/WEB-INF/templates/client_edit2.tpl b/WEB-INF/templates/client_edit2.tpl index 935c6a1e5..91f2b1c39 100644 --- a/WEB-INF/templates/client_edit2.tpl +++ b/WEB-INF/templates/client_edit2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.clientForm.open}
{$i18n.form.client.client_to_delete}:
diff --git a/WEB-INF/templates/clients2.tpl b/WEB-INF/templates/clients2.tpl index 1ec69df2f..9f7d4064b 100644 --- a/WEB-INF/templates/clients2.tpl +++ b/WEB-INF/templates/clients2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + diff --git a/WEB-INF/templates/entity_files2.tpl b/WEB-INF/templates/entity_files2.tpl index 9d48e24c1..d6b892b38 100644 --- a/WEB-INF/templates/entity_files2.tpl +++ b/WEB-INF/templates/entity_files2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {if $files}
diff --git a/WEB-INF/templates/expense_delete2.tpl b/WEB-INF/templates/expense_delete2.tpl index 9b9bab838..a9ea04d10 100644 --- a/WEB-INF/templates/expense_delete2.tpl +++ b/WEB-INF/templates/expense_delete2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.expenseItemForm.open}
diff --git a/WEB-INF/templates/expense_edit2.tpl b/WEB-INF/templates/expense_edit2.tpl index 3cea79482..ec921e007 100644 --- a/WEB-INF/templates/expense_edit2.tpl +++ b/WEB-INF/templates/expense_edit2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 33aa428e7..487bff7cf 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {include file="time_script.tpl"} {if $show_navigation} diff --git a/WEB-INF/templates/time_delete2.tpl b/WEB-INF/templates/time_delete2.tpl index 20acb783c..59d9039d1 100644 --- a/WEB-INF/templates/time_delete2.tpl +++ b/WEB-INF/templates/time_delete2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {$forms.timeRecordForm.open}
diff --git a/WEB-INF/templates/time_edit2.tpl b/WEB-INF/templates/time_edit2.tpl index dc3d78cd0..8a25c43cf 100644 --- a/WEB-INF/templates/time_edit2.tpl +++ b/WEB-INF/templates/time_edit2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + {include file="time_script.tpl"} {* Conditional include of confirmSave handler. *} diff --git a/WEB-INF/templates/user_add2.tpl b/WEB-INF/templates/user_add2.tpl index dfb4bfa19..ad421b9e8 100644 --- a/WEB-INF/templates/user_add2.tpl +++ b/WEB-INF/templates/user_add2.tpl @@ -1,3 +1,6 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + diff --git a/initialize.php b/initialize.php index f2b193e74..42b94a865 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5381"); +define("APP_VERSION", "1.19.23.5382"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 25202d51cbcbe494fb4a5a30cf90687736d64342 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 25 Nov 2020 18:25:02 +0000 Subject: [PATCH 194/652] Cleanup. Removed no longer used legacy mobile client pages and templates. --- WEB-INF/templates/mobile/client_add.tpl | 37 ------ WEB-INF/templates/mobile/client_delete.tpl | 25 ---- WEB-INF/templates/mobile/client_edit.tpl | 41 ------- WEB-INF/templates/mobile/clients.tpl | 66 ---------- WEB-INF/templates/mobile/header.tpl | 3 - initialize.php | 2 +- mobile/client_add.php | 94 -------------- mobile/client_delete.php | 78 ------------ mobile/client_edit.php | 135 --------------------- mobile/clients.php | 54 --------- 10 files changed, 1 insertion(+), 534 deletions(-) delete mode 100644 WEB-INF/templates/mobile/client_add.tpl delete mode 100644 WEB-INF/templates/mobile/client_delete.tpl delete mode 100644 WEB-INF/templates/mobile/client_edit.tpl delete mode 100644 WEB-INF/templates/mobile/clients.tpl delete mode 100644 mobile/client_add.php delete mode 100644 mobile/client_delete.php delete mode 100644 mobile/client_edit.php delete mode 100644 mobile/clients.php diff --git a/WEB-INF/templates/mobile/client_add.tpl b/WEB-INF/templates/mobile/client_add.tpl deleted file mode 100644 index db10ede45..000000000 --- a/WEB-INF/templates/mobile/client_add.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{$forms.clientForm.open} -
- - - -
- - - - - - - - - - - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - -
{$i18n.label.client_name} (*):{$forms.clientForm.name.control}
{$i18n.label.client_address}:{$forms.clientForm.address.control}
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->getDecimalMark()}00)
{$i18n.label.required_fields}
 
{$i18n.label.projects}:{$forms.clientForm.projects.control}
 
{$forms.clientForm.btn_submit.control}
-
-{$forms.clientForm.close} diff --git a/WEB-INF/templates/mobile/client_delete.tpl b/WEB-INF/templates/mobile/client_delete.tpl deleted file mode 100644 index f40b94c12..000000000 --- a/WEB-INF/templates/mobile/client_delete.tpl +++ /dev/null @@ -1,25 +0,0 @@ -{$forms.clientDeleteForm.open} - - - - -
- - - - - - - - - - - - - - - - -
{$i18n.form.client.client_to_delete}:{$client_to_delete|escape}
{$i18n.form.client.client_entries}:{$forms.clientDeleteForm.delete_client_entries.control}
 
{$forms.clientDeleteForm.btn_delete.control}  {$forms.clientDeleteForm.btn_cancel.control}
-
-{$forms.clientDeleteForm.close} diff --git a/WEB-INF/templates/mobile/client_edit.tpl b/WEB-INF/templates/mobile/client_edit.tpl deleted file mode 100644 index 4f70ced7a..000000000 --- a/WEB-INF/templates/mobile/client_edit.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{$forms.clientForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - -{if $show_projects} - - - - -{/if} - - - - -
{$i18n.label.client_name} (*):{$forms.clientForm.name.control}
{$i18n.label.client_address}:{$forms.clientForm.address.control}
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->decimal_mark}00)
{$i18n.label.status}:{$forms.clientForm.status.control}
{$i18n.label.required_fields}
 
{$i18n.label.projects}:{$forms.clientForm.projects.control}
 
{$forms.clientForm.btn_save.control} {$forms.clientForm.btn_copy.control} {$forms.clientForm.btn_delete.control}
-
-{$forms.clientForm.close} diff --git a/WEB-INF/templates/mobile/clients.tpl b/WEB-INF/templates/mobile/clients.tpl deleted file mode 100644 index 34f53a919..000000000 --- a/WEB-INF/templates/mobile/clients.tpl +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - -
-{if $user->can('manage_clients')} - - {if $inactive_clients} - - {/if} - - - - - {foreach $active_clients as $client} - - - - - {/foreach} -
{$i18n.form.clients.active_clients}
{$i18n.label.person_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}
- - - -

- - {if $inactive_clients} - - - - - - - {foreach $inactive_clients as $client} - - - - - {/foreach} -
{$i18n.form.clients.inactive_clients}
{$i18n.label.person_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}
- - - -

- {/if} -{else} - - - - - - {if $active_clients} - {foreach $active_clients as $client} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}
-{/if} -
diff --git a/WEB-INF/templates/mobile/header.tpl b/WEB-INF/templates/mobile/header.tpl index ccea5e7e1..d4cf2c53b 100644 --- a/WEB-INF/templates/mobile/header.tpl +++ b/WEB-INF/templates/mobile/header.tpl @@ -91,9 +91,6 @@ {/if} {if $user->can('view_users') || $user->can('manage_users')} {$i18n.menu.users} - {/if} - {if $user->isPluginEnabled('cl') && ($user->can('view_own_clients') || $user->can('manage_clients'))} - {$i18n.menu.clients} {/if}
{$i18n.label.required_fields}
{$i18n.label.projects}:
{$i18n.label.projects}:
{$i18n.label.required_fields}
{$i18n.label.projects}:
{$i18n.label.projects}:
{$i18n.label.users}:
{$i18n.label.users}:
{$i18n.label.tasks}:
{$i18n.label.tasks}:
{$i18n.label.users}:
{$i18n.label.users}:
{$i18n.label.tasks}:
{$i18n.label.tasks}:
{$i18n.label.projects}:
{$i18n.label.projects}:
{$i18n.label.projects}:
{$i18n.label.projects}:
@@ -37,8 +38,8 @@ License: See license.txt *} +
{$forms.fileUploadForm.description.control}
{$forms.fileUploadForm.btn_submit.control}
-
{$forms.fileUploadForm.btn_submit.control}
{$forms.fileUploadForm.close} {/if} diff --git a/default.css b/default.css index fea2e8da5..8079296aa 100644 --- a/default.css +++ b/default.css @@ -128,8 +128,7 @@ div.page-hint { margin-top: .5rem; margin-left: auto; margin-right: auto; - padding: .5rem; - background-color: #f0f0f0; + border-collapse: collapse; } .x-scrollable-table th { @@ -140,6 +139,9 @@ div.page-hint { padding: .25rem; } +.x-scrollable-table tr:nth-child(even) {background: #ffffff} +.x-scrollable-table tr:nth-child(odd) {background: #f5f5f5} + .text-cell { text-align: left; } diff --git a/initialize.php b/initialize.php index 837759f2b..2cd8198bb 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5390"); +define("APP_VERSION", "1.19.23.5391"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 83fc6da0ea7e7e2ef1e23653e9d442efa303c32e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 18:36:05 +0000 Subject: [PATCH 203/652] Some style fixes for calendar and x-scrollable-table. --- default.css | 5 +++++ initialize.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index 8079296aa..c4f8ac542 100644 --- a/default.css +++ b/default.css @@ -133,6 +133,7 @@ div.page-hint { .x-scrollable-table th { white-space: nowrap; + padding: .25rem; } .x-scrollable-table td { @@ -281,6 +282,10 @@ input[type="file"] { margin-right: auto; } +.small-screen-calendar a:focus, .large-screen-calendar a:focus { + outline: none; +} + .large-screen-calendar { display: block; width: 210px; diff --git a/initialize.php b/initialize.php index 2cd8198bb..627153414 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5391"); +define("APP_VERSION", "1.19.23.5392"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ad9d244216139d0c9e0aec21a00905eb3198a897 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 20:35:20 +0000 Subject: [PATCH 204/652] Fixed an issue with incorrect column span. --- initialize.php | 2 +- time.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/initialize.php b/initialize.php index 627153414..79d1105fe 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5392"); +define("APP_VERSION", "1.19.23.5393"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 27c21d431..6bd10ad53 100644 --- a/time.php +++ b/time.php @@ -86,8 +86,7 @@ } if ($showProject) $colspan++; if ($showTask) $colspan++; - if ($showStart) $colspan++; - if ($showFinish) $colspan++; + if ($showStart) $colspan += 2; // Another for show finish. $colspan++; // There is always a duration. if ($showFiles) $colspan++; $colspan++; // There is always an edit column. From 9d37ef6efab76fa1f94cb7b534f6c31cb2d227f0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 27 Nov 2020 21:02:08 +0000 Subject: [PATCH 205/652] Improved UI for user pages. --- WEB-INF/templates/user_add2.tpl | 1 + WEB-INF/templates/user_edit2.tpl | 1 + default.css | 4 ++++ initialize.php | 2 +- user_add.php | 1 + user_edit.php | 1 + 6 files changed, 9 insertions(+), 1 deletion(-) diff --git a/WEB-INF/templates/user_add2.tpl b/WEB-INF/templates/user_add2.tpl index ad421b9e8..7413fd2a2 100644 --- a/WEB-INF/templates/user_add2.tpl +++ b/WEB-INF/templates/user_add2.tpl @@ -147,6 +147,7 @@ function handleClientRole() { {if $show_projects} +
diff --git a/WEB-INF/templates/user_edit2.tpl b/WEB-INF/templates/user_edit2.tpl index 107891777..5adad2e9f 100644 --- a/WEB-INF/templates/user_edit2.tpl +++ b/WEB-INF/templates/user_edit2.tpl @@ -185,6 +185,7 @@ function handleClientRole() { {if $show_projects} +
diff --git a/default.css b/default.css index c4f8ac542..8159cab08 100644 --- a/default.css +++ b/default.css @@ -234,6 +234,10 @@ input[type="text"] { width: 220px; } +input[type="text"].project-rate-field { + width: 100px; +} + input[type="password"] { width: 220px; } diff --git a/initialize.php b/initialize.php index 79d1105fe..68f36434c 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5393"); +define("APP_VERSION", "1.19.23.5394"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_add.php b/user_add.php index e87fed752..046ecdb87 100644 --- a/user_add.php +++ b/user_add.php @@ -123,6 +123,7 @@ class RateCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { global $assigned_projects; $field = new FloatField('rate_'.$table->getValueAtName($row, 'id')); + $field->setCssClass('project-rate-field'); $field->setFormName($table->getFormName()); $field->setSize(5); $field->setFormat('.2'); diff --git a/user_edit.php b/user_edit.php index 17c8292e3..be0f13e26 100644 --- a/user_edit.php +++ b/user_edit.php @@ -156,6 +156,7 @@ function render(&$table, $value, $row, $column, $selected = false) { global $assigned_projects; $field = new FloatField('rate_'.$table->getValueAtName($row,'id')); + $field->setCssClass('project-rate-field'); $field->setFormName($table->getFormName()); $field->setSize(5); $field->setFormat('.2'); From 26058d1c778fba9ecdbef81453eaf64ed13f3607 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 29 Nov 2020 23:36:30 +0000 Subject: [PATCH 206/652] Improved presentation of project rates table. --- WEB-INF/lib/form/Table.class.php | 9 ++++----- default.css | 6 +++++- initialize.php | 2 +- user_edit.php | 5 +++-- week.php | 3 ++- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/form/Table.class.php b/WEB-INF/lib/form/Table.class.php index 7bcd78be8..1995b7dea 100644 --- a/WEB-INF/lib/form/Table.class.php +++ b/WEB-INF/lib/form/Table.class.php @@ -47,10 +47,9 @@ class Table extends FormElement { var $mHeaderOptions = array(); var $mProccessed = false; - function __construct($name, $cssClass = null) { + function __construct($name) { $this->class = 'Table'; $this->name = $name; - $this->cssClass = $cssClass; } function setKeyField($value) { @@ -123,15 +122,15 @@ function getHtml() { if ($this->mInteractive) $html .= $this->_addJavaScript(); $html .= "cssClass) { - $html .= " class=\"".$this->cssClass."\""; + if ($this->css_class) { + $html .= " class=\"".$this->css_class."\""; } if (count($this->mTableOptions) > 0) { foreach ($this->mTableOptions as $k=>$v) { $html .= " $k=\"$v\""; } } else { - $html .= " border=\"1\""; + // $html .= " border=\"1\""; } if ($this->mWidth!="") $html .= " width=\"".$this->mWidth."\""; $html .= ">\n"; diff --git a/default.css b/default.css index 8159cab08..2a6b06382 100644 --- a/default.css +++ b/default.css @@ -108,6 +108,10 @@ div.page-hint { margin-top: 1rem; } +.project-rate-table { + width: 300px; +} + .centered-table { margin-top: .5rem; margin-left: auto; @@ -235,7 +239,7 @@ input[type="text"] { } input[type="text"].project-rate-field { - width: 100px; + width: 50px; } input[type="password"] { diff --git a/initialize.php b/initialize.php index 68f36434c..ca81befef 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5394"); +define("APP_VERSION", "1.19.23.5395"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_edit.php b/user_edit.php index be0f13e26..b0868c4e5 100644 --- a/user_edit.php +++ b/user_edit.php @@ -146,7 +146,7 @@ // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200)); + //$this->setOptions(array('width'=>200)); $this->setValue(''); return $this->toString(); } @@ -169,8 +169,9 @@ function render(&$table, $value, $row, $column, $selected = false) { } // Create projects table. $table = new Table('projects'); +$table->setCssClass('project-rate-table'); $table->setIAScript('setRate'); -$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); +//$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); $table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); diff --git a/week.php b/week.php index d86e0c99c..fee395d66 100644 --- a/week.php +++ b/week.php @@ -275,7 +275,8 @@ function render(&$table, $value, $row, $column, $selected = false) { } // Create week_durations table. -$table = new Table('week_durations', 'week_view_table'); +$table = new Table('week_durations'); +// $table->setCssClass('week_view_table'); // Currently not used. Fix this. $table->setTableOptions(array('width'=>'100%','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); $table->setRowOptions(array('class'=>'tableHeaderCentered')); $table->setData($dataArray); From 374853526cac28b5b38fc96638601eb550058564 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 1 Dec 2020 18:23:14 +0000 Subject: [PATCH 207/652] Resuming work on styles. --- WEB-INF/lib/form/Table.class.php | 3 +-- initialize.php | 2 +- user_edit.php | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/WEB-INF/lib/form/Table.class.php b/WEB-INF/lib/form/Table.class.php index 1995b7dea..c83d90bd8 100644 --- a/WEB-INF/lib/form/Table.class.php +++ b/WEB-INF/lib/form/Table.class.php @@ -129,9 +129,8 @@ function getHtml() { foreach ($this->mTableOptions as $k=>$v) { $html .= " $k=\"$v\""; } - } else { - // $html .= " border=\"1\""; } + if ($this->mWidth!="") $html .= " width=\"".$this->mWidth."\""; $html .= ">\n"; diff --git a/initialize.php b/initialize.php index ca81befef..daa1b0522 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5395"); +define("APP_VERSION", "1.19.23.5396"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_edit.php b/user_edit.php index b0868c4e5..c270243ad 100644 --- a/user_edit.php +++ b/user_edit.php @@ -171,8 +171,6 @@ function render(&$table, $value, $row, $column, $selected = false) { $table = new Table('projects'); $table->setCssClass('project-rate-table'); $table->setIAScript('setRate'); -//$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); $table->setValue($cl_projects); From 5d1667d8de0bf0583234d750d2123f5c40962246 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 1 Dec 2020 18:33:13 +0000 Subject: [PATCH 208/652] Improved styles on user_add.php. --- default.css | 5 +++++ initialize.php | 2 +- user_add.php | 4 +--- user_edit.php | 2 -- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/default.css b/default.css index 2a6b06382..2aa8335f8 100644 --- a/default.css +++ b/default.css @@ -110,6 +110,11 @@ div.page-hint { .project-rate-table { width: 300px; + border-collapse: collapse; +} + +.project-rate-table td { + padding: .2rem; } .centered-table { diff --git a/initialize.php b/initialize.php index daa1b0522..aced0690c 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5396"); +define("APP_VERSION", "1.19.23.5397"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/user_add.php b/user_add.php index 046ecdb87..7b7b72ed8 100644 --- a/user_add.php +++ b/user_add.php @@ -114,7 +114,6 @@ // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200)); $this->setValue(''); return $this->toString(); } @@ -136,9 +135,8 @@ function render(&$table, $value, $row, $column, $selected = false) { } // Create projects table. $table = new Table('projects'); +$table->setCssClass('project-rate-table'); $table->setIAScript('setDefaultRate'); -$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); $table->setData($projects); $table->setKeyField('id'); $table->setValue($cl_projects); diff --git a/user_edit.php b/user_edit.php index c270243ad..b1f1e65e2 100644 --- a/user_edit.php +++ b/user_edit.php @@ -146,7 +146,6 @@ // Define classes for the projects table. class NameCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { - //$this->setOptions(array('width'=>200)); $this->setValue(''); return $this->toString(); } @@ -154,7 +153,6 @@ function render(&$table, $value, $row, $column, $selected = false) { class RateCellRenderer extends DefaultCellRenderer { function render(&$table, $value, $row, $column, $selected = false) { global $assigned_projects; - $field = new FloatField('rate_'.$table->getValueAtName($row,'id')); $field->setCssClass('project-rate-field'); $field->setFormName($table->getFormName()); From 529edc11b2f3476cae0a976ff40bdd5b62e4cbd2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 1 Dec 2020 22:03:35 +0000 Subject: [PATCH 209/652] Some cleanup and commenting in css. --- WEB-INF/templates/charts2.tpl | 4 +- default.css | 92 ++++++++++++++++++++++------------- initialize.php | 2 +- 3 files changed, 61 insertions(+), 37 deletions(-) diff --git a/WEB-INF/templates/charts2.tpl b/WEB-INF/templates/charts2.tpl index 7f4c3844a..6e9f1756d 100644 --- a/WEB-INF/templates/charts2.tpl +++ b/WEB-INF/templates/charts2.tpl @@ -53,7 +53,7 @@ function adjustTodayLinks() { -
+ {section name=i loop=$totals} {if $smarty.section.i.index <= 12} @@ -68,7 +68,7 @@ function adjustTodayLinks() {
-
+ {section name=i loop=$totals} {if $smarty.section.i.index <= 12} diff --git a/default.css b/default.css index 2aa8335f8..2262acf67 100644 --- a/default.css +++ b/default.css @@ -8,57 +8,53 @@ body { background-color: white; } +/* logo on top of pages */ div.logo { padding: .5rem; text-align: center; background-color: #a6ccf7; } +/* top menu bar for large screens */ div.top-menu-large-screen { background-color: black; display: block; } -.top-submenu-large-screen { +/* submenu for large screens */ +div.top-submenu-large-screen { background-color: #d9d9d9; display: block; } +/* top menu for small screens */ div.top-menu-small-screen { background-color: black; display: none; } -div.top-menu-small-screen a { +/* top menu items */ +div.top-menu-large-screen a, div.top-menu-small-screen a { font-size: 1rem; font-weight: bold; color: white; margin: .1rem .2rem .1rem .2rem; } -div.top-menu-large-screen a { - font-size: 1rem; - font-weight: bold; - color: white; - margin: .1rem .2rem .1rem .2rem; -} - -.top-menu-table { - margin-left: auto; - margin-right: auto; -} - -.top-submenu-table { +/* top menu tables */ +.top-menu-table, .top-submenu-table { margin-left: auto; margin-right: auto; } +/* top submenu items */ .top-submenu-large-screen a { font-size: 1rem; color: #444444; margin: .1rem .2rem .1rem .2rem; } +/* page title div */ div.page-title { font-size: 12pt; font-weight: bold; @@ -69,45 +65,60 @@ div.page-title { margin-bottom: .2rem; } +/* user details div */ div.user-details { text-align: center; padding: .2rem; } +/* page errors div */ .page-errors { margin-top: .5rem; text-align: center; color: red; } +/* page messages div */ .page-messages { margin-top: .5rem; text-align: center; color: blue; } +/* page content div */ .page-content { text-align: center; } +/* vertical separator for controls on forms for both large and small screens */ .form-control-separator { height: .5rem; } +/* vertical separator for controls on small screens */ +.small-screen-form-control-separator { + height: .25rem; + display: none; +} + +/* "about" text div on login page */ div#LoginAboutText { padding: 1rem; margin-left:auto; margin-right:auto; } +/* default domain text div for ldap login */ #ldapDefaultDomain { color: #777777; } +/* page hint div to display on top of some pages to clarify things */ div.page-hint { margin-top: 1rem; } +/* project rate table for user add and user edit pages */ .project-rate-table { width: 300px; border-collapse: collapse; @@ -117,21 +128,15 @@ div.page-hint { padding: .2rem; } +/* a table to display controls centered horizontally */ .centered-table { + display: inline-block; margin-top: .5rem; margin-left: auto; margin-right: auto; - display: inline-block; -} - -.chart-list { - border-spacing: .2rem; -} - -.record-list { - margin: 1rem; } +/* a table to hold things that may not fit into available screen width */ .x-scrollable-table { display: inline-block; margin-top: .5rem; @@ -152,40 +157,59 @@ div.page-hint { .x-scrollable-table tr:nth-child(even) {background: #ffffff} .x-scrollable-table tr:nth-child(odd) {background: #f5f5f5} +/* a text cell in tables */ .text-cell { text-align: left; } +/* time cell in tables */ .time-cell { text-align: right; } +/* text cell for note header when we display notes on separate rows */ .note-header-cell { text-align: right; } +/* control labels for large screens */ .large-screen-label { text-align: right; vertical-align: middle; display: table-cell; } -.large-screen-chart-list { +/* control labels for small screens */ +.small-screen-label { + text-align: left; + display: none; +} + +/* list of items displayed in a chart on large screens */ +.large-screen-chart-items-list { display: table-cell; } -.small-screen-chart-list { +/* list of items displayed in a chart on small screens */ +.small-screen-chart-items-list { display: none; } -.small-screen-label { - text-align: left; - display: none; +/* a div to display a chart in */ +div.chart { + padding-left: 1rem; + padding-right: 1rem; } -.small-screen-form-control-separator { - height: .25rem; - display: none; + + +/* TODO: work in progress below... */ +.chart-list { + border-spacing: .2rem; +} + +.record-list { + margin: 1rem; } .page-content input { @@ -393,11 +417,11 @@ input[type="file"] { display: none; } - .large-screen-chart-list { + .large-screen-chart-items-list { display: none; } - .small-screen-chart-list { + .small-screen-chart-items-list { display: table-cell; } diff --git a/initialize.php b/initialize.php index aced0690c..c33acb839 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5397"); +define("APP_VERSION", "1.19.23.5398"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 13bc4e28d73abdc10b4c02f264161719b6bc7866 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 2 Dec 2020 18:32:30 +0000 Subject: [PATCH 210/652] Some cleanup and commenting in styles. --- WEB-INF/templates/charts2.tpl | 4 ++-- default.css | 10 ++++++---- initialize.php | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/WEB-INF/templates/charts2.tpl b/WEB-INF/templates/charts2.tpl index 6e9f1756d..ff15ea8f2 100644 --- a/WEB-INF/templates/charts2.tpl +++ b/WEB-INF/templates/charts2.tpl @@ -54,7 +54,7 @@ function adjustTodayLinks() {
- +
{section name=i loop=$totals} {if $smarty.section.i.index <= 12} @@ -69,7 +69,7 @@ function adjustTodayLinks() {
{$totals[i].name|escape}
- +
{section name=i loop=$totals} {if $smarty.section.i.index <= 12} diff --git a/default.css b/default.css index 2262acf67..518f200db 100644 --- a/default.css +++ b/default.css @@ -145,15 +145,18 @@ div.page-hint { border-collapse: collapse; } +/* th in x-scrollable-table */ .x-scrollable-table th { white-space: nowrap; padding: .25rem; } +/* td in x-scrollable-table */ .x-scrollable-table td { padding: .25rem; } +/* alternating row background in x-scrollable-table */ .x-scrollable-table tr:nth-child(even) {background: #ffffff} .x-scrollable-table tr:nth-child(odd) {background: #f5f5f5} @@ -201,13 +204,12 @@ div.chart { padding-right: 1rem; } - - -/* TODO: work in progress below... */ -.chart-list { +/* a table to annotate items from chart picture */ +.chart-items-list-table { border-spacing: .2rem; } +/* TODO: work in progress below */ .record-list { margin: 1rem; } diff --git a/initialize.php b/initialize.php index c33acb839..0f49c474f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5398"); +define("APP_VERSION", "1.19.23.5399"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 000093299c75e46866bcccc6fd42a4092dd8a0ef Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 15:22:32 +0000 Subject: [PATCH 211/652] Put some more comments in default.css. --- default.css | 26 ++++++++++++++++++-------- initialize.php | 2 +- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/default.css b/default.css index 518f200db..619426ef1 100644 --- a/default.css +++ b/default.css @@ -209,38 +209,48 @@ div.chart { border-spacing: .2rem; } -/* TODO: work in progress below */ -.record-list { +/* a div to display a list of records in */ +div.record-list { margin: 1rem; } +/* input controls */ .page-content input { border-radius: 4px; border: 1px solid #c9c9c9; padding: .4rem; } -.td-with-input { - text-align: left; -} - +/* input controls with focus on them */ .page-content input:focus { background-color: yellow; border: 1px solid black; outline: none; } -.contribute-msg { +/* a table cell containing input control */ +.td-with-input { + text-align: left; +} + +/* div containing how to contribute message */ +div.contribute-msg { text-align: center; margin-top: 2rem; padding: .2rem; background-color: #eeeeee; } -.version-and-copyright { + +/* div containing app version and copyright info */ +div.version-and-copyright { text-align: center; padding: .5rem; } + + + +/* TODO: work in progress below */ .centered-table td img { vertical-align: middle; } diff --git a/initialize.php b/initialize.php index 0f49c474f..82cc5d7df 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5399"); +define("APP_VERSION", "1.19.23.5400"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 82fa8f93e9a8c5cffd16db0303b9ca18ec6cd25b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 16:59:01 +0000 Subject: [PATCH 212/652] Added more comments in default.css. --- default.css | 131 ++++++++++++++++++++++++++++++------------------- initialize.php | 2 +- 2 files changed, 82 insertions(+), 51 deletions(-) diff --git a/default.css b/default.css index 619426ef1..30160902b 100644 --- a/default.css +++ b/default.css @@ -247,82 +247,95 @@ div.version-and-copyright { padding: .5rem; } - - - -/* TODO: work in progress below */ +/* img in td in centered-table, ex: now icons */ .centered-table td img { vertical-align: middle; } -.what-is-it-img { +/* span for what is it icon image */ +span.what-is-it-img { display: none; } -.what-is-it-text { +/* span for what is it text */ +span.what-is-it-text { display: inline-block; } -input[type="submit"] { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; -} - -input[type="button"] { +/* buttons */ +input[type="submit"], input[type="button"] { -webkit-appearance: none; -moz-appearance: none; appearance: none; } -input[type="text"] { +/* input controls */ +input[type="text"], input[type="password"], input[type="file"] { width: 220px; } +/* project rate input control */ input[type="text"].project-rate-field { width: 50px; } -input[type="password"] { - width: 220px; +/* dropdown control */ +.dropdown-field { + width: 236px; } -input[type="file"] { +/* textareas for fields */ +#description, #address, #item_name { width: 220px; + border-radius: 4px; + border: 1px solid #c9c9c9; + padding: .4rem; } -.dropdown-field { - width: 237px; +/* textareas with focus */ +#description:focus, #address:focus, #item_name:focus { + background-color: yellow; + border: 1px solid black; + outline: none; } -#description, #address, #item_name { - width: 220px; +/* textarea for note field */ +#note { + width: 100%; + margin: 0; + height: 4rem; + resize: none; border-radius: 4px; border: 1px solid #c9c9c9; padding: .4rem; } -#description:focus, #address:focus, #item_name:focus { +/* note field with focus */ +#note:focus { background-color: yellow; border: 1px solid black; outline: none; } +/* chart image */ .chart-image { width: 300px; height: 300px; } +/* chart color cell for annotations */ .chart-color-cell { width: .4rem; height: 1rem; } +/* chart description cell for annotations */ .chart-description-cell { text-align: left; padding-left: .25rem; } +/* calendar for small screens */ .small-screen-calendar { display: none; width: 210px; @@ -331,10 +344,12 @@ input[type="file"] { margin-right: auto; } +/* calendars with focus */ .small-screen-calendar a:focus, .large-screen-calendar a:focus { outline: none; } +/* calendar for large screens */ .large-screen-calendar { display: block; width: 210px; @@ -342,143 +357,159 @@ input[type="file"] { margin-top: 1rem; } +/* label for checkboxes */ .checkbox-label { float: left; } -#note { - width: 100%; - margin: 0; - height: 4rem; - resize: none; - border-radius: 4px; - border: 1px solid #c9c9c9; - padding: .4rem; -} - -#note:focus { - background-color: yellow; - border: 1px solid black; - outline: none; -} - -.day-totals { +/* div for day totals */ +div.day-totals { margin-bottom: 1rem; + width: 100%; } +/* column 1 for day totals */ .day-totals-col1 { text-align: left; padding-left: .5rem; padding-right: .5rem; } +/* column 2 for day totals */ .day-totals-col2 { padding-left: .5rem; padding-right: .5rem; text-align: right; } +/* not billable items */ .not-billable { - color: #ff6666; + color: red; } -.remaining-quota { +/* remaining quota span */ +span.remaining-quota { color: red; } -.remaining-quota-balance { +/* remaining quota balance span */ +span.remaining-quota-balance { color: red; } -.over-quota { +/* over quota span */ +span.over-quota { color: green; } -.over-quota-balance { +/* over quota balance span */ +span.over-quota-balance { color: green; } -.optional-nav { +/* div for optional navigation, ex: week view */ +div.optional-nav { margin-top: .5rem; } +/* div for a set of buttons, ex: save, copy, delete */ .button-set { margin-top: .5rem; margin-bottom: 1rem; } -.section-header { +/* section header div */ +div.section-header { font-weight: bold; text-align: center; margin-left: auto; margin-right: auto; } -.sitemap-item-group { +/* div for a group of items in site map */ +div.sitemap-item-group { margin-top: 2rem; margin-bottom: 2rem; } -.sitemap-item { +/* div for a single item in site map */ +div.sitemap-item { margin: .4rem; } +/* media rules for small screens */ @media screen and (max-width: 600px) { + /* hide large screen labels */ .large-screen-label { display: none; } + /* hide large screen chart annotations */ .large-screen-chart-items-list { display: none; } + /* show small screen chart annotations */ .small-screen-chart-items-list { display: table-cell; } + /* show small screen labels */ .small-screen-label { display: block; } + /* show small screen calendar */ .small-screen-calendar { display: block; } + /* hide large screen calendar */ .large-screen-calendar { display: none; } + /* show small screen form control separators */ .small-screen-form-control-separator { display: block; } - .what-is-it-img { + /* show what is it icons */ + span.what-is-it-img { display: inline-block; } - .what-is-it-text { + /* hide what is it text */ + span.what-is-it-text { display: none; } + /* hide how to contribute message */ div.contribute-msg { display: none; } + /* hide version and copyright */ div.version-and-copyright { display: none; } } +/* media rules for menus on small screens */ @media screen and (max-width: 1170px) { + + /* show small screen menu */ div.top-menu-small-screen { display: block; } + /* hide large screen menu */ div.top-menu-large-screen { display: none; } + /* hide large screen submenu */ div.top-submenu-large-screen { display: none; } diff --git a/initialize.php b/initialize.php index 82cc5d7df..2978e7a1b 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5400"); +define("APP_VERSION", "1.19.23.5401"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 05988b6d9bf9be8fc5f64f55cc9c61e602058638 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 17:43:38 +0000 Subject: [PATCH 213/652] Removed no longer used files. --- charts1.php | 227 -------------------- clients1.php | 55 ----- default.css | 4 - expense_delete1.php | 88 -------- expense_edit1.php | 243 --------------------- expenses1.php | 251 ---------------------- initialize.php | 2 +- project_add1.php | 118 ----------- project_edit1.php | 136 ------------ projects1.php | 58 ----- task_add1.php | 89 -------- task_edit1.php | 122 ----------- tasks1.php | 77 ------- time1.php | 506 -------------------------------------------- user_add1.php | 244 --------------------- user_edit1.php | 308 --------------------------- users1.php | 69 ------ 17 files changed, 1 insertion(+), 2596 deletions(-) delete mode 100644 charts1.php delete mode 100644 clients1.php delete mode 100644 expense_delete1.php delete mode 100644 expense_edit1.php delete mode 100644 expenses1.php delete mode 100644 project_add1.php delete mode 100644 project_edit1.php delete mode 100644 projects1.php delete mode 100644 task_add1.php delete mode 100644 task_edit1.php delete mode 100644 tasks1.php delete mode 100644 time1.php delete mode 100644 user_add1.php delete mode 100644 user_edit1.php delete mode 100644 users1.php diff --git a/charts1.php b/charts1.php deleted file mode 100644 index 3b4ce15a1..000000000 --- a/charts1.php +++ /dev/null @@ -1,227 +0,0 @@ -isPluginEnabled('ch')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!$user->exists()) { - header('Location: access_denied.php'); // Nobody to display a chart for. - exit(); -} -if ($user->behalf_id && (!$user->can('view_charts') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('view_own_charts') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to view on behalf. - exit(); -} -if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { - header('Location: access_denied.php'); // Wrong user id on post. - exit(); - } -} -// End of access checks. - -// Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -$uc = new ttUserConfig(); -$tracking_mode = $user->getTrackingMode(); - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -if(!$cl_date) { - $now = new DateAndTime(DB_DATEFORMAT); - $cl_date = $now->toString(DB_DATEFORMAT); -} -$_SESSION['date'] = $cl_date; - -if ($request->isPost()) { - $cl_interval = $request->getParameter('interval'); - if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; - $_SESSION['chart_interval'] = $cl_interval; - $uc->setValue(SYSC_CHART_INTERVAL, $cl_interval); - - $cl_type = $request->getParameter('type'); - if (!$cl_type) $cl_type = ttChartHelper::adjustType($cl_type); - $_SESSION['chart_type'] = $cl_type; - $uc->setValue(SYSC_CHART_TYPE, $cl_type); -} else { - // Initialize chart interval. - $cl_interval = $_SESSION['chart_interval']; - if (!$cl_interval) $cl_interval = $uc->getValue(SYSC_CHART_INTERVAL); - if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; - $_SESSION['chart_interval'] = $cl_interval; - - // Initialize chart type. - $cl_type = $_SESSION['chart_type']; - if (!$cl_type) $cl_type = $uc->getValue(SYSC_CHART_TYPE); - $cl_type = ttChartHelper::adjustType($cl_type); - $_SESSION['chart_type'] = $cl_type; -} - -// Elements of chartForm. -$chart_form = new Form('chartForm'); - -// User dropdown. Changes the user "on behalf" of whom we are working. -if ($user->can('view_charts')) { - $rank = $user->getMaxRankForGroup($user->getGroup()); - if ($user->can('view_own_charts')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $chart_form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', - 'name'=>'user', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'), - )); - $chart_form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Chart interval options. -$intervals = array(); -$intervals[INTERVAL_THIS_DAY] = $i18n->get('dropdown.selected_day'); -$intervals[INTERVAL_THIS_WEEK] = $i18n->get('dropdown.selected_week'); -$intervals[INTERVAL_THIS_MONTH] = $i18n->get('dropdown.selected_month'); -$intervals[INTERVAL_THIS_YEAR] = $i18n->get('dropdown.selected_year'); -$intervals[INTERVAL_ALL_TIME] = $i18n->get('dropdown.all_time'); - -// Chart interval dropdown. -$chart_form->addInput(array('type' => 'combobox', - 'onchange' => 'this.form.submit();', - 'name' => 'interval', - 'value' => $cl_interval, - 'data' => $intervals -)); - -// Chart type options. -$chart_selector = (MODE_PROJECTS_AND_TASKS == $tracking_mode || $user->isPluginEnabled('cl')); -if ($chart_selector) { - $types = array(); - if (MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode) - $types[CHART_PROJECTS] = $i18n->get('dropdown.projects'); - if (MODE_PROJECTS_AND_TASKS == $tracking_mode) - $types[CHART_TASKS] = $i18n->get('dropdown.tasks'); - if ($user->isPluginEnabled('cl')) - $types[CHART_CLIENTS] = $i18n->get('dropdown.clients'); - - // Add chart type dropdown. - $chart_form->addInput(array('type' => 'combobox', - 'onchange' => 'this.form.submit();', - 'name' => 'type', - 'value' => $cl_type, - 'data' => $types - )); -} - -// Calendar. -$chart_form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar - -// Get data for our chart. -$totals = ttChartHelper::getTotals($user_id, $cl_type, $cl_date, $cl_interval); -$smarty->assign('totals', $totals); - -// Prepare chart for drawing. -/* - * We use libchart.php library to draw chart images. It can draw chart labels, too (embed in the image). - * But quality of such auto-scaled text is not good. Therefore, we only use libchart to draw a pie-chart picture with - * auto-calculated percentage markers around it. We print labels (to the side of the picture) ourselves, - * using the same colors libchart is using. For labels printout, the $totals array (which is used for picture points) - * is also passed to charts.tpl Smarty template. - * - * To make all of the above possible with only one database call to obtain $totals we have to print the chart image - * to a file here (see code below). Once the image is available as a .png file, the charts.tpl can render it. - * - * PieChartEx class is a little extension to libchart-provided PieChart class. It allows us to print the chart - * without title, logo, and labels. - */ -$chart = new PieChartEx(300, 300); -$data_set = new XYDataSet(); -foreach($totals as $total) { - $data_set->addPoint(new Point( $total['name'], $total['time'])); -} -$chart->setDataSet($data_set); - -// Prepare a file name. -$img_dir = TEMPLATE_DIR.'_c/'; // Directory. -$file_name = uniqid('chart_').'.png'; // Short file name. Unique ID here is to avoid problems with browser caching. -$img_ref = 'WEB-INF/templates_c/'.$file_name; // Image reference for html. -$file_name = $img_dir.$file_name; // Full file name. - -// Clean up the file system from older images. -$img_files = glob($img_dir.'chart_*.png'); -if (is_array($img_files)) { - foreach($img_files as $file) { - // If file creation time is older than 1 minute, delete it. - if (filemtime($file) < (time() - 60)) { - unlink($file); - } - } -} - -// Write chart image to file system. -$chart->renderEx(array('fileName'=>$file_name,'hideLogo'=>true,'hideTitle'=>true,'hideLabel'=>true)); -// At this point libchart usage is complete and we have chart image on disk. - -$smarty->assign('img_file_name', $img_ref); -$smarty->assign('chart_selector', $chart_selector); -$smarty->assign('forms', array($chart_form->getName() => $chart_form->toArray())); -$smarty->assign('title', $i18n->get('title.charts')); -$smarty->assign('content_page_name', 'charts.tpl'); -$smarty->display('index.tpl'); diff --git a/clients1.php b/clients1.php deleted file mode 100644 index a299d3061..000000000 --- a/clients1.php +++ /dev/null @@ -1,55 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -if($user->can('manage_clients')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $inactive_clients = ttGroupHelper::getInactiveClients(true); -} else - $active_clients = $user->getAssignedClients(); - -$smarty->assign('active_clients', $active_clients); -$smarty->assign('inactive_clients', $inactive_clients); -$smarty->assign('title', $i18n->get('title.clients')); -$smarty->assign('content_page_name', 'clients.tpl'); -$smarty->display('index.tpl'); diff --git a/default.css b/default.css index 30160902b..595967e64 100644 --- a/default.css +++ b/default.css @@ -515,10 +515,6 @@ div.sitemap-item { } } - - - - /* TODO: below are legacy styles. Review as work on mobile-friendly pages continues. */ a { color: blue; text-decoration: none; } diff --git a/expense_delete1.php b/expense_delete1.php deleted file mode 100644 index 788fb59fa..000000000 --- a/expense_delete1.php +++ /dev/null @@ -1,88 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -// Get the expense item we are deleting. -$expense_item = ttExpenseHelper::getItem($cl_id); -if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { - // Prohibit deleting not ours, approved, or invoiced items. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -if ($request->isPost()) { - if ($request->getParameter('delete_button')) { // Delete button pressed. - - // Determine if it is okay to delete the record. - $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - if ($err->no()) { - // Mark the record as deleted. - if (ttExpenseHelper::markDeleted($cl_id)) { - header('Location: expenses.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } - if ($request->getParameter('cancel_button')) { // Cancel button pressed. - header('Location: expenses.php'); - exit(); - } -} // isPost - -$form = new Form('expenseItemForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); - -$show_project = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); - -$smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('expense_item', $expense_item); -$smarty->assign('show_project', $show_project); -$smarty->assign('title', $i18n->get('title.delete_expense')); -$smarty->assign('content_page_name', 'expense_delete.tpl'); -$smarty->display('index.tpl'); diff --git a/expense_edit1.php b/expense_edit1.php deleted file mode 100644 index d8b452d56..000000000 --- a/expense_edit1.php +++ /dev/null @@ -1,243 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -// Get the expense item we are editing. -$expense_item = ttExpenseHelper::getItem($cl_id); -if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { - // Prohibit editing not ours, approved, or invoiced items. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); -$confirm_save = $user->getConfigOption('confirm_save'); -$trackingMode = $user->getTrackingMode(); -$show_project = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; - -// Initialize variables. -$cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; -if ($request->isPost()) { - $cl_date = trim($request->getParameter('date')); - $cl_client = $request->getParameter('client'); - $cl_project = $request->getParameter('project'); - $cl_item_name = trim($request->getParameter('item_name')); - $cl_cost = trim($request->getParameter('cost')); - if ($user->isPluginEnabled('ps')) - $cl_paid = $request->getParameter('paid'); -} else { - $cl_date = $item_date->toString($user->getDateFormat()); - $cl_client = $expense_item['client_id']; - $cl_project = $expense_item['project_id']; - $cl_item_name = $expense_item['name']; - $cl_cost = $expense_item['cost']; - $cl_paid = $expense_item['paid']; -} - -// Initialize elements of 'expenseItemForm'. -$form = new Form('expenseItemForm'); - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $trackingMode && $user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -if ($show_project) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} -// If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); -if ($predefined_expenses) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'recalculateCost();', - 'name'=>'predefined_expense', - 'style'=>'width: 250px;', - 'value'=>$cl_predefined_expense, - 'data'=>$predefined_expenses, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); -} -$form->addInput(array('type'=>'textarea','maxlength'=>'800','name'=>'item_name','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_item_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -if ($user->can('manage_invoices') && $user->isPluginEnabled('ps')) - $form->addInput(array('type'=>'checkbox','name'=>'paid','value'=>$cl_paid)); -$form->addInput(array('type'=>'datefield','name'=>'date','maxlength'=>'20','value'=>$cl_date)); -// Hidden control for record id. -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$on_click_action = 'browser_today.value=get_date();'; -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); -if ($confirm_save) $on_click_action .= 'return(confirmSave());'; -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - if ($show_project && !$cl_project) - $err->add($i18n->get('error.project')); - if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); - if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); - - // This is a new date for the expense item. - $new_date = new DateAndTime($user->getDateFormat(), $cl_date); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($new_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating user input. - - // Save record. - if ($request->getParameter('btn_save')) { - // We need to: - // 1) Prohibit updating locked entries (that are in locked range). - // 2) Prohibit saving unlocked entries into locked range. - - // Now, step by step. - // 1) Prohibit saving locked entries in any form. - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - // 2) Prohibit saving unlocked entries into locked range. - if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // Now, an update. - if ($err->no()) { - if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(DB_DATEFORMAT), - 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'paid'=>$cl_paid))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } - } - } - - // Save as new record. - if ($request->getParameter('btn_copy')) { - // We need to prohibit saving into locked interval. - if ($user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // Now, a new insert. - if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'client_id'=>$cl_client, - 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } - - if ($request->getParameter('btn_delete')) { - header("Location: expense_delete.php?id=$cl_id"); - exit(); - } -} // isPost - -if ($confirm_save) { - $smarty->assign('confirm_save', true); - $smarty->assign('entry_date', $cl_date); -} -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_project', $show_project); -$smarty->assign('predefined_expenses', $predefined_expenses); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('title', $i18n->get('title.edit_expense')); -$smarty->assign('content_page_name', 'expense_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/expenses1.php b/expenses1.php deleted file mode 100644 index cd930a8b8..000000000 --- a/expenses1.php +++ /dev/null @@ -1,251 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!$user->exists()) { - header('Location: access_denied.php'); // Nobody to enter expenses for. - exit(); -} -if ($user->behalf_id && (!$user->can('track_expenses') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_expenses') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { - header('Location: access_denied.php'); // Wrong user id on post. - exit(); - } -} -// End of access checks. - -// Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -$tracking_mode = $user->getTrackingMode(); -$show_project = MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode; -$showFiles = $user->isPluginEnabled('at'); - -// Initialize variables. -$cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); -$_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); -$_SESSION['project'] = $cl_project; -$cl_item_name = $request->getParameter('item_name'); -$cl_cost = $request->getParameter('cost'); - -// Elements of expensesForm. -$form = new Form('expensesForm'); - -if ($user->can('track_expenses')) { - $rank = $user->getMaxRankForGroup($user->getGroup()); - if ($user->can('track_own_expenses')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', - 'name'=>'user', - 'style'=>'width: 250px;', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -if ($show_project) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} -// If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); -if ($predefined_expenses) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'recalculateCost();', - 'name'=>'predefined_expense', - 'style'=>'width: 250px;', - 'value'=>$cl_predefined_expense, - 'data'=>$predefined_expenses, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); -} -$form->addInput(array('type'=>'textarea','maxlength'=>'800','name'=>'item_name','style'=>'width: 250px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_item_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -if ($showFiles) - $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'calendar','name'=>'date','highlight'=>'expenses','value'=>$cl_date)); // calendar -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); - -// Submit. -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - if ($show_project && !$cl_project) - $err->add($i18n->get('error.project')); - if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.comment')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating input data. - - // Prohibit creating entries in locked range. - if ($user->isDateLocked($selected_date)) - $err->add($i18n->get('error.range_locked')); - - // Insert record. - if ($err->no()) { - $id = ttExpenseHelper::insert(array('date'=>$cl_date,'client_id'=>$cl_client, - 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1)); - - // Put a new file in storage if we have it. - if ($id && $showFiles && $_FILES['newfile']['name']) { - $fileHelper = new ttFileHelper($err); - $fields = array('entity_type'=>'expense', - 'entity_id' => $id, - 'file_name' => $_FILES['newfile']['name']); - $fileHelper->putFile($fields); - } - - if ($id) { - header('Location: expenses.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } -} - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_project', $show_project); -$smarty->assign('show_files', $showFiles); -$smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); -$smarty->assign('expense_items', ttExpenseHelper::getItems($cl_date, $showFiles)); -$smarty->assign('predefined_expenses', $predefined_expenses); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); -$smarty->assign('title', $i18n->get('title.expenses')); -$smarty->assign('content_page_name', 'expenses.tpl'); -$smarty->display('index.tpl'); diff --git a/initialize.php b/initialize.php index 2978e7a1b..f176802f5 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5401"); +define("APP_VERSION", "1.19.23.5402"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/project_add1.php b/project_add1.php deleted file mode 100644 index 5768d5fb5..000000000 --- a/project_add1.php +++ /dev/null @@ -1,118 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$showFiles = $user->isPluginEnabled('at'); -$users = ttGroupHelper::getActiveUsers(); -foreach ($users as $user_item) - $all_users[$user_item['id']] = $user_item['name']; - -$tasks = ttGroupHelper::getActiveTasks(); -foreach ($tasks as $task_item) - $all_tasks[$task_item['id']] = $task_item['name']; -$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('project_name')); - $cl_description = trim($request->getParameter('description')); - $cl_users = $request->getParameter('users', array()); - $cl_tasks = $request->getParameter('tasks', array()); -} else { - foreach ($users as $user_item) - $cl_users[] = $user_item['id']; - foreach ($tasks as $task_item) - $cl_tasks[] = $task_item['id']; -} - -$form = new Form('projectForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -if ($showFiles) - $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if ($show_tasks) - $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); - - if ($err->no()) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - $id = ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE)); - - // Put a new file in storage if we have it. - if ($id && $showFiles && $_FILES['newfile']['name']) { - $fileHelper = new ttFileHelper($err); - $fields = array('entity_type'=>'project', - 'entity_id' => $id, - 'file_name' => $_FILES['newfile']['name']); - $fileHelper->putFile($fields); - } - if ($id) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('show_files', $showFiles); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); -$smarty->assign('title', $i18n->get('title.add_project')); -$smarty->assign('content_page_name', 'project_add.tpl'); -$smarty->display('index.tpl'); diff --git a/project_edit1.php b/project_edit1.php deleted file mode 100644 index e1792e48c..000000000 --- a/project_edit1.php +++ /dev/null @@ -1,136 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_project_id = (int)$request->getParameter('id'); -$project = ttProjectHelper::get($cl_project_id); -if (!$project) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$users = ttGroupHelper::getActiveUsers(); -foreach ($users as $user_item) - $all_users[$user_item['id']] = $user_item['name']; - -$tasks = ttGroupHelper::getActiveTasks(); -foreach ($tasks as $task_item) - $all_tasks[$task_item['id']] = $task_item['name']; -$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('project_name')); - $cl_description = trim($request->getParameter('description')); - $cl_status = $request->getParameter('status'); - $cl_users = $request->getParameter('users', array()); - $cl_tasks = $request->getParameter('tasks', array()); -} else { - $cl_name = $project['name']; - $cl_description = $project['description']; - $cl_status = $project['status']; - $cl_users = ttProjectHelper::getAssignedUsers($cl_project_id); - $cl_tasks = explode(',', $project['tasks']); -} - -$form = new Form('projectForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if ($show_tasks) - $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $existing_project = ttProjectHelper::getProjectByName($cl_name); - if (!$existing_project || ($cl_project_id == $existing_project['id'])) { - // Update project information. - if (ttProjectHelper::update(array( - 'id' => $cl_project_id, - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'users' => $cl_users, - 'tasks' => $cl_tasks))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); -$smarty->assign('title', $i18n->get('title.edit_project')); -$smarty->assign('content_page_name', 'project_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/projects1.php b/projects1.php deleted file mode 100644 index 0075c038f..000000000 --- a/projects1.php +++ /dev/null @@ -1,58 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$showFiles = $user->isPluginEnabled('at'); - -if($user->can('manage_projects')) { - $active_projects = ttGroupHelper::getActiveProjects($showFiles); - $inactive_projects = ttGroupHelper::getInactiveProjects($showFiles); -} else { - $options['include_files'] = $showFiles; - $active_projects = $user->getAssignedProjects($options); -} - -$smarty->assign('active_projects', $active_projects); -$smarty->assign('inactive_projects', $inactive_projects); -$smarty->assign('show_files', $showFiles); -$smarty->assign('title', $i18n->get('title.projects')); -$smarty->assign('content_page_name', 'projects.tpl'); -$smarty->display('index.tpl'); diff --git a/task_add1.php b/task_add1.php deleted file mode 100644 index 078bd5ca1..000000000 --- a/task_add1.php +++ /dev/null @@ -1,89 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_description = trim($request->getParameter('description')); - $cl_projects = $request->getParameter('projects'); -} else { - foreach ($projects as $project_item) - $cl_projects[] = $project_item['id']; -} - -$form = new Form('taskForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - - if ($err->no()) { - if (!ttTaskHelper::getTaskByName($cl_name)) { - if (ttTaskHelper::insert(array( - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => ACTIVE, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', count($projects) > 0); -$smarty->assign('onload', 'onLoad="document.taskForm.name.focus()"'); -$smarty->assign('title', $i18n->get('title.add_task')); -$smarty->assign('content_page_name', 'task_add.tpl'); -$smarty->display('index.tpl'); diff --git a/task_edit1.php b/task_edit1.php deleted file mode 100644 index 10410c4b3..000000000 --- a/task_edit1.php +++ /dev/null @@ -1,122 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_task_id = (int)$request->getParameter('id'); -$task = ttTaskHelper::get($cl_task_id); -if (!$task) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_description = trim($request->getParameter('description')); - $cl_status = $request->getParameter('status'); - $cl_projects = $request->getParameter('projects'); -} else { - $cl_name = $task['name']; - $cl_description = $task['description']; - $cl_status = $task['status']; - $assigned_projects = ttTaskHelper::getAssignedProjects($cl_task_id); - foreach ($assigned_projects as $project_item) - $cl_projects[] = $project_item['id']; -} - -$form = new Form('taskForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 250px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $existing_task = ttTaskHelper::getTaskByName($cl_name); - if (!$existing_task || ($cl_task_id == $existing_task['id'])) { - // Update task information. - if (ttTaskHelper::update(array( - 'task_id' => $cl_task_id, - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttTaskHelper::getTaskByName($cl_name)) { - if (ttTaskHelper::insert(array( - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', count($projects) > 0); -$smarty->assign('title', $i18n->get('title.edit_task')); -$smarty->assign('content_page_name', 'task_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/tasks1.php b/tasks1.php deleted file mode 100644 index 2e13ead5c..000000000 --- a/tasks1.php +++ /dev/null @@ -1,77 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$config = $user->getConfigHelper(); - -if ($request->isPost()) { - $cl_task_required = $request->getParameter('task_required'); -} else { - $cl_task_required = $config->getDefinedValue('task_required'); -} - -if($user->can('manage_tasks')) { - $active_tasks = ttGroupHelper::getActiveTasks(); - $inactive_tasks = ttGroupHelper::getInactiveTasks(); -} else - $active_tasks = $user->getAssignedTasks(); - -$form = new Form('tasksForm'); -$form->addInput(array('type'=>'checkbox','name'=>'task_required','value'=>$cl_task_required)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_save')) { - // Save button clicked. Update config. - $config->setDefinedValue('task_required', $cl_task_required); - if (!$user->updateGroup(array('config' => $config->getConfig()))) { - $err->add($i18n->get('error.db')); - } - } -} - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('active_tasks', $active_tasks); -$smarty->assign('inactive_tasks', $inactive_tasks); -$smarty->assign('title', $i18n->get('title.tasks')); -$smarty->assign('content_page_name', 'tasks.tpl'); -$smarty->display('index.tpl'); diff --git a/time1.php b/time1.php deleted file mode 100644 index b249f05b7..000000000 --- a/time1.php +++ /dev/null @@ -1,506 +0,0 @@ -behalf_id && (!$user->can('track_time') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_time') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { - header('Location: access_denied.php'); // User changed, but no right or wrong user id. - exit(); - } -} -// End of access checks. - -// Determine user for whom we display this page. -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -$group_id = $user->getGroup(); -$config = new ttConfigHelper($user->getConfig()); - -$showClient = $user->isPluginEnabled('cl'); -$showBillable = $user->isPluginEnabled('iv'); -$trackingMode = $user->getTrackingMode(); -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; -$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; -if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); -$recordType = $user->getRecordType(); -$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; -$showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; -$showFiles = $user->isPluginEnabled('at'); -$showRecordCustomFields = $user->isOptionEnabled('record_custom_fields'); - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -$showNoteColumn = !$config->getDefinedValue('time_note_on_separate_row'); -$showNoteRow = $config->getDefinedValue('time_note_on_separate_row'); -if ($showNoteRow) { - // Determine column span for note field. - $colspan = 0; - if ($showClient) $colspan++; - if ($showRecordCustomFields && $custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $colspan++; - } - } - if ($showProject) $colspan++; - if ($showTask) $colspan++; - if ($showStart) $colspan++; - if ($showFinish) $colspan++; - $colspan++; // There is always a duration. - if ($showFiles) $colspan++; - $colspan++; // There is always an edit column. - // $colspan++; // There is always a delete column. - // $colspan--; // Remove one column for label. - $smarty->assign('colspan', $colspan); -} - -if ($user->isPluginEnabled('mq')){ - require_once('plugins/MonthlyQuota.class.php'); - $quota = new MonthlyQuota(); - $month_quota_minutes = $quota->getUserQuota($selected_date->mYear, $selected_date->mMonth); - $quota_minutes_from_1st = $quota->getUserQuotaFrom1st($selected_date); - $month_total = ttTimeHelper::getTimeForMonth($selected_date); - $month_total_minutes = ttTimeHelper::toMinutes($month_total); - $balance_left = $quota_minutes_from_1st - $month_total_minutes; - $minutes_left = $month_quota_minutes - $month_total_minutes; - - $smarty->assign('month_total', $month_total); - $smarty->assign('month_quota', ttTimeHelper::toAbsDuration($month_quota_minutes)); - $smarty->assign('over_balance', $balance_left < 0); - $smarty->assign('balance_remaining', ttTimeHelper::toAbsDuration($balance_left)); - $smarty->assign('over_quota', $minutes_left < 0); - $smarty->assign('quota_remaining', ttTimeHelper::toAbsDuration($minutes_left)); -} - -// Initialize variables. -$cl_start = trim($request->getParameter('start')); -$cl_finish = trim($request->getParameter('finish')); -$cl_duration = trim($request->getParameter('duration')); -$cl_note = trim($request->getParameter('note')); -$cl_billable = 1; -if ($showBillable) { - if ($request->isPost()) { - $cl_billable = $request->getParameter('billable'); - $_SESSION['billable'] = (int) $cl_billable; - } else - if (isset($_SESSION['billable'])) - $cl_billable = $_SESSION['billable']; -} -$cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); -$_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); -$_SESSION['project'] = $cl_project; -$cl_task = $request->getParameter('task', ($request->isPost() ? null : @$_SESSION['task'])); -$_SESSION['task'] = $cl_task; - -// Handle time custom fields. -$timeCustomFields = array(); -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $cl_control_name = $request->getParameter($control_name, ($request->isPost() ? null : @$_SESSION[$control_name])); - $_SESSION[$control_name] = $cl_control_name; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($cl_control_name)); - } -} - -// Elements of timeRecordForm. -$form = new Form('timeRecordForm'); - -// Dropdown for user and a hidden control to indicate user change. -if ($user->can('track_time')) { - $rank = $user->getMaxRankForGroup($group_id); - if ($user->can('track_own_time')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'document.timeRecordForm.user_changed.value=1;document.timeRecordForm.submit();', - 'name'=>'user', - 'style'=>'width: 250px;', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Dropdown for clients in MODE_TIME. Use all active clients. -// Note: for other tracking modes the control is added further below. -if (MODE_TIME == $trackingMode && $showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -// Billable checkbox. -if ($showBillable) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); - -// If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'style'=>'width: 250px;','value'=>$timeCustomFields[$timeField['id']]['value'])); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -// If we show project dropdown, add controls for project and client. -if ($showProject) { - // Dropdown for projects assigned to user. - $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); - $project_list = $user->getAssignedProjects($options); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);prepopulateNote();', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Client dropdown. - if ($showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - if (is_array($projects_assigned_to_client) && is_array($projects_assigned_to_user)) - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} - -// Task dropdown. -if ($showTask) { - $task_list = ttGroupHelper::getActiveTasks(); - $form->addInput(array('type'=>'combobox', - 'name'=>'task', - 'style'=>'width: 250px;', - 'value'=>$cl_task, - 'data'=>$task_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); -} - -// Start and finish controls. -if ($showStart) { - $form->addInput(array('type'=>'text','name'=>'start','value'=>$cl_start,'onchange'=>"formDisable('start');")); - $form->addInput(array('type'=>'text','name'=>'finish','value'=>$cl_finish,'onchange'=>"formDisable('finish');")); - if ($user->punch_mode && !$user->canOverridePunchMode()) { - // Make the start and finish fields read-only. - $form->getElement('start')->setEnabled(false); - $form->getElement('finish')->setEnabled(false); - } -} - -// Duration control. -if ($showDuration) - $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); - -// File upload control. -if ($showFiles) - $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); - -// If we have templates, add a dropdown to select one. -if ($user->isPluginEnabled('tp')){ - $template_list = ttGroupHelper::getActiveTemplates(); - if (count($template_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillNote(this.value);', - 'name'=>'template', - 'style'=>'width: 250px;', - 'data'=>$template_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $smarty->assign('template_dropdown', 1); - $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); - $smarty->assign('prepopulate_note', $config->getDefinedValue('prepopulate_note')); - $smarty->assign('template_list', $template_list); - } -} - -// Note control. -if (!defined('NOTE_INPUT_HEIGHT')) - define('NOTE_INPUT_HEIGHT', 40); -$form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 600px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); - -// Calendar. -$form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar - -// A hidden control for today's date from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. - -// Submit button. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Submit button clicked. - // Validate user input. - if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - // Validate input in time custom fields. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($timeCustomFields as $timeField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); - } - } - if ($showProject) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } - if ($showTask && $taskRequired) { - if (!$cl_task) $err->add($i18n->get('error.task')); - } - if (strlen($cl_duration) == 0) { - if ($cl_start || $cl_finish) { - if (!ttTimeHelper::isValidTime($cl_start)) - $err->add($i18n->get('error.field'), $i18n->get('label.start')); - if ($cl_finish) { - if (!ttTimeHelper::isValidTime($cl_finish)) - $err->add($i18n->get('error.field'), $i18n->get('label.finish')); - if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) - $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); - } - } else { - if ($showStart) { - $err->add($i18n->get('error.empty'), $i18n->get('label.start')); - $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); - } - if ($showDuration) - $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); - } - } else { - if (false === ttTimeHelper::postedDurationToMinutes($cl_duration)) - $err->add($i18n->get('error.field'), $i18n->get('label.duration')); - } - if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); - if ($user->isPluginEnabled('tp') && !ttValidTemplateText($cl_note)) { - $err->add($i18n->get('error.field'), $i18n->get('label.note')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating user input. - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - - // Prohibit creating entries in locked range. - if ($user->isDateLocked($selected_date)) - $err->add($i18n->get('error.range_locked')); - - // Prohibit creating another uncompleted record. - if ($err->no()) { - if (($not_completed_rec = ttTimeHelper::getUncompleted($user_id)) && (($cl_finish == '') && ($cl_duration == ''))) - $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); - } - - // Prohibit creating an overlapping record. - if ($err->no()) { - if (ttTimeHelper::overlaps($user_id, $cl_date, $cl_start, $cl_finish)) - $err->add($i18n->get('error.overlap')); - } - - // Insert record. - if ($err->no()) { - $id = ttTimeHelper::insert(array( - 'date' => $cl_date, - 'client' => $cl_client, - 'project' => $cl_project, - 'task' => $cl_task, - 'start' => $cl_start, - 'finish' => $cl_finish, - 'duration' => $cl_duration, - 'note' => $cl_note, - 'billable' => $cl_billable)); - - // Insert time custom fields if we have them. - $result = true; - if ($id && $custom_fields && $custom_fields->timeFields) { - $result = $custom_fields->insertTimeFields($id, $timeCustomFields); - } - - // Put a new file in storage if we have it. - if ($id && $showFiles && $_FILES['newfile']['name']) { - $fileHelper = new ttFileHelper($err); - $fields = array('entity_type'=>'time', - 'entity_id' => $id, - 'file_name' => $_FILES['newfile']['name']); - $fileHelper->putFile($fields); - } - - if ($id && $result && $err->no()) { - header('Location: time.php'); - exit(); - } - $err->add($i18n->get('error.db')); - } - } elseif ($request->getParameter('btn_stop')) { - // Stop button pressed to finish an uncompleted record. - $record_id = $request->getParameter('record_id'); - $record = ttTimeHelper::getRecord($record_id); - $browser_date = $request->getParameter('browser_date'); - $browser_time = $request->getParameter('browser_time'); - - // Can we complete this record? - if ($record['date'] == $browser_date // closing today's record - && ttTimeHelper::isValidInterval($record['start'], $browser_time) // finish time is greater than start time - && !ttTimeHelper::overlaps($user_id, $browser_date, $record['start'], $browser_time)) { // no overlap - $res = ttTimeHelper::update(array( - 'id'=>$record['id'], - 'date'=>$record['date'], - 'client'=>$record['client_id'], - 'project'=>$record['project_id'], - 'task'=>$record['task_id'], - 'start'=>$record['start'], - 'finish'=>$browser_time, - 'note'=>$record['comment'], - 'billable'=>$record['billable'])); - if (!$res) - $err->add($i18n->get('error.db')); - } else { - // Cannot complete, redirect for manual edit. - header('Location: time_edit.php?id='.$record_id); - exit(); - } - } -} // isPost - -$week_total = ttTimeHelper::getTimeForWeek($selected_date); -$timeRecords = ttTimeHelper::getRecords($cl_date, $showFiles); - -$smarty->assign('selected_date', $selected_date); -$smarty->assign('week_total', $week_total); -$smarty->assign('day_total', ttTimeHelper::getTimeForDay($cl_date)); -$smarty->assign('time_records', $timeRecords); -$smarty->assign('show_record_custom_fields', $showRecordCustomFields); -$smarty->assign('show_navigation', $user->isPluginEnabled('wv') && !$user->isOptionEnabled('week_menu')); -$smarty->assign('show_client', $showClient); -$smarty->assign('show_billable', $showBillable); -$smarty->assign('show_project', $showProject); -$smarty->assign('show_task', $showTask); -$smarty->assign('task_required', $taskRequired); -$smarty->assign('show_start', $showStart); -$smarty->assign('show_duration', $showDuration); -$smarty->assign('show_note_column', $showNoteColumn); -$smarty->assign('show_note_row', $showNoteRow); -$smarty->assign('show_files', $showFiles); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="fillDropdowns();prepopulateNote();"'); -$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); -$smarty->assign('title', $i18n->get('title.time')); -$smarty->assign('content_page_name', 'time.tpl'); -$smarty->display('index.tpl'); diff --git a/user_add1.php b/user_add1.php deleted file mode 100644 index b7c2bc7a6..000000000 --- a/user_add1.php +++ /dev/null @@ -1,244 +0,0 @@ -isPluginEnabled('mq'); -if ($user->isPluginEnabled('cl')) - $clients = ttGroupHelper::getActiveClients(); - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -$assigned_projects = array(); -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_login = trim($request->getParameter('login')); - if (!$auth->isPasswordExternal()) { - $cl_password1 = $request->getParameter('pas1'); - $cl_password2 = $request->getParameter('pas2'); - } - $cl_email = trim($request->getParameter('email')); - $cl_role_id = $request->getParameter('role'); - $cl_client_id = $request->getParameter('client'); - $cl_quota_percent = $request->getParameter('quota_percent'); - // If we have user custom fields - collect input. - if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $control_name = 'user_field_'.$userField['id']; - $userCustomFields[$userField['id']] = array('field_id' => $userField['id'], - 'control_name' => $control_name, - 'label' => $userField['label'], - 'type' => $userField['type'], - 'required' => $userField['required'], - 'value' => trim($request->getParameter($control_name))); - } - } - $cl_rate = $request->getParameter('rate'); - $cl_projects = $request->getParameter('projects'); - if (is_array($cl_projects)) { - foreach ($cl_projects as $p) { - if (ttValidFloat($request->getParameter('rate_'.$p), true)) { - $project_with_rate = array(); - $project_with_rate['id'] = $p; - $project_with_rate['rate'] = $request->getParameter('rate_'.$p); - $assigned_projects[] = $project_with_rate; - } else - $err->add($i18n->get('error.field'), 'rate_'.$p); - } - } -} - -$form = new Form('userForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 300px;','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','style'=>'width: 300px;','value'=>$cl_login)); -if (!$auth->isPasswordExternal()) { - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas1','value'=>$cl_password1)); - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas2','value'=>$cl_password2)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email)); - -$active_roles = ttTeamHelper::getActiveRolesForUser(); -$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles,'datakeys'=>array('id', 'name'))); -if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); - -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $field_name = 'user_field_'.$userField['id']; - if ($userField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$userCustomFields[$userField['id']]['value'])); - } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($userField['id']), - 'value'=>$userCustomFields[$userField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -if ($show_quota) - $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); - -$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); -if ($show_projects) { - $projects = ttGroupHelper::getActiveProjects(); - if (count($projects) == 0) $show_projects = false; -} - -// Define classes for the projects table. -class NameCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200)); - $this->setValue(''); - return $this->toString(); - } -} -class RateCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $assigned_projects; - $field = new FloatField('rate_'.$table->getValueAtName($row, 'id')); - $field->setFormName($table->getFormName()); - $field->setSize(5); - $field->setFormat('.2'); - foreach ($assigned_projects as $p) { - if ($p['id'] == $table->getValueAtName($row,'id')) $field->setValue($p['rate']); - } - $this->setValue($field->getHtml()); - return $this->toString(); - } -} -// Create projects table. -$table = new Table('projects'); -$table->setIAScript('setDefaultRate'); -$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); -$table->setData($projects); -$table->setKeyField('id'); -$table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); -$form->addInputElement($table); - -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); - if (!$auth->isPasswordExternal()) { - if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); - } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - // Require selection of a client for a client role. - if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); - // Validate input in user custom fields. - if ($custom_fields && $custom_fields->userFields) { - foreach ($userCustomFields as $userField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($userField['value'], !$userField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($userField['label'])); - } - } - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttUserHelper::canAdd()) $err->add($i18n->get('error.user_count')); - - if ($err->no()) { - if (!ttUserHelper::getUserByLogin($cl_login)) { - $fields = array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'rate' => $cl_rate, - 'quota_percent' => $cl_quota_percent, - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'role_id' => $cl_role_id, - 'client_id' => $cl_client_id, - 'projects' => $assigned_projects, - 'email' => $cl_email); - $user_id = ttUserHelper::insert($fields); - - // Insert user custom fields if we have them. - $result = true; - if ($user_id && $custom_fields && $custom_fields->userFields) { - $result = $custom_fields->insertEntityFields(CustomFields::ENTITY_USER, $user_id, $userCustomFields); - } - - if ($user_id && $result) { - if (!$user->exists()) { - // We added a user to an empty subgroup. Set new user as on behalf user. - // Needed for user-based things to work (such as notifications config). - $user->setOnBehalfUser($user_id); - } - header('Location: users.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.user_exists')); - } -} // isPost - -$smarty->assign('auth_external', $auth->isPasswordExternal()); -$smarty->assign('active_roles', $active_roles); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('show_quota', $show_quota); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.add_user')); -$smarty->assign('content_page_name', 'user_add.tpl'); -$smarty->display('index.tpl'); diff --git a/user_edit1.php b/user_edit1.php deleted file mode 100644 index d74ae2785..000000000 --- a/user_edit1.php +++ /dev/null @@ -1,308 +0,0 @@ -getParameter('id'); -$user_details = $user->getUserDetails($user_id); -if (!$user_details) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$show_quota = $user->isPluginEnabled('mq'); -if ($user->isPluginEnabled('cl')) - $clients = ttGroupHelper::getActiveClients(); - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); -if ($show_projects) { - $projects = ttGroupHelper::getActiveProjects(); - if (count($projects) == 0) $show_projects = false; -} -$assigned_projects = array(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_login = trim($request->getParameter('login')); - if (!$auth->isPasswordExternal()) { - $cl_password1 = $request->getParameter('pas1'); - $cl_password2 = $request->getParameter('pas2'); - } - $cl_email = trim($request->getParameter('email')); - $cl_role_id = $request->getParameter('role'); - $cl_client_id = $request->getParameter('client'); - $cl_status = $request->getParameter('status'); - $cl_quota_percent = $request->getParameter('quota_percent'); - // If we have user custom fields - collect input. - if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $control_name = 'user_field_'.$userField['id']; - $userCustomFields[$userField['id']] = array('field_id' => $userField['id'], - 'control_name' => $control_name, - 'label' => $userField['label'], - 'type' => $userField['type'], - 'required' => $userField['required'], - 'value' => trim($request->getParameter($control_name))); - } - } - $cl_rate = $request->getParameter('rate'); - $cl_projects = $request->getParameter('projects'); - if (is_array($cl_projects)) { - foreach ($cl_projects as $p) { - if (ttValidFloat($request->getParameter('rate_'.$p), true)) { - $project_with_rate = array(); - $project_with_rate['id'] = $p; - $project_with_rate['rate'] = $request->getParameter('rate_'.$p); - $assigned_projects[] = $project_with_rate; - } else - $err->add($i18n->get('error.field'), 'rate_'.$p); - } - } -} else { - $cl_name = $user_details['name']; - $cl_login = $user_details['login']; - $cl_email = $user_details['email']; - $cl_quota_percent = str_replace('.', $user->getDecimalMark(), $user_details['quota_percent']); - // If we have user custom fields - collect values from database. - if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $control_name = 'user_field_'.$userField['id']; - $userCustomFields[$userField['id']] = array('field_id' => $userField['id'], - 'control_name' => $control_name, - 'label' => $userField['label'], - 'type' => $userField['type'], - 'required' => $userField['required'], - 'value' => $custom_fields->getEntityFieldValue(CustomFields::ENTITY_USER, $user_id, $userField['id'], $userField['type'])); - } - } - $cl_rate = str_replace('.', $user->getDecimalMark(), $user_details['rate']); - $cl_role_id = $user_details['role_id']; - $cl_client_id = $user_details['client_id']; - $cl_status = $user_details['status']; - $cl_projects = array(); - $assigned_projects = ttProjectHelper::getAssignedProjects($user_id); - foreach($assigned_projects as $p) { - $cl_projects[] = $p['id']; - } -} - -$form = new Form('userForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 300px;','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','style'=>'width: 300px;','value'=>$cl_login)); -if (!$auth->isPasswordExternal()) { - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas1','value'=>$cl_password1)); - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas2','value'=>$cl_password2)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','style'=>'width: 300px;','value'=>$cl_email)); - -$active_roles = ttTeamHelper::getActiveRolesForUser(); -$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles, 'datakeys'=>array('id', 'name'))); -if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); - -// If we have custom fields - add controls for them. -if ($custom_fields && $custom_fields->userFields) { - foreach ($custom_fields->userFields as $userField) { - $field_name = 'user_field_'.$userField['id']; - if ($userField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$userCustomFields[$userField['id']]['value'])); - } elseif ($userField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($userField['id']), - 'value'=>$userCustomFields[$userField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -if ($show_quota) - $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); - -// Define classes for the projects table. -class NameCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200)); - $this->setValue(''); - return $this->toString(); - } -} -class RateCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $assigned_projects; - - $field = new FloatField('rate_'.$table->getValueAtName($row,'id')); - $field->setFormName($table->getFormName()); - $field->setSize(5); - $field->setFormat('.2'); - foreach ($assigned_projects as $p) { - if ($p['id'] == $table->getValueAtName($row,'id')) $field->setValue($p['rate']); - } - $this->setValue($field->getHtml()); - return $this->toString(); - } -} -// Create projects table. -$table = new Table('projects'); -$table->setIAScript('setRate'); -$table->setTableOptions(array('width'=>'300','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); -$table->setData($projects); -$table->setKeyField('id'); -$table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); -$form->addInputElement($table); - -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.save'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); - if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { - if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); - } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - // Require selection of a client for a client role. - if ($user->isPluginEnabled('cl') && ttRoleHelper::isClientRole($cl_role_id) && !$cl_client_id) $err->add($i18n->get('error.client')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); - // Validate input in user custom fields. - if ($custom_fields && $custom_fields->userFields) { - foreach ($userCustomFields as $userField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($userField['value'], !$userField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($userField['label'])); - } - } - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - - if ($err->no()) { - $existing_user = ttUserHelper::getUserByLogin($cl_login); - if (!$existing_user || ($user_id == $existing_user['id'])) { - - $fields = array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'email' => $cl_email, - 'status' => $cl_status, - 'rate' => $cl_rate, - 'quota_percent' => $cl_quota_percent, - 'projects' => $assigned_projects); - if (in_array('manage_users', $user->rights) && $cl_role_id) { - $fields['role_id'] = $cl_role_id; - $fields['client_id'] = $cl_client_id; - } - - $result = ttUserHelper::update($user_id, $fields); - // Update user custom fields if we have them. - if ($result && $custom_fields && $custom_fields->userFields) { - $result = $custom_fields->updateEntityFields(CustomFields::ENTITY_USER, $user_id, $userCustomFields); - } - - if ($result) { - // If our own login changed, set new one in cookie to remember it. - if (($user_id == $user->id) && ($user->login != $cl_login)) { - setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); - } - - // In case the name of the "on behalf" user has changed - set it in session. - if (($user->behalf_id == $user_id) && ($user->behalf_name != $cl_name)) { - $_SESSION['behalf_name'] = $cl_name; - } - - // If we deactivated our own account, do housekeeping and logout. - if ($user->id == $user_id && !is_null($cl_status) && $cl_status == INACTIVE) { - // Remove LOGIN_COOKIE_NAME cookie that stores login name. - unset($_COOKIE[LOGIN_COOKIE_NAME]); - setcookie(LOGIN_COOKIE_NAME, NULL, -1); - - $auth->doLogout(); - header('Location: login.php'); - exit(); - } - - header('Location: users.php'); - exit(); - - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.user_exists')); - } -} // isPost - -$can_swap = false; -if ($user->id == $user_id && $user->can('swap_roles')) { - $users_for_swap = ttTeamHelper::getUsersForSwap(); - if (is_array($users_for_swap) && sizeof($users_for_swap) > 0) - $can_swap = true; -} - -$rates = ttProjectHelper::getRates($user_id); -$smarty->assign('rates', $rates); - -$smarty->assign('auth_external', $auth->isPasswordExternal()); -$smarty->assign('active_roles', $active_roles); -$smarty->assign('can_swap', $can_swap); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('show_quota', $show_quota); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('user_id', $user_id); -$smarty->assign('title', $i18n->get('title.edit_user')); -$smarty->assign('content_page_name', 'user_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/users1.php b/users1.php deleted file mode 100644 index 2fbcb5d20..000000000 --- a/users1.php +++ /dev/null @@ -1,69 +0,0 @@ -getMaxRankForGroup($user->getGroup()); -if ($user->can('view_users')) - $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); -else /* if ($user->can('manage_users')) */ - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); -$active_users = $user->getUsers($options); - -// Prepare a list of inactive users. -if($user->can('manage_users')) { - $options = array('status'=>INACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_login'=>true,'include_role'=>true); - $inactive_users = $user->getUsers($options); -} - -$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); -if ($uncompleted_indicators) { - // Check each active user if they have an uncompleted time entry. - foreach ($active_users as $key => $active_user) { - $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($active_user['id']); - } - $smarty->assign('uncompleted_indicators', true); -} - -$smarty->assign('active_users', $active_users); -$smarty->assign('inactive_users', $inactive_users); -$smarty->assign('show_quota', $user->isPluginEnabled('mq')); -$smarty->assign('title', $i18n->get('title.users')); -$smarty->assign('content_page_name', 'users.tpl'); -$smarty->display('index.tpl'); From ba13f2e7523c2913c1af268ff85e3392657872f0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 18:27:09 +0000 Subject: [PATCH 214/652] Made file_edit.php page mobile-friendly. --- WEB-INF/templates/file_edit2.tpl | 22 ++++++ client_edit1.php | 131 ------------------------------- file_edit.php | 36 ++------- initialize.php | 2 +- 4 files changed, 29 insertions(+), 162 deletions(-) create mode 100644 WEB-INF/templates/file_edit2.tpl delete mode 100644 client_edit1.php diff --git a/WEB-INF/templates/file_edit2.tpl b/WEB-INF/templates/file_edit2.tpl new file mode 100644 index 000000000..66f72cc3d --- /dev/null +++ b/WEB-INF/templates/file_edit2.tpl @@ -0,0 +1,22 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.fileForm.open} +
{$totals[i].name|escape}
+ + + + + + + + + + + + + + +
{$forms.fileForm.file_name.control}
{$forms.fileForm.description.control}
{$i18n.label.required_fields}
+
{$forms.fileForm.btn_save.control}
+{$forms.fileForm.close} diff --git a/client_edit1.php b/client_edit1.php deleted file mode 100644 index 7b572ea7c..000000000 --- a/client_edit1.php +++ /dev/null @@ -1,131 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -$client = ttClientHelper::getClient($cl_id, true); -if (!$client) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_address = trim($request->getParameter('address')); - $cl_tax = trim($request->getParameter('tax')); - $cl_status = $request->getParameter('status'); - $cl_projects = $request->getParameter('projects'); -} else { - $cl_name = $client['name']; - $cl_address = $client['address']; - $cl_tax = $client['tax']; - $cl_status = $client['status']; - $assigned_projects = ttClientHelper::getAssignedProjects($cl_id); - foreach($assigned_projects as $project_item) { - $cl_projects[] = $project_item['id']; - } -} - -$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; - -$form = new Form('clientForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'text','name'=>'name','maxlength'=>'100','style'=>'width: 350px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','style'=>'width: 350px; height: 80px;','value'=>$cl_address)); -$form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -if ($show_projects) - $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'datakeys'=>array('id','name'),'layout'=>'H','value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $client = ttClientHelper::getClientByName($cl_name); - if (($client && ($cl_id == $client['id'])) || !$client) { - if (ttClientHelper::update(array( - 'id' => $cl_id, - 'name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array('name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.edit_client')); -$smarty->assign('content_page_name', 'client_edit.tpl'); -$smarty->display('index.tpl'); diff --git a/file_edit.php b/file_edit.php index d2c8f2990..745293c2e 100644 --- a/file_edit.php +++ b/file_edit.php @@ -1,30 +1,6 @@ addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_file_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'file_name','style'=>'width: 250px;','value'=>$cl_name)); +$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'file_name','value'=>$cl_name)); $form->getElement('file_name')->setEnabled(false); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); if ($request->isPost()) { @@ -120,5 +96,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fileForm.description.focus()"'); $smarty->assign('title', $i18n->get('title.edit_file')); -$smarty->assign('content_page_name', 'file_edit.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'file_edit2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index f176802f5..0a7d91412 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5402"); +define("APP_VERSION", "1.19.23.5403"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From b72b5fbd56be8cede708844df1fc9d19ce5e84d2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 19:46:03 +0000 Subject: [PATCH 215/652] Made file_delete.php mobile-friendly. --- WEB-INF/templates/file_delete2.tpl | 7 +++++++ file_delete.php | 32 ++++-------------------------- initialize.php | 2 +- 3 files changed, 12 insertions(+), 29 deletions(-) create mode 100644 WEB-INF/templates/file_delete2.tpl diff --git a/WEB-INF/templates/file_delete2.tpl b/WEB-INF/templates/file_delete2.tpl new file mode 100644 index 000000000..80abe01ce --- /dev/null +++ b/WEB-INF/templates/file_delete2.tpl @@ -0,0 +1,7 @@ +{* Copyright (c) Anuko International Ltd. https://www.anuko.com +License: See license.txt *} + +{$forms.fileDeleteForm.open} +
{$file_to_delete|escape}
+
{$forms.fileDeleteForm.btn_delete.control} {$forms.fileDeleteForm.btn_cancel.control}
+{$forms.fileDeleteForm.close} diff --git a/file_delete.php b/file_delete.php index ff56f118b..1b415c19b 100644 --- a/file_delete.php +++ b/file_delete.php @@ -1,30 +1,6 @@ assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('onload', 'onLoad="document.fileDeleteForm.btn_cancel.focus()"'); $smarty->assign('title', $i18n->get('title.delete_file')); -$smarty->assign('content_page_name', 'file_delete.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'file_delete2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index 0a7d91412..a863d270f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5403"); +define("APP_VERSION", "1.19.23.5404"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 509a401638a0eaba661196cc38e0b3159e71db7c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 20:36:33 +0000 Subject: [PATCH 216/652] Cleanup: removed no longer used templates. --- WEB-INF/templates/charts.tpl | 37 ---- WEB-INF/templates/client_add.tpl | 37 ---- WEB-INF/templates/client_delete.tpl | 25 --- WEB-INF/templates/client_edit.tpl | 41 ----- WEB-INF/templates/clients.tpl | 74 -------- WEB-INF/templates/entity_files.tpl | 47 ------ WEB-INF/templates/expense_delete.tpl | 39 ----- WEB-INF/templates/expense_edit.tpl | 189 --------------------- WEB-INF/templates/expenses.tpl | 241 --------------------------- WEB-INF/templates/file_delete.tpl | 18 -- WEB-INF/templates/file_edit.tpl | 29 ---- WEB-INF/templates/project_add.tpl | 49 ------ WEB-INF/templates/project_delete.tpl | 18 -- WEB-INF/templates/project_edit.tpl | 47 ------ WEB-INF/templates/projects.tpl | 114 ------------- WEB-INF/templates/swap_roles.tpl | 15 -- WEB-INF/templates/task_add.tpl | 36 ---- WEB-INF/templates/task_delete.tpl | 20 --- WEB-INF/templates/task_edit.tpl | 40 ----- WEB-INF/templates/tasks.tpl | 96 ----------- WEB-INF/templates/time.tpl | 234 -------------------------- WEB-INF/templates/user_add.tpl | 134 --------------- WEB-INF/templates/user_delete.tpl | 20 --- WEB-INF/templates/user_edit.tpl | 168 ------------------- WEB-INF/templates/users.tpl | 121 -------------- expense_files.php | 34 +--- initialize.php | 2 +- project_files.php | 34 +--- timesheet_delete.php | 28 +--- timesheet_files.php | 34 +--- 30 files changed, 18 insertions(+), 2003 deletions(-) delete mode 100644 WEB-INF/templates/charts.tpl delete mode 100644 WEB-INF/templates/client_add.tpl delete mode 100644 WEB-INF/templates/client_delete.tpl delete mode 100644 WEB-INF/templates/client_edit.tpl delete mode 100644 WEB-INF/templates/clients.tpl delete mode 100644 WEB-INF/templates/entity_files.tpl delete mode 100644 WEB-INF/templates/expense_delete.tpl delete mode 100644 WEB-INF/templates/expense_edit.tpl delete mode 100644 WEB-INF/templates/expenses.tpl delete mode 100644 WEB-INF/templates/file_delete.tpl delete mode 100644 WEB-INF/templates/file_edit.tpl delete mode 100644 WEB-INF/templates/project_add.tpl delete mode 100644 WEB-INF/templates/project_delete.tpl delete mode 100644 WEB-INF/templates/project_edit.tpl delete mode 100644 WEB-INF/templates/projects.tpl delete mode 100644 WEB-INF/templates/swap_roles.tpl delete mode 100644 WEB-INF/templates/task_add.tpl delete mode 100644 WEB-INF/templates/task_delete.tpl delete mode 100644 WEB-INF/templates/task_edit.tpl delete mode 100644 WEB-INF/templates/tasks.tpl delete mode 100644 WEB-INF/templates/time.tpl delete mode 100644 WEB-INF/templates/user_add.tpl delete mode 100644 WEB-INF/templates/user_delete.tpl delete mode 100644 WEB-INF/templates/user_edit.tpl delete mode 100644 WEB-INF/templates/users.tpl diff --git a/WEB-INF/templates/charts.tpl b/WEB-INF/templates/charts.tpl deleted file mode 100644 index 8e05e1985..000000000 --- a/WEB-INF/templates/charts.tpl +++ /dev/null @@ -1,37 +0,0 @@ -

-{$forms.chartForm.open} - - -{if $user_dropdown} - - {if $chart_selector} - - {/if} -{else} - {if $chart_selector} - - {/if} -{/if} - - -
{$i18n.label.user}: {$forms.chartForm.user.control}{$i18n.form.charts.chart}: {$forms.chartForm.type.control}{$i18n.form.charts.chart}: {$forms.chartForm.type.control}
- - - - - -
- - {section name=i loop=$totals} - {if $smarty.section.i.index <= 12} - - {/if} - {/section} -
{$totals[i].name|escape}
-
-

- - - -
{$i18n.form.charts.interval}: {$forms.chartForm.interval.control}
{$forms.chartForm.date.control}
-{$forms.chartForm.close} diff --git a/WEB-INF/templates/client_add.tpl b/WEB-INF/templates/client_add.tpl deleted file mode 100644 index db10ede45..000000000 --- a/WEB-INF/templates/client_add.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{$forms.clientForm.open} - - - - -
- - - - - - - - - - - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - -
{$i18n.label.client_name} (*):{$forms.clientForm.name.control}
{$i18n.label.client_address}:{$forms.clientForm.address.control}
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->getDecimalMark()}00)
{$i18n.label.required_fields}
 
{$i18n.label.projects}:{$forms.clientForm.projects.control}
 
{$forms.clientForm.btn_submit.control}
-
-{$forms.clientForm.close} diff --git a/WEB-INF/templates/client_delete.tpl b/WEB-INF/templates/client_delete.tpl deleted file mode 100644 index f40b94c12..000000000 --- a/WEB-INF/templates/client_delete.tpl +++ /dev/null @@ -1,25 +0,0 @@ -{$forms.clientDeleteForm.open} - - - - -
- - - - - - - - - - - - - - - - -
{$i18n.form.client.client_to_delete}:{$client_to_delete|escape}
{$i18n.form.client.client_entries}:{$forms.clientDeleteForm.delete_client_entries.control}
 
{$forms.clientDeleteForm.btn_delete.control}  {$forms.clientDeleteForm.btn_cancel.control}
-
-{$forms.clientDeleteForm.close} diff --git a/WEB-INF/templates/client_edit.tpl b/WEB-INF/templates/client_edit.tpl deleted file mode 100644 index 2abf70dc1..000000000 --- a/WEB-INF/templates/client_edit.tpl +++ /dev/null @@ -1,41 +0,0 @@ -{$forms.clientForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - -{if $show_projects} - - - - -{/if} - - - - -
{$i18n.label.client_name} (*):{$forms.clientForm.name.control}
{$i18n.label.client_address}:{$forms.clientForm.address.control}
{$i18n.label.tax}, %:{$forms.clientForm.tax.control} (0{$user->getDecimalMark()}00)
{$i18n.label.status}:{$forms.clientForm.status.control}
{$i18n.label.required_fields}
 
{$i18n.label.projects}:{$forms.clientForm.projects.control}
 
{$forms.clientForm.btn_save.control} {$forms.clientForm.btn_copy.control}
-
-{$forms.clientForm.close} diff --git a/WEB-INF/templates/clients.tpl b/WEB-INF/templates/clients.tpl deleted file mode 100644 index 07b835c87..000000000 --- a/WEB-INF/templates/clients.tpl +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - -
-{if $user->can('manage_clients')} - - {if $inactive_clients} - - {/if} - - - - - - - {foreach $active_clients as $client} - - - - - - - {/foreach} -
{$i18n.form.clients.active_clients}
{$i18n.label.person_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - -

- - {if $inactive_clients} - - - - - - - - - {foreach $inactive_clients as $client} - - - - - - - {/foreach} -
{$i18n.form.clients.inactive_clients}
{$i18n.label.person_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - -

- {/if} -{else} - - - - - - {if $active_clients} - {foreach $active_clients as $client} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.address}
{$client.name|escape}{$client.address|escape}
-{/if} -
diff --git a/WEB-INF/templates/entity_files.tpl b/WEB-INF/templates/entity_files.tpl deleted file mode 100644 index ab9564852..000000000 --- a/WEB-INF/templates/entity_files.tpl +++ /dev/null @@ -1,47 +0,0 @@ - - - - -
- - - - -{if $can_edit} - - -{/if} - -{if $files} - {foreach $files as $file} - - - - {if $can_edit} - - - {/if} - - {/foreach} -{/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$file.name|escape}{$file.description|escape}{$i18n.label.edit}{$i18n.label.delete}
-
- -{if $can_edit} -{$forms.fileUploadForm.open} - - - - -
- - - - - - - -
{$i18n.label.description}:{$forms.fileUploadForm.description.control}{$forms.fileUploadForm.newfile.control}
{$forms.fileUploadForm.btn_submit.control}
-
-{$forms.fileUploadForm.close} -{/if} diff --git a/WEB-INF/templates/expense_delete.tpl b/WEB-INF/templates/expense_delete.tpl deleted file mode 100644 index 6e5bf12c8..000000000 --- a/WEB-INF/templates/expense_delete.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{$forms.expenseItemForm.open} - - - - -
- - -{if $user->isPluginEnabled('cl')} - -{/if} - -{if $show_project} - -{/if} - - - - -{if $user->isPluginEnabled('cl')} - -{/if} -{if $show_project} - -{/if} - - - -
{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$i18n.label.cost}
{$expense_item.client_name|escape}{$expense_item.project_name|escape}{$expense_item.name|escape}{$expense_item.cost}
- - - - - - - -
 
{$forms.expenseItemForm.delete_button.control}  {$forms.expenseItemForm.cancel_button.control}
-
-{$forms.expenseItemForm.close} diff --git a/WEB-INF/templates/expense_edit.tpl b/WEB-INF/templates/expense_edit.tpl deleted file mode 100644 index 671e868cf..000000000 --- a/WEB-INF/templates/expense_edit.tpl +++ /dev/null @@ -1,189 +0,0 @@ - - -{$forms.expenseItemForm.open} - - - - -
- - - - -
- -{if $user->isPluginEnabled('cl')} - - - - -{/if} -{if $show_project} - - - - -{/if} -{if $predefined_expenses} - - - - - - - - -{/if} - - - - - - - - -{if ($user->can('manage_invoices') && $user->isPluginEnabled('ps'))} - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.client} {if $user->isOptionEnabled('client_required')}(*){/if}:{$forms.expenseItemForm.client.control}
{$i18n.label.project} (*):{$forms.expenseItemForm.project.control}
{$i18n.label.expense}:{$forms.expenseItemForm.predefined_expense.control}
{$i18n.label.quantity}:{$forms.expenseItemForm.quantity.control}
{$i18n.label.comment}:{$forms.expenseItemForm.item_name.control}
{$i18n.label.cost}:{$forms.expenseItemForm.cost.control} {$user->getCurrency()|escape}
 
{$i18n.label.date}:{$forms.expenseItemForm.date.control}
 
{$forms.expenseItemForm.btn_save.control} {$forms.expenseItemForm.btn_copy.control} {$forms.expenseItemForm.btn_delete.control}
-
-
-{$forms.expenseItemForm.close} diff --git a/WEB-INF/templates/expenses.tpl b/WEB-INF/templates/expenses.tpl deleted file mode 100644 index 3c5867279..000000000 --- a/WEB-INF/templates/expenses.tpl +++ /dev/null @@ -1,241 +0,0 @@ - - -{$forms.expensesForm.open} - - - - - -
- -{if $user_dropdown} - - - - -{/if} -{if $user->isPluginEnabled('cl')} - - - - -{/if} -{if $show_project} - - - - -{/if} -{if $predefined_expenses} - - - - - - - - -{/if} - - - - - - - - -{if $show_files} - - - - -{/if} -
{$i18n.label.user}:{$forms.expensesForm.user.control}
{$i18n.label.client}{if $user->isOptionEnabled('client_required')} (*){/if}:{$forms.expensesForm.client.control}
{$i18n.label.project} (*):{$forms.expensesForm.project.control}
{$i18n.label.expense}:{$forms.expensesForm.predefined_expense.control}
{$i18n.label.quantity}:{$forms.expensesForm.quantity.control}
{$i18n.label.comment} (*):{$forms.expensesForm.item_name.control}
{$i18n.label.cost} (*):{$forms.expensesForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.file}:{$forms.expensesForm.newfile.control}
-
- - -
{$forms.expensesForm.date.control}
-
- - - - - -
{$forms.expensesForm.btn_submit.control}
- - - - - -
-{if $expense_items} - - - {if $user->isPluginEnabled('cl')} - - {/if} - {if $show_project} - - {/if} - - - {if $show_files} - - {/if} - - - - {foreach $expense_items as $item} - - {if $user->isPluginEnabled('cl')} - - {/if} - {if $show_project} - - {/if} - - - {if $show_files} - {if $item.has_files} - - {else} - - {/if} - {/if} - - - - {/foreach} -
{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$i18n.label.cost}
{$item.client|escape}{$item.project|escape}{$item.item|escape}{$item.cost}{$i18n.label.files}{$i18n.label.files} - {if $item.approved || $item.invoice_id} -   - {else} - {$i18n.label.edit} - {/if} - - {if $item.approved || $item.invoice_id} -   - {else} - {$i18n.label.delete} - {/if} -
- - - - -
{$i18n.label.day_total}: {$user->getCurrency()|escape} {$day_total}
-{/if} -
-{$forms.expensesForm.close} diff --git a/WEB-INF/templates/file_delete.tpl b/WEB-INF/templates/file_delete.tpl deleted file mode 100644 index 81107daa5..000000000 --- a/WEB-INF/templates/file_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.fileDeleteForm.open} - - - - -
- - - - - - - - - -
{$file_to_delete|escape}
 
{$forms.fileDeleteForm.btn_delete.control}  {$forms.fileDeleteForm.btn_cancel.control}
-
-{$forms.fileDeleteForm.close} diff --git a/WEB-INF/templates/file_edit.tpl b/WEB-INF/templates/file_edit.tpl deleted file mode 100644 index 697a650ce..000000000 --- a/WEB-INF/templates/file_edit.tpl +++ /dev/null @@ -1,29 +0,0 @@ -{$forms.fileForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.fileForm.file_name.control}
{$i18n.label.description}:{$forms.fileForm.description.control}
{$i18n.label.required_fields}
 
{$forms.fileForm.btn_save.control}
-
-{$forms.fileForm.close} diff --git a/WEB-INF/templates/project_add.tpl b/WEB-INF/templates/project_add.tpl deleted file mode 100644 index 309b13788..000000000 --- a/WEB-INF/templates/project_add.tpl +++ /dev/null @@ -1,49 +0,0 @@ -{$forms.projectForm.open} - - - - -
- - - - - - - - - -{if $show_files} - - - - -{/if} -{if $show_users} - - - - - -{/if} -{if $show_tasks} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.projectForm.project_name.control}
{$i18n.label.description}:{$forms.projectForm.description.control}
{$i18n.label.file}:{$forms.projectForm.newfile.control}
 
{$i18n.label.users}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}
{$i18n.label.required_fields}
 
{$forms.projectForm.btn_add.control}
-
-{$forms.projectForm.close} diff --git a/WEB-INF/templates/project_delete.tpl b/WEB-INF/templates/project_delete.tpl deleted file mode 100644 index 98d3e836d..000000000 --- a/WEB-INF/templates/project_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.projectDeleteForm.open} - - - - -
- - - - - - - - - -
{$project_to_delete|escape}
 
{$forms.projectDeleteForm.btn_delete.control}  {$forms.projectDeleteForm.btn_cancel.control}
-
-{$forms.projectDeleteForm.close} diff --git a/WEB-INF/templates/project_edit.tpl b/WEB-INF/templates/project_edit.tpl deleted file mode 100644 index 2a2364f20..000000000 --- a/WEB-INF/templates/project_edit.tpl +++ /dev/null @@ -1,47 +0,0 @@ -{$forms.projectForm.open} - - - - -
- - - - - - - - - - - - - -{if $show_users} - - - - - -{/if} -{if $show_tasks} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.projectForm.project_name.control}
{$i18n.label.description}:{$forms.projectForm.description.control}
{$i18n.label.status}:{$forms.projectForm.status.control}
 
{$i18n.label.users}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}
{$i18n.label.required_fields}
 
{$forms.projectForm.btn_save.control} {$forms.projectForm.btn_copy.control}
-
-{$forms.projectForm.close} diff --git a/WEB-INF/templates/projects.tpl b/WEB-INF/templates/projects.tpl deleted file mode 100644 index 19bbe2373..000000000 --- a/WEB-INF/templates/projects.tpl +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - -
-{if $user->can('manage_projects')} - - {if $inactive_projects} - - {/if} - {if $active_projects} - - - - {if $show_files} - - {/if} - - - - {foreach $active_projects as $project} - - - - {if $show_files} - {if $project.has_files} - - {else} - - {/if} - {/if} - - - - {/foreach} - {/if} -
{$i18n.form.projects.active_projects}
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- - {if $inactive_projects} - - - - - - {if $show_files} - - {/if} - - - - {foreach $inactive_projects as $project} - - - - {if $show_files} - {if $project.has_files} - - {else} - - {/if} - {/if} - - - - {/foreach} -
{$i18n.form.projects.inactive_projects}
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}{$i18n.label.files}{$i18n.label.files}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- {/if} -{else} - - - - - {if $show_files} - - {/if} - - {if $active_projects} - {foreach $active_projects as $project} - - - - {if $show_files} - {if $project.has_files} - - {else} - - {/if} - {/if} - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}{$i18n.label.files} 
-{/if} -
diff --git a/WEB-INF/templates/swap_roles.tpl b/WEB-INF/templates/swap_roles.tpl deleted file mode 100644 index 2d3086329..000000000 --- a/WEB-INF/templates/swap_roles.tpl +++ /dev/null @@ -1,15 +0,0 @@ -{$forms.swapForm.open} - -
- - - - - - - - -
{$i18n.form.swap.hint}
 
{$i18n.form.swap.swap_with}:{$forms.swapForm.swap_with.control}
{$forms.swapForm.btn_submit.control} {$forms.swapForm.btn_cancel.control}
-
-{$forms.swapForm.close} diff --git a/WEB-INF/templates/task_add.tpl b/WEB-INF/templates/task_add.tpl deleted file mode 100644 index d1892709a..000000000 --- a/WEB-INF/templates/task_add.tpl +++ /dev/null @@ -1,36 +0,0 @@ -{$forms.taskForm.open} - - - - -
- - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.taskForm.name.control}
{$i18n.label.description}:{$forms.taskForm.description.control}
 
{$i18n.label.projects}:{$forms.taskForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.taskForm.btn_submit.control}
-
-{$forms.taskForm.close} diff --git a/WEB-INF/templates/task_delete.tpl b/WEB-INF/templates/task_delete.tpl deleted file mode 100644 index 9f16d7c3a..000000000 --- a/WEB-INF/templates/task_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.taskDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$task_to_delete|escape}
 
{$forms.taskDeleteForm.btn_delete.control}  {$forms.taskDeleteForm.btn_cancel.control}
-
-{$forms.taskDeleteForm.close} diff --git a/WEB-INF/templates/task_edit.tpl b/WEB-INF/templates/task_edit.tpl deleted file mode 100644 index 0c2b1a555..000000000 --- a/WEB-INF/templates/task_edit.tpl +++ /dev/null @@ -1,40 +0,0 @@ -{$forms.taskForm.open} - - - - -
- - - - - - - - - - - - - -{if $show_projects} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.taskForm.name.control}
{$i18n.label.description}:{$forms.taskForm.description.control}
{$i18n.label.status}:{$forms.taskForm.status.control}
 
{$i18n.label.projects}:{$forms.taskForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.taskForm.btn_save.control} {$forms.taskForm.btn_copy.control}
-
-{$forms.taskForm.close} diff --git a/WEB-INF/templates/tasks.tpl b/WEB-INF/templates/tasks.tpl deleted file mode 100644 index 591820199..000000000 --- a/WEB-INF/templates/tasks.tpl +++ /dev/null @@ -1,96 +0,0 @@ - - -{$forms.tasksForm.open} - - - - -
-{if $user->can('manage_tasks')} - - - - - - - - -
{$forms.tasksForm.task_required.control} {$i18n.label.what_is_it}
{$forms.tasksForm.btn_save.control}
-
- - {if $inactive_tasks} - - {/if} - - - - - - - {if $active_tasks} - {foreach $active_tasks as $task} - - - - - - - {/foreach} - {/if} -
{$i18n.form.tasks.active_tasks}
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- - {if $inactive_tasks} - - - - - - - - - {foreach $inactive_tasks as $task} - - - - - - - {/foreach} -
{$i18n.form.tasks.inactive_tasks}
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- {/if} -{else} - - - - - - {if $active_tasks} - {foreach $active_tasks as $task} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}
-{/if} -
-{$forms.tasksForm.close} diff --git a/WEB-INF/templates/time.tpl b/WEB-INF/templates/time.tpl deleted file mode 100644 index 69d214127..000000000 --- a/WEB-INF/templates/time.tpl +++ /dev/null @@ -1,234 +0,0 @@ -{include file="time_script.tpl"} - - - -{$forms.timeRecordForm.open} - -{if $show_navigation} - - - -{/if} - - - - -
- {$i18n.label.day_view} / {$i18n.label.week_view} -
- -{if $user_dropdown} - - - - -{/if} -{if $show_client} - - - - -{/if} -{if $show_billable} - - - - -{/if} -{if $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - - {/foreach} -{/if} -{if $show_project} - - - - -{/if} -{if $show_task} - - - - -{/if} -{if $show_start} - - - - - - - - -{/if} -{if $show_duration} - - - - -{/if} -{if $show_files} - - - - -{/if} -{if $template_dropdown} - - - - -{/if} -
{$i18n.label.user}:{$forms.timeRecordForm.user.control}
{$i18n.label.client}{if $user->isOptionEnabled('client_required')} (*){/if}:{$forms.timeRecordForm.client.control}
 
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project} (*):{$forms.timeRecordForm.project.control}
{$i18n.label.task}{if $task_required} (*){/if}:{$forms.timeRecordForm.task.control}
{$i18n.label.start}:{$forms.timeRecordForm.start.control} 
{$i18n.label.finish}:{$forms.timeRecordForm.finish.control} 
{$i18n.label.duration}:{$forms.timeRecordForm.duration.control} {if $user->getDecimalMark() == ','}{str_replace('.', ',', $i18n.form.time.duration_format)}{else}{$i18n.form.time.duration_format}{/if}
{$i18n.label.file}:{$forms.timeRecordForm.newfile.control}
{$i18n.label.template}:{$forms.timeRecordForm.template.control}
-
- - -
{$forms.timeRecordForm.date.control}
-
- - - - - - - - - -
{$i18n.label.note}:{$forms.timeRecordForm.note.control}
{$forms.timeRecordForm.btn_submit.control}
- - - - - -
-{if $time_records} - - - {if $show_client} - - {/if} - {if $show_record_custom_fields && $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - {/foreach} - {/if} - {if $show_project} - - {/if} - {if $show_task} - - {/if} - {if $show_start} - - - {/if} - - {if $show_note_column} - - {/if} - {if $show_files} - - {/if} - - - - {foreach $time_records as $record} - - {if $show_client} - - {/if} - {* record custom fileds *} - {if $show_record_custom_fields && $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - {/foreach} - {/if} - {if $show_project} - - {/if} - {if $show_task} - - {/if} - {if $show_start} - - - {/if} - - {if $show_note_column} - - {/if} - {if $show_files} - {if $record.has_files} - - {else} - - {/if} - {/if} - - - - {if $show_note_row && $record.comment} - - - - - {/if} - {/foreach} -
{$i18n.label.client}{$timeField['label']|escape}{$i18n.label.project}{$i18n.label.task}{$i18n.label.start}{$i18n.label.finish}{$i18n.label.duration}{$i18n.label.note}
{$record.client|escape}{$record.$control_name|escape}{$record.project|escape}{$record.task|escape}{if $record.start}{$record.start}{else} {/if}{if $record.finish}{$record.finish}{else} {/if}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}{if $record.comment}{$record.comment|escape}{else} {/if}{$i18n.label.files}{$i18n.label.files} - {if $record.approved || $record.timesheet_id || $record.invoice_id} -   - {else} - {$i18n.label.edit} - {if ($record.duration == '0:00' && $record.start <> '')} - - - - - {/if} - {/if} - - {if $record.approved || $record.timesheet_id || $record.invoice_id} -   - {else} - {$i18n.label.delete} - {/if} -
{$i18n.label.note}:{$record.comment|escape}
-{/if} -
- - - - - - - {if $user->isPluginEnabled('mq')} - - - {if $over_balance} - - {else} - - {/if} - - - - {if $over_quota} - - {else} - - {/if} - - {/if} -
{$i18n.label.week_total}: {$week_total}{$i18n.label.day_total}: {$day_total}
{$i18n.label.month_total}: {$month_total}{$i18n.form.time.over_balance}: {$balance_remaining}{$i18n.form.time.remaining_balance}: {$balance_remaining}
{$i18n.label.quota}: {$month_quota}{$i18n.form.time.over_quota}: {$quota_remaining}{$i18n.form.time.remaining_quota}: {$quota_remaining}
- -{$forms.timeRecordForm.close} diff --git a/WEB-INF/templates/user_add.tpl b/WEB-INF/templates/user_add.tpl deleted file mode 100644 index 35040f3c4..000000000 --- a/WEB-INF/templates/user_add.tpl +++ /dev/null @@ -1,134 +0,0 @@ - - -{$forms.userForm.open} - -
- - - - - - - - -{if !$auth_external} - - - - - - - - -{/if} - - - - - - - - - -{if $show_quota} - - - - -{/if} -{if $custom_fields && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - - - {assign var="control_name" value='user_field_'|cat:$userField['id']} - - - {/foreach} -{/if} - - - - - -{if $show_projects} - - - - - - - -{/if} - - - - - - -
{$i18n.label.person_name} (*):{$forms.userForm.name.control}
{$i18n.label.login} (*):{$forms.userForm.login.control}
{$i18n.label.password} (*):{$forms.userForm.pas1.control}
{$i18n.label.confirm_password} (*):{$forms.userForm.pas2.control}
{$i18n.label.email}:{$forms.userForm.email.control}
{$i18n.form.users.role}:{$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.label.quota} (%):{$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$userField['label']|escape}{if $userField['required']} (*){/if}:{$forms.userForm.$control_name.control}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00):{$forms.userForm.rate.control}
 
{$i18n.label.projects}:{$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
-
-{$forms.userForm.close} diff --git a/WEB-INF/templates/user_delete.tpl b/WEB-INF/templates/user_delete.tpl deleted file mode 100644 index e85d97f1f..000000000 --- a/WEB-INF/templates/user_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.userDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$user_to_delete|escape}
 
{$forms.userDeleteForm.btn_delete.control}  {$forms.userDeleteForm.btn_cancel.control}
-
-{$forms.userDeleteForm.close} diff --git a/WEB-INF/templates/user_edit.tpl b/WEB-INF/templates/user_edit.tpl deleted file mode 100644 index 49fa4ae50..000000000 --- a/WEB-INF/templates/user_edit.tpl +++ /dev/null @@ -1,168 +0,0 @@ - - -{$forms.userForm.open} - -
- - - - - - - - -{if !$auth_external} - - - - - - - - -{/if} - - - - -{if $user->id != $user_id} - - - - - - - - -{/if} -{if $user->id == $user_id} - - - - -{/if} - -{if $show_quota} - - - - -{/if} -{if $custom_fields && $custom_fields->userFields} - {foreach $custom_fields->userFields as $userField} - - - {assign var="control_name" value='user_field_'|cat:$userField['id']} - - - {/foreach} -{/if} - - - - - -{if $show_projects} - - - - - - - -{/if} - - - - - - -
{$i18n.label.person_name} (*):{$forms.userForm.name.control}
{$i18n.label.login} (*):{$forms.userForm.login.control}
{$i18n.label.password} (*):{$forms.userForm.pas1.control}
{$i18n.label.confirm_password} (*):{$forms.userForm.pas2.control}
{$i18n.label.email}:{$forms.userForm.email.control}
{$i18n.form.users.role}:{$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.label.status}:{$forms.userForm.status.control}
{$i18n.form.users.role}:{$user->role_name} {if $can_swap}{$i18n.form.user_edit.swap_roles}{/if}
{$i18n.label.quota} (%):{$forms.userForm.quota_percent.control} {$i18n.label.what_is_it}
{$userField['label']|escape}{if $userField['required']} (*){/if}:{$forms.userForm.$control_name.control}
{$i18n.form.users.default_rate} (0{$user->getDecimalMark()}00):{$forms.userForm.rate.control}
 
{$i18n.label.projects}:{$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
-
-{$forms.userForm.close} diff --git a/WEB-INF/templates/users.tpl b/WEB-INF/templates/users.tpl deleted file mode 100644 index c3f6861ea..000000000 --- a/WEB-INF/templates/users.tpl +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - -
-{if $user->can('manage_users')} - - {if $inactive_users} - - {/if} - {if $active_users} - - - - - {if $show_quota} - - {/if} - - - - {foreach $active_users as $u} - - - - - {if $show_quota} - - {/if} - {if $u.group_id != $user->group_id || $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} - - {if $u.id != $user->id}{else}{/if} - {else} - - - {/if} - - {/foreach} - {/if} -
{$i18n.label.active_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}{$i18n.label.quota}
- {if $uncompleted_indicators} - - {/if} - {$u.name|escape} - {$u.login|escape}{$u.role_name|escape}{$u.quota_percent}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -

-
-
- - {if $inactive_users} - - - - - - - {if $show_quota} - - {/if} - - - - {foreach $inactive_users as $u} - - - - - {if $show_quota} - - {/if} - {if $u.group_id != $user->group_id || $u.rank < $user->rank} - - - {else} - - - {/if} - - {/foreach} - -
{$i18n.label.inactive_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}{$i18n.label.quota}
{$u.name|escape}{$u.login|escape}{$u.role_name|escape}{$u.quota_percent}{$i18n.label.edit}{$i18n.label.delete}
- - - - - -
-
-
- {/if} -{else} - - - - - - - {foreach $active_users as $u} - - - - - - {/foreach} -
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}
- {if $uncompleted_indicators} - - {/if} - {$u.name|escape} - {$u.login|escape}{$u.role_name|escape}
-{/if} -
diff --git a/expense_files.php b/expense_files.php index feab9b611..5642cb383 100644 --- a/expense_files.php +++ b/expense_files.php @@ -1,30 +1,6 @@ addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -85,5 +61,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.expense_files')); -$smarty->assign('content_page_name', 'entity_files.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'entity_files2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index a863d270f..a222510c9 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5404"); +define("APP_VERSION", "1.19.23.5405"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/project_files.php b/project_files.php index 6ffe123f1..5dd816d6c 100644 --- a/project_files.php +++ b/project_files.php @@ -1,30 +1,6 @@ addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -85,5 +61,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.project_files').': '.$project['name']); -$smarty->assign('content_page_name', 'entity_files.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'entity_files2.tpl'); +$smarty->display('index2.tpl'); diff --git a/timesheet_delete.php b/timesheet_delete.php index 5e98a6cc9..ff1e4e180 100644 --- a/timesheet_delete.php +++ b/timesheet_delete.php @@ -1,30 +1,6 @@ addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_timesheet_id)); $form->addInput(array('type'=>'upload','name'=>'newfile','value'=>$i18n->get('button.submit'))); -$form->addInput(array('type'=>'textarea','name'=>'description','style'=>'width: 250px; height: 40px;','value'=>$cl_description)); +$form->addInput(array('type'=>'textarea','name'=>'description','value'=>$cl_description)); $form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); if ($request->isPost()) { @@ -85,5 +61,5 @@ $smarty->assign('forms', array($form->getName()=>$form->toArray())); $smarty->assign('files', $files); $smarty->assign('title', $i18n->get('title.timesheet_files').': '.$timesheet['name']); -$smarty->assign('content_page_name', 'entity_files.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'entity_files2.tpl'); +$smarty->display('index2.tpl'); From 4500d03942456a4be84e82635412c0ebacf5d152 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 6 Dec 2020 21:35:10 +0000 Subject: [PATCH 217/652] Some more cleanup. --- .../{access_denied.tpl => access_denied2.tpl} | 0 .../{file_download.tpl => file_download2.tpl} | 0 access_denied.php | 2 +- client_add1.php | 94 ------------------- client_delete1.php | 78 --------------- feature_disabled.php | 32 +------ file_download.php | 4 +- initialize.php | 2 +- 8 files changed, 8 insertions(+), 204 deletions(-) rename WEB-INF/templates/{access_denied.tpl => access_denied2.tpl} (100%) rename WEB-INF/templates/{file_download.tpl => file_download2.tpl} (100%) delete mode 100644 client_add1.php delete mode 100644 client_delete1.php diff --git a/WEB-INF/templates/access_denied.tpl b/WEB-INF/templates/access_denied2.tpl similarity index 100% rename from WEB-INF/templates/access_denied.tpl rename to WEB-INF/templates/access_denied2.tpl diff --git a/WEB-INF/templates/file_download.tpl b/WEB-INF/templates/file_download2.tpl similarity index 100% rename from WEB-INF/templates/file_download.tpl rename to WEB-INF/templates/file_download2.tpl diff --git a/access_denied.php b/access_denied.php index 7025d8739..2aa3c5d77 100644 --- a/access_denied.php +++ b/access_denied.php @@ -8,5 +8,5 @@ if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. $smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'access_denied.tpl'); +$smarty->assign('content_page_name', 'access_denied2.tpl'); $smarty->display('index2.tpl'); diff --git a/client_add1.php b/client_add1.php deleted file mode 100644 index 820a32fde..000000000 --- a/client_add1.php +++ /dev/null @@ -1,94 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_address = trim($request->getParameter('address')); - $cl_tax = $request->getParameter('tax'); - $cl_projects = $request->getParameter('projects'); -} else { - // Do not assign all projects to a new client by default. This should help to reduce clutter. - // foreach ($projects as $project_item) - // $cl_projects[] = $project_item['id']; -} - -$show_projects = (MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode()) && count($projects) > 0; - -$form = new Form('clientForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 350px;','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','style'=>'width: 350px; height: 80px;','value'=>$cl_address)); -$form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax)); -if ($show_projects) - $form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.client_name')); - if (!ttValidString($cl_address, true)) $err->add($i18n->get('error.field'), $i18n->get('label.client_address')); - if (!ttValidFloat($cl_tax, true)) $err->add($i18n->get('error.field'), $i18n->get('label.tax')); - - if ($err->no()) { - if (!ttClientHelper::getClientByName($cl_name)) { - if (ttClientHelper::insert(array('name' => $cl_name, - 'address' => $cl_address, - 'tax' => $cl_tax, - 'projects' => $cl_projects, - 'status' => ACTIVE))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"'); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.add_client')); -$smarty->assign('content_page_name', 'client_add.tpl'); -$smarty->display('index.tpl'); diff --git a/client_delete1.php b/client_delete1.php deleted file mode 100644 index a5f00656e..000000000 --- a/client_delete1.php +++ /dev/null @@ -1,78 +0,0 @@ -isPluginEnabled('cl')) { - header('Location: feature_disabled.php'); - exit(); -} -$id = (int)$request->getParameter('id'); -$client = ttClientHelper::getClient($id); -if (!$client) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$client_to_delete = $client['name']; - -$form = new Form('clientDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$id)); -$form->addInput(array('type'=>'combobox','name'=>'delete_client_entries', - 'data'=>array('0'=>$i18n->get('dropdown.do_not_delete'),'1'=>$i18n->get('dropdown.delete')))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if (ttClientHelper::delete($id, $request->getParameter('delete_client_entries'))) { - header('Location: clients.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - - if ($request->getParameter('btn_cancel')) { - header('Location: clients.php'); - exit(); - } -} // isPost - -$smarty->assign('client_to_delete', $client_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.delete_client')); -$smarty->assign('content_page_name', 'client_delete.tpl'); -$smarty->display('index.tpl'); diff --git a/feature_disabled.php b/feature_disabled.php index 7f0bb81f5..c04afe734 100644 --- a/feature_disabled.php +++ b/feature_disabled.php @@ -1,30 +1,6 @@ isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. $smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'access_denied.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'access_denied2.tpl'); +$smarty->display('index2.tpl'); diff --git a/file_download.php b/file_download.php index ac076b27e..0c323f7f3 100644 --- a/file_download.php +++ b/file_download.php @@ -83,5 +83,5 @@ } $smarty->assign('title', $i18n->get('title.download_file')); -$smarty->assign('content_page_name', 'file_download.tpl'); -$smarty->display('index.tpl'); +$smarty->assign('content_page_name', 'file_download2.tpl'); +$smarty->display('index2.tpl'); diff --git a/initialize.php b/initialize.php index a222510c9..0af6f6c3c 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5405"); +define("APP_VERSION", "1.19.23.5406"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 684c41fbf421859d01fbd7391d7bbb7fef430bc8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 7 Dec 2020 17:28:19 +0000 Subject: [PATCH 218/652] Removed no longer used mobile pages. --- WEB-INF/templates/mobile/access_denied.tpl | 1 - WEB-INF/templates/mobile/expense_delete.tpl | 39 -- WEB-INF/templates/mobile/expense_edit.tpl | 183 -------- WEB-INF/templates/mobile/project_add.tpl | 43 -- WEB-INF/templates/mobile/project_delete.tpl | 18 - WEB-INF/templates/mobile/project_edit.tpl | 47 -- WEB-INF/templates/mobile/task_add.tpl | 33 -- WEB-INF/templates/mobile/task_delete.tpl | 20 - WEB-INF/templates/mobile/task_edit.tpl | 37 -- WEB-INF/templates/mobile/time_delete.tpl | 32 -- WEB-INF/templates/mobile/time_edit.tpl | 76 --- WEB-INF/templates/mobile/user_add.tpl | 124 ----- WEB-INF/templates/mobile/user_delete.tpl | 20 - WEB-INF/templates/mobile/user_edit.tpl | 153 ------ initialize.php | 2 +- mobile/access_denied.php | 36 -- mobile/expense_delete.php | 88 ---- mobile/expense_edit.php | 238 ---------- mobile/expenses.php | 5 + mobile/feature_disabled.php | 36 -- mobile/index.php | 5 + mobile/project_add.php | 103 ---- mobile/project_delete.php | 75 --- mobile/project_edit.php | 142 ------ mobile/projects.php | 5 + mobile/task_add.php | 87 ---- mobile/task_delete.php | 78 ---- mobile/task_edit.php | 128 ----- mobile/tasks.php | 5 + mobile/time_delete.php | 89 ---- mobile/time_edit.php | 494 -------------------- mobile/user_add.php | 186 -------- mobile/user_delete.php | 87 ---- mobile/user_edit.php | 245 ---------- mobile/users.php | 5 + 35 files changed, 26 insertions(+), 2939 deletions(-) delete mode 100644 WEB-INF/templates/mobile/access_denied.tpl delete mode 100644 WEB-INF/templates/mobile/expense_delete.tpl delete mode 100644 WEB-INF/templates/mobile/expense_edit.tpl delete mode 100644 WEB-INF/templates/mobile/project_add.tpl delete mode 100644 WEB-INF/templates/mobile/project_delete.tpl delete mode 100644 WEB-INF/templates/mobile/project_edit.tpl delete mode 100644 WEB-INF/templates/mobile/task_add.tpl delete mode 100644 WEB-INF/templates/mobile/task_delete.tpl delete mode 100644 WEB-INF/templates/mobile/task_edit.tpl delete mode 100644 WEB-INF/templates/mobile/time_delete.tpl delete mode 100644 WEB-INF/templates/mobile/time_edit.tpl delete mode 100644 WEB-INF/templates/mobile/user_add.tpl delete mode 100644 WEB-INF/templates/mobile/user_delete.tpl delete mode 100644 WEB-INF/templates/mobile/user_edit.tpl delete mode 100644 mobile/access_denied.php delete mode 100644 mobile/expense_delete.php delete mode 100644 mobile/expense_edit.php delete mode 100644 mobile/feature_disabled.php delete mode 100644 mobile/project_add.php delete mode 100644 mobile/project_delete.php delete mode 100644 mobile/project_edit.php delete mode 100644 mobile/task_add.php delete mode 100644 mobile/task_delete.php delete mode 100644 mobile/task_edit.php delete mode 100644 mobile/time_delete.php delete mode 100644 mobile/time_edit.php delete mode 100644 mobile/user_add.php delete mode 100644 mobile/user_delete.php delete mode 100644 mobile/user_edit.php diff --git a/WEB-INF/templates/mobile/access_denied.tpl b/WEB-INF/templates/mobile/access_denied.tpl deleted file mode 100644 index c341a4039..000000000 --- a/WEB-INF/templates/mobile/access_denied.tpl +++ /dev/null @@ -1 +0,0 @@ - diff --git a/WEB-INF/templates/mobile/expense_delete.tpl b/WEB-INF/templates/mobile/expense_delete.tpl deleted file mode 100644 index bd14824e2..000000000 --- a/WEB-INF/templates/mobile/expense_delete.tpl +++ /dev/null @@ -1,39 +0,0 @@ -{$forms.expenseItemForm.open} - - - - -
- - -{if $user->isPluginEnabled('cl')} - -{/if} - -{if $show_project} - -{/if} - - - - -{if $user->isPluginEnabled('cl')} - -{/if} -{if $show_project} - -{/if} - - - -
{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$i18n.label.cost}
{$expense_item.client_name|escape}{$expense_item.project_name|escape}{$expense_item.name|escape}{$expense_item.cost}
- - - - - - - -
 
{$forms.expenseItemForm.delete_button.control}  {$forms.expenseItemForm.cancel_button.control}
-
-{$forms.expenseItemForm.close} diff --git a/WEB-INF/templates/mobile/expense_edit.tpl b/WEB-INF/templates/mobile/expense_edit.tpl deleted file mode 100644 index d4834ae1a..000000000 --- a/WEB-INF/templates/mobile/expense_edit.tpl +++ /dev/null @@ -1,183 +0,0 @@ - - -{$forms.expenseItemForm.open} - - - - -
- - - - -
- -{if $user->isPluginEnabled('cl')} - - - - -{/if} -{if $show_project} - - - - -{/if} -{if $predefined_expenses} - - - - - - - - -{/if} - - - - - - - - - - - - - - - - - - - -
{$i18n.label.client} {if $user->isOptionEnabled('client_required')}(*){/if}:{$forms.expenseItemForm.client.control}
{$i18n.label.project} (*):{$forms.expenseItemForm.project.control}
{$i18n.label.expense}:{$forms.expenseItemForm.predefined_expense.control}
{$i18n.label.quantity}:{$forms.expenseItemForm.quantity.control}
{$i18n.label.item}:{$forms.expenseItemForm.item_name.control}
{$i18n.label.cost}:{$forms.expenseItemForm.cost.control} {$user->getCurrency()|escape}
{$i18n.label.date}:{$forms.expenseItemForm.date.control}
 
{$forms.expenseItemForm.btn_save.control} {$forms.expenseItemForm.btn_copy.control} {$forms.expenseItemForm.btn_delete.control}
-
-
-{$forms.expenseItemForm.close} diff --git a/WEB-INF/templates/mobile/project_add.tpl b/WEB-INF/templates/mobile/project_add.tpl deleted file mode 100644 index d49b9a33e..000000000 --- a/WEB-INF/templates/mobile/project_add.tpl +++ /dev/null @@ -1,43 +0,0 @@ -{$forms.projectForm.open} - - - - -
- - - - - - - - - -{if $show_users} - - - - - -{/if} -{if $show_tasks} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.projectForm.project_name.control}
{$i18n.label.description}:{$forms.projectForm.description.control}
 
{$i18n.label.users}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}
{$i18n.label.required_fields}
 
{$forms.projectForm.btn_add.control}
-
-{$forms.projectForm.close} diff --git a/WEB-INF/templates/mobile/project_delete.tpl b/WEB-INF/templates/mobile/project_delete.tpl deleted file mode 100644 index 98d3e836d..000000000 --- a/WEB-INF/templates/mobile/project_delete.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{$forms.projectDeleteForm.open} - - - - -
- - - - - - - - - -
{$project_to_delete|escape}
 
{$forms.projectDeleteForm.btn_delete.control}  {$forms.projectDeleteForm.btn_cancel.control}
-
-{$forms.projectDeleteForm.close} diff --git a/WEB-INF/templates/mobile/project_edit.tpl b/WEB-INF/templates/mobile/project_edit.tpl deleted file mode 100644 index 871f5c1dc..000000000 --- a/WEB-INF/templates/mobile/project_edit.tpl +++ /dev/null @@ -1,47 +0,0 @@ -{$forms.projectForm.open} - - - - -
- - - - - - - - - - - - - -{if $show_users} - - - - - -{/if} -{if $show_tasks} - - - - - -{/if} - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.projectForm.project_name.control}
{$i18n.label.description}:{$forms.projectForm.description.control}
{$i18n.label.status}:{$forms.projectForm.status.control}
 
{$i18n.label.users}:{$forms.projectForm.users.control}
 
{$i18n.label.tasks}:{$forms.projectForm.tasks.control}
{$i18n.label.required_fields}
 
{$forms.projectForm.btn_save.control} {$forms.projectForm.btn_copy.control} {$forms.projectForm.btn_delete.control}
-
-{$forms.projectForm.close} diff --git a/WEB-INF/templates/mobile/task_add.tpl b/WEB-INF/templates/mobile/task_add.tpl deleted file mode 100644 index 68e415e1c..000000000 --- a/WEB-INF/templates/mobile/task_add.tpl +++ /dev/null @@ -1,33 +0,0 @@ -{$forms.taskForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.taskForm.name.control}
{$i18n.label.description}:{$forms.taskForm.description.control}
{$i18n.label.projects}:{$forms.taskForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.taskForm.btn_submit.control}
-
-{$forms.taskForm.close} diff --git a/WEB-INF/templates/mobile/task_delete.tpl b/WEB-INF/templates/mobile/task_delete.tpl deleted file mode 100644 index 9f16d7c3a..000000000 --- a/WEB-INF/templates/mobile/task_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.taskDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$task_to_delete|escape}
 
{$forms.taskDeleteForm.btn_delete.control}  {$forms.taskDeleteForm.btn_cancel.control}
-
-{$forms.taskDeleteForm.close} diff --git a/WEB-INF/templates/mobile/task_edit.tpl b/WEB-INF/templates/mobile/task_edit.tpl deleted file mode 100644 index f6672c739..000000000 --- a/WEB-INF/templates/mobile/task_edit.tpl +++ /dev/null @@ -1,37 +0,0 @@ -{$forms.taskForm.open} - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{$i18n.label.thing_name} (*):{$forms.taskForm.name.control}
{$i18n.label.description}:{$forms.taskForm.description.control}
{$i18n.label.status}:{$forms.taskForm.status.control}
{$i18n.label.projects}:{$forms.taskForm.projects.control}
{$i18n.label.required_fields}
 
{$forms.taskForm.btn_save.control} {$forms.taskForm.btn_copy.control} {$forms.taskForm.btn_delete.control}
-
-{$forms.taskForm.close} diff --git a/WEB-INF/templates/mobile/time_delete.tpl b/WEB-INF/templates/mobile/time_delete.tpl deleted file mode 100644 index 2e3ac7fea..000000000 --- a/WEB-INF/templates/mobile/time_delete.tpl +++ /dev/null @@ -1,32 +0,0 @@ -{$forms.timeRecordForm.open} - - - - -
- - -{if $show_project} - -{/if} - - - - -{if $show_project} - -{/if} - - - -
{$i18n.label.project}{$i18n.label.duration}{$i18n.label.note}
{$time_rec.project_name|escape}{if ($time_rec.duration == '0:00' && $time_rec.start <> '')}{$i18n.form.time.uncompleted}{else}{$time_rec.duration}{/if}{if $time_rec.comment}{$time_rec.comment|escape}{else} {/if}
- - - - - - - -
 
{$forms.timeRecordForm.delete_button.control}  {$forms.timeRecordForm.cancel_button.control}
-
-{$forms.timeRecordForm.close} diff --git a/WEB-INF/templates/mobile/time_edit.tpl b/WEB-INF/templates/mobile/time_edit.tpl deleted file mode 100644 index 3025a63f7..000000000 --- a/WEB-INF/templates/mobile/time_edit.tpl +++ /dev/null @@ -1,76 +0,0 @@ -{include file="time_script.tpl"} - -{* Conditional include of confirmSave handler. *} -{if $confirm_save} - -{/if} - -{$forms.timeRecordForm.open} - - - - -
- - - - -
- -{if $show_client} - - -{/if} -{if $show_billable} - -{/if} -{if $show_paid_status} - -{/if} -{if $custom_fields && $custom_fields->timeFields} - {foreach $custom_fields->timeFields as $timeField} - - {assign var="control_name" value='time_field_'|cat:$timeField['id']} - - {/foreach} -{/if} -{if $show_project} - - -{/if} -{if $show_task} - - -{/if} -{if $show_start} - - - - -{/if} -{if $show_duration} - - -{/if} - - -{if $template_dropdown} - - -{/if} - - - -
{$i18n.label.client}:
{$forms.timeRecordForm.client.control}
{$timeField['label']|escape}{if $timeField['required']} (*){/if}:
{$forms.timeRecordForm.$control_name.control}
{$i18n.label.project}:
{$forms.timeRecordForm.project.control}
{$i18n.label.task}{if $task_required} (*){/if}:
{$forms.timeRecordForm.task.control}
{$i18n.label.start}:
{$forms.timeRecordForm.start.control} 
{$i18n.label.finish}:
{$forms.timeRecordForm.finish.control} 
{$i18n.label.duration}:
{$forms.timeRecordForm.duration.control}
{$i18n.label.date}:
{$forms.timeRecordForm.date.control}
{$i18n.label.template}:
{$forms.timeRecordForm.template.control}
{$i18n.label.note}:
{$forms.timeRecordForm.note.control}
{$forms.timeRecordForm.btn_save.control} {$forms.timeRecordForm.btn_copy.control} {$forms.timeRecordForm.btn_delete.control}
-
-
-{$forms.timeRecordForm.close} diff --git a/WEB-INF/templates/mobile/user_add.tpl b/WEB-INF/templates/mobile/user_add.tpl deleted file mode 100644 index 9df99ff00..000000000 --- a/WEB-INF/templates/mobile/user_add.tpl +++ /dev/null @@ -1,124 +0,0 @@ - - -{$forms.userForm.open} - -
- - - - - - - - -{if !$auth_external} - - - - - - - - -{/if} - - - - - - - - - -{if $show_quota} - - - - -{/if} - - - - - -{if $show_projects} - - - - - - -{/if} - - - - - - -
{$i18n.label.person_name} (*):{$forms.userForm.name.control}
{$i18n.label.login} (*):{$forms.userForm.login.control}
{$i18n.label.password} (*):{$forms.userForm.pas1.control}
{$i18n.label.confirm_password} (*):{$forms.userForm.pas2.control}
{$i18n.label.email}:{$forms.userForm.email.control}
{$i18n.form.users.role}:{$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.label.quota} (%):{$forms.userForm.quota_percent.control}
{$i18n.form.users.default_rate} (0{$user->decimal_mark}00):{$forms.userForm.rate.control}
{$i18n.label.projects}:{$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control}
-
-{$forms.userForm.close} diff --git a/WEB-INF/templates/mobile/user_delete.tpl b/WEB-INF/templates/mobile/user_delete.tpl deleted file mode 100644 index e85d97f1f..000000000 --- a/WEB-INF/templates/mobile/user_delete.tpl +++ /dev/null @@ -1,20 +0,0 @@ -{$forms.userDeleteForm.open} - - - - -
- - - - - - - - - - - -
{$user_to_delete|escape}
 
{$forms.userDeleteForm.btn_delete.control}  {$forms.userDeleteForm.btn_cancel.control}
-
-{$forms.userDeleteForm.close} diff --git a/WEB-INF/templates/mobile/user_edit.tpl b/WEB-INF/templates/mobile/user_edit.tpl deleted file mode 100644 index 03c5db2ef..000000000 --- a/WEB-INF/templates/mobile/user_edit.tpl +++ /dev/null @@ -1,153 +0,0 @@ - - - -{$forms.userForm.open} - -
- - - - - - - - -{if !$auth_external} - - - - - - - - -{/if} - - - - -{if $user->id != $user_id} - - - - - - - - -{/if} - -{if $show_quota} - - - - -{/if} - - - - - -{if $show_projects} - - - - - - -{/if} - - - - - - -
{$i18n.label.person_name} (*):{$forms.userForm.name.control}
{$i18n.label.login} (*):{$forms.userForm.login.control}
{$i18n.label.password} (*):{$forms.userForm.pas1.control}
{$i18n.label.confirm_password} (*):{$forms.userForm.pas2.control}
{$i18n.label.email}:{$forms.userForm.email.control}
{$i18n.form.users.role}:{$forms.userForm.role.control} {$forms.userForm.client.control}
{$i18n.label.status}:{$forms.userForm.status.control}
{$i18n.label.quota} (%):{$forms.userForm.quota_percent.control}
{$i18n.form.users.default_rate} (0{$user->decimal_mark}00):{$forms.userForm.rate.control}
{$i18n.label.projects}:{$forms.userForm.projects.control}
{$i18n.label.required_fields}
{$forms.userForm.btn_submit.control} {$forms.userForm.btn_delete.control}
- -{$forms.userForm.close} diff --git a/initialize.php b/initialize.php index 0af6f6c3c..265d13aea 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5406"); +define("APP_VERSION", "1.19.23.5407"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/access_denied.php b/mobile/access_denied.php deleted file mode 100644 index 6e7174a26..000000000 --- a/mobile/access_denied.php +++ /dev/null @@ -1,36 +0,0 @@ -add($i18n->get('error.access_denied')); -if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. - -$smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'mobile/access_denied.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/expense_delete.php b/mobile/expense_delete.php deleted file mode 100644 index 48e74dc0e..000000000 --- a/mobile/expense_delete.php +++ /dev/null @@ -1,88 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -// Get the expense item we are deleting. -$expense_item = ttExpenseHelper::getItem($cl_id); -if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { - // Prohibit deleting not ours, approved, or invoiced items. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -if ($request->isPost()) { - if ($request->getParameter('delete_button')) { // Delete button pressed. - - // Determine if it is okay to delete the record. - $item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - if ($err->no()) { - // Mark the record as deleted. - if (ttExpenseHelper::markDeleted($cl_id)) { - header('Location: expenses.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } - if ($request->getParameter('cancel_button')) { // Cancel button pressed. - header('Location: expenses.php'); - exit(); - } -} // isPost - -$form = new Form('expenseItemForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); - -$show_project = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); - -$smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('expense_item', $expense_item); -$smarty->assign('show_project', $show_project); -$smarty->assign('title', $i18n->get('title.delete_expense')); -$smarty->assign('content_page_name', 'mobile/expense_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/expense_edit.php b/mobile/expense_edit.php deleted file mode 100644 index 67813a6f1..000000000 --- a/mobile/expense_edit.php +++ /dev/null @@ -1,238 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_id = (int)$request->getParameter('id'); -// Get the expense item we are editing. -$expense_item = ttExpenseHelper::getItem($cl_id); -if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { - // Prohibit editing not ours, approved, or invoiced items. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$item_date = new DateAndTime(DB_DATEFORMAT, $expense_item['date']); -$confirm_save = $user->getConfigOption('confirm_save'); -$trackingMode = $user->getTrackingMode(); -$show_project = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; - -// Initialize variables. -$cl_date = $cl_client = $cl_project = $cl_item_name = $cl_cost = null; -if ($request->isPost()) { - $cl_date = trim($request->getParameter('date')); - $cl_client = $request->getParameter('client'); - $cl_project = $request->getParameter('project'); - $cl_item_name = trim($request->getParameter('item_name')); - $cl_cost = trim($request->getParameter('cost')); -} else { - $cl_date = $item_date->toString($user->getDateFormat()); - $cl_client = $expense_item['client_id']; - $cl_project = $expense_item['project_id']; - $cl_item_name = $expense_item['name']; - $cl_cost = $expense_item['cost']; -} - -// Initialize elements of 'expenseItemForm'. -$form = new Form('expenseItemForm'); - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $trackingMode && $user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -if ($show_project) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} -// If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); -if ($predefined_expenses) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'recalculateCost();', - 'name'=>'predefined_expense', - 'style'=>'width: 250px;', - 'value'=>$cl_predefined_expense, - 'data'=>$predefined_expenses, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'item_name','style'=>'width: 250px;','value'=>$cl_item_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -$form->addInput(array('type'=>'datefield','name'=>'date','maxlength'=>'20','value'=>$cl_date)); -// Hidden control for record id. -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save or btn_copy click. -$on_click_action = 'browser_today.value=get_date();'; -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); -if ($confirm_save) $on_click_action .= 'return(confirmSave());'; -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - if ($show_project && !$cl_project) - $err->add($i18n->get('error.project')); - if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); - if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); - - // This is a new date for the expense item. - $new_date = new DateAndTime($user->getDateFormat(), $cl_date); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($new_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating input data. - - // Save record. - if ($request->getParameter('btn_save')) { - // We need to: - // 1) Prohibit updating locked entries (that are in locked range). - // 2) Prohibit saving unlocked entries into locked range. - - // Now, step by step. - // 1) Prohibit saving locked entries in any form. - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - // 2) Prohibit saving unlocked entries into locked range. - if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // Now, an update. - if ($err->no()) { - if (ttExpenseHelper::update(array('id'=>$cl_id,'date'=>$new_date->toString(DB_DATEFORMAT), - 'client_id'=>$cl_client,'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } - } - } - - // Save as new record. - if ($request->getParameter('btn_copy')) { - // We need to prohibit saving into locked interval. - if ($user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // Now, a new insert. - if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$new_date->toString(DB_DATEFORMAT),'client_id'=>$cl_client, - 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { - header('Location: expenses.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } - - if ($request->getParameter('btn_delete')) { - header("Location: expense_delete.php?id=$cl_id"); - exit(); - } -} // isPost - -if ($confirm_save) { - $smarty->assign('confirm_save', true); - $smarty->assign('entry_date', $cl_date); -} -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_project', $show_project); -$smarty->assign('predefined_expenses', $predefined_expenses); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('title', $i18n->get('title.edit_expense')); -$smarty->assign('content_page_name', 'mobile/expense_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/expenses.php b/mobile/expenses.php index 05d469985..463671f4a 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -34,6 +34,11 @@ import('ttTimeHelper'); import('ttExpenseHelper'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../expenses.php'); +exit(); +// Below is no longer used code. + // Access checks. if (!(ttAccessAllowed('track_own_expenses') || ttAccessAllowed('track_expenses'))) { header('Location: access_denied.php'); diff --git a/mobile/feature_disabled.php b/mobile/feature_disabled.php deleted file mode 100644 index cf399568e..000000000 --- a/mobile/feature_disabled.php +++ /dev/null @@ -1,36 +0,0 @@ -add($i18n->get('error.feature_disabled')); -if ($auth->isAuthenticated()) $smarty->assign('authenticated', true); // Used in header.tpl for menu display. - -$smarty->assign('title', $i18n->get('label.error')); -$smarty->assign('content_page_name', 'mobile/access_denied.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/index.php b/mobile/index.php index 8fc64b35e..88408af23 100644 --- a/mobile/index.php +++ b/mobile/index.php @@ -28,6 +28,11 @@ require_once('../initialize.php'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../index.php'); +exit(); +// Below is no longer used code. + // Redirects for admin and client roles. if ($auth->isAuthenticated()) { if ($user->can('administer_site')) { diff --git a/mobile/project_add.php b/mobile/project_add.php deleted file mode 100644 index c152006f3..000000000 --- a/mobile/project_add.php +++ /dev/null @@ -1,103 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$users = ttGroupHelper::getActiveUsers(); -foreach ($users as $user_item) - $all_users[$user_item['id']] = $user_item['name']; - -$tasks = ttGroupHelper::getActiveTasks(); -foreach ($tasks as $task_item) - $all_tasks[$task_item['id']] = $task_item['name']; -$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('project_name')); - $cl_description = trim($request->getParameter('description')); - $cl_users = $request->getParameter('users', array()); - $cl_tasks = $request->getParameter('tasks', array()); -} else { - foreach ($users as $user_item) - $cl_users[] = $user_item['id']; - foreach ($tasks as $task_item) - $cl_tasks[] = $task_item['id']; -} - -$form = new Form('projectForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); -$form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if ($show_tasks) - $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_add','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); - - if ($err->no()) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); -$smarty->assign('title', $i18n->get('title.add_project')); -$smarty->assign('content_page_name', 'mobile/project_add.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/project_delete.php b/mobile/project_delete.php deleted file mode 100644 index ac957e249..000000000 --- a/mobile/project_delete.php +++ /dev/null @@ -1,75 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_project_id = (int)$request->getParameter('id'); -$project = ttProjectHelper::get($cl_project_id); -if (!$project) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$project_to_delete = $project['name']; - -$form = new Form('projectDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if (ttProjectHelper::delete($cl_project_id)) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } elseif ($request->getParameter('btn_cancel')) { - header('Location: projects.php'); - exit(); - } -} // isPost - -$smarty->assign('project_to_delete', $project_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_project')); -$smarty->assign('content_page_name', 'mobile/project_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/project_edit.php b/mobile/project_edit.php deleted file mode 100644 index 31da38903..000000000 --- a/mobile/project_edit.php +++ /dev/null @@ -1,142 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_project_id = (int)$request->getParameter('id'); -$project = ttProjectHelper::get($cl_project_id); -if (!$project) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$users = ttGroupHelper::getActiveUsers(); -foreach ($users as $user_item) - $all_users[$user_item['id']] = $user_item['name']; - -$tasks = ttGroupHelper::getActiveTasks(); -foreach ($tasks as $task_item) - $all_tasks[$task_item['id']] = $task_item['name']; -$show_tasks = MODE_PROJECTS_AND_TASKS == $user->getTrackingMode() && count($tasks) > 0; - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('project_name')); - $cl_description = trim($request->getParameter('description')); - $cl_status = $request->getParameter('status'); - $cl_users = $request->getParameter('users', array()); - $cl_tasks = $request->getParameter('tasks', array()); -} else { - $cl_name = $project['name']; - $cl_description = $project['description']; - $cl_status = $project['status']; - $cl_users = ttProjectHelper::getAssignedUsers($cl_project_id); - $cl_tasks = explode(',', $project['tasks']); -} - -$form = new Form('projectForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_project_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'project_name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'users','data'=>$all_users,'layout'=>'H','value'=>$cl_users)); -if ($show_tasks) - $form->addInput(array('type'=>'checkboxgroup','name'=>'tasks','data'=>$all_tasks,'layout'=>'H','value'=>$cl_tasks)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_users, 'tt_users')) $err->add($i18n->get('error.field'), $i18n->get('label.users')); - if (!ttGroupHelper::validateCheckboxGroupInput($cl_tasks, 'tt_tasks')) $err->add($i18n->get('error.field'), $i18n->get('label.tasks')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $existing_project = ttProjectHelper::getProjectByName($cl_name); - if (!$existing_project || ($cl_project_id == $existing_project['id'])) { - // Update project information. - if (ttProjectHelper::update(array( - 'id' => $cl_project_id, - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'users' => $cl_users, - 'tasks' => $cl_tasks))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttProjectHelper::getProjectByName($cl_name)) { - if (ttProjectHelper::insert(array('name' => $cl_name, - 'description' => $cl_description, - 'users' => $cl_users, - 'tasks' => $cl_tasks, - 'status' => ACTIVE))) { - header('Location: projects.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_delete')) { - header("Location: project_delete.php?id=$cl_project_id"); - exit(); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.projectForm.project_name.focus()"'); -$smarty->assign('show_users', count($users) > 0); -$smarty->assign('show_tasks', $show_tasks); -$smarty->assign('title', $i18n->get('title.edit_project')); -$smarty->assign('content_page_name', 'mobile/project_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/projects.php b/mobile/projects.php index 6a5ac572a..ee5d8dc18 100644 --- a/mobile/projects.php +++ b/mobile/projects.php @@ -31,6 +31,11 @@ import('ttTeamHelper'); import('ttGroupHelper'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../projects.php'); +exit(); +// Below is no longer used code. + // Access checks. if (!(ttAccessAllowed('view_own_projects') || ttAccessAllowed('manage_projects'))) { header('Location: access_denied.php'); diff --git a/mobile/task_add.php b/mobile/task_add.php deleted file mode 100644 index db73d1c77..000000000 --- a/mobile/task_add.php +++ /dev/null @@ -1,87 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_description = trim($request->getParameter('description')); - $cl_projects = $request->getParameter('projects'); -} else { - foreach ($projects as $project_item) - $cl_projects[] = $project_item['id']; -} - -$form = new Form('taskForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); -$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.add'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - - if ($err->no()) { - if (!ttTaskHelper::getTaskByName($cl_name)) { - if (ttTaskHelper::insert(array( - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => ACTIVE, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.taskForm.name.focus()"'); -$smarty->assign('title', $i18n->get('title.add_task')); -$smarty->assign('content_page_name', 'mobile/task_add.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/task_delete.php b/mobile/task_delete.php deleted file mode 100644 index dd0dae935..000000000 --- a/mobile/task_delete.php +++ /dev/null @@ -1,78 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_task_id = (int)$request->getParameter('id'); -$task = ttTaskHelper::get($cl_task_id); -if (!$task) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$task_to_delete = $task['name']; - -$form = new Form('taskDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if(ttTaskHelper::get($cl_task_id)) { - if (ttTaskHelper::delete($cl_task_id)) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.db')); - } elseif ($request->getParameter('btn_cancel')) { - header('Location: tasks.php'); - exit(); - } -} // isPost - -$smarty->assign('task_to_delete', $task_to_delete); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.taskDeleteForm.btn_cancel.focus()"'); -$smarty->assign('title', $i18n->get('title.delete_task')); -$smarty->assign('content_page_name', 'mobile/task_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/task_edit.php b/mobile/task_edit.php deleted file mode 100644 index 02a947676..000000000 --- a/mobile/task_edit.php +++ /dev/null @@ -1,128 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -$cl_task_id = (int)$request->getParameter('id'); -$task = ttTaskHelper::get($cl_task_id); -if (!$task) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$projects = ttGroupHelper::getActiveProjects(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_description = trim($request->getParameter('description')); - $cl_status = $request->getParameter('status'); - $cl_projects = $request->getParameter('projects'); -} else { - $cl_name = $task['name']; - $cl_description = $task['description']; - $cl_status = $task['status']; - $assigned_projects = ttTaskHelper::getAssignedProjects($cl_task_id); - foreach ($assigned_projects as $project_item) - $cl_projects[] = $project_item['id']; -} - -$form = new Form('taskForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_task_id)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'textarea','name'=>'description','class'=>'mobile-textarea','value'=>$cl_description)); -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','layout'=>'H','data'=>$projects,'datakeys'=>array('id','name'),'value'=>$cl_projects)); -$form->addInput(array('type'=>'submit','name'=>'btn_save','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_copy','value'=>$i18n->get('button.copy'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.thing_name')); - if (!ttValidString($cl_description, true)) $err->add($i18n->get('error.field'), $i18n->get('label.description')); - - if ($err->no()) { - if ($request->getParameter('btn_save')) { - $existing_task = ttTaskHelper::getTaskByName($cl_name); - if (!$existing_task || ($cl_task_id == $existing_task['id'])) { - // Update task information. - if (ttTaskHelper::update(array( - 'task_id' => $cl_task_id, - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_copy')) { - if (!ttTaskHelper::getTaskByName($cl_name)) { - if (ttTaskHelper::insert(array( - 'name' => $cl_name, - 'description' => $cl_description, - 'status' => $cl_status, - 'projects' => $cl_projects))) { - header('Location: tasks.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.object_exists')); - } - - if ($request->getParameter('btn_delete')) { - header("Location: task_delete.php?id=$cl_task_id"); - exit(); - } - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.edit_task')); -$smarty->assign('content_page_name', 'mobile/task_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/tasks.php b/mobile/tasks.php index 2745df23a..960990166 100644 --- a/mobile/tasks.php +++ b/mobile/tasks.php @@ -30,6 +30,11 @@ import('form.Form'); import('ttGroupHelper'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../tasks.php'); +exit(); +// Below is no longer used code. + // Access checks. if (!(ttAccessAllowed('view_own_tasks') || ttAccessAllowed('manage_tasks'))) { header('Location: access_denied.php'); diff --git a/mobile/time_delete.php b/mobile/time_delete.php deleted file mode 100644 index e80c5c733..000000000 --- a/mobile/time_delete.php +++ /dev/null @@ -1,89 +0,0 @@ -getParameter('id'); -$time_rec = ttTimeHelper::getRecord($cl_id); -if (!$time_rec || $time_rec['approved'] || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { - // Prohibit deleting not ours, approved, assigned to timesheet, or invoiced records. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$trackingMode = $user->getTrackingMode(); -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; - -if ($request->isPost()) { - if ($request->getParameter('delete_button')) { // Delete button pressed. - - // Determine if it's okay to delete the record. - $item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); - - // Determine if the record is uncompleted. - $uncompleted = ($time_rec['duration'] == '0:00'); - - if ($user->isDateLocked($item_date) && !$uncompleted) - $err->add($i18n->get('error.range_locked')); - - if ($err->no()) { - // Delete the record. - if (ttTimeHelper::delete($cl_id)) { - header('Location: time.php'); - exit(); - } else { - $err->add($i18n->get('error.db')); - } - } - } - if ($request->getParameter('cancel_button')) { // Cancel button pressed. - header('Location: time.php'); - exit(); - } -} // isPost - -$form = new Form('timeRecordForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); -$form->addInput(array('type'=>'submit','name'=>'delete_button','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'cancel_button','value'=>$i18n->get('button.cancel'))); -$smarty->assign('time_rec', $time_rec); -$smarty->assign('show_project', $showProject); -$smarty->assign('forms', array($form->getName() => $form->toArray())); -$smarty->assign('title', $i18n->get('title.delete_time_record')); -$smarty->assign('content_page_name', 'mobile/time_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/time_edit.php b/mobile/time_edit.php deleted file mode 100644 index fb3a918dc..000000000 --- a/mobile/time_edit.php +++ /dev/null @@ -1,494 +0,0 @@ -getParameter('id'); -$time_rec = ttTimeHelper::getRecord($cl_id); -if (!$time_rec || $time_rec['approved'] || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { - // Prohibit editing not ours, approved, assigned to timesheet, or invoiced records. - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$user_id = $user->getUser(); -$config = new ttConfigHelper($user->getConfig()); - -$showClient = $user->isPluginEnabled('cl'); -$showBillable = $user->isPluginEnabled('iv'); -$showPaidStatus = $user->isPluginEnabled('ps') && $user->can('manage_invoices'); -$trackingMode = $user->getTrackingMode(); -$showProject = MODE_PROJECTS == $trackingMode || MODE_PROJECTS_AND_TASKS == $trackingMode; -$showTask = MODE_PROJECTS_AND_TASKS == $trackingMode; -if ($showTask) $taskRequired = $config->getDefinedValue('task_required'); -$recordType = $user->getRecordType(); -$showStart = TYPE_START_FINISH == $recordType || TYPE_ALL == $recordType; -$showDuration = TYPE_DURATION == $recordType || TYPE_ALL == $recordType; - -// Use custom fields plugin if it is enabled. -if ($user->isPluginEnabled('cf')) { - require_once('../plugins/CustomFields.class.php'); - $custom_fields = new CustomFields(); - $smarty->assign('custom_fields', $custom_fields); -} - -$item_date = new DateAndTime(DB_DATEFORMAT, $time_rec['date']); -$confirm_save = $user->getConfigOption('confirm_save'); - -// Initialize variables. -$cl_start = $cl_finish = $cl_duration = $cl_date = $cl_note = $cl_project = $cl_task = $cl_billable = null; -if ($request->isPost()) { - $cl_start = trim($request->getParameter('start')); - $cl_finish = trim($request->getParameter('finish')); - $cl_duration = trim($request->getParameter('duration')); - $cl_date = $request->getParameter('date'); - $cl_note = trim($request->getParameter('note')); - // If we have user custom fields - collect input. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => trim($request->getParameter($control_name))); - } - } - $cl_client = $request->getParameter('client'); - $cl_project = $request->getParameter('project'); - $cl_task = $request->getParameter('task'); - $cl_billable = 1; - if ($showBillable) - $cl_billable = $request->getParameter('billable'); - if ($showPaidStatus) - $cl_paid = $request->getParameter('paid'); -} else { - $cl_client = $time_rec['client_id']; - $cl_project = $time_rec['project_id']; - $cl_task = $time_rec['task_id']; - $cl_start = $time_rec['start']; - $cl_finish = $time_rec['finish']; - $cl_duration = $time_rec['duration']; - $cl_date = $item_date->toString($user->getDateFormat()); - $cl_note = $time_rec['comment']; - - // If we have time custom fields - collect values from database. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $control_name = 'time_field_'.$timeField['id']; - $timeCustomFields[$timeField['id']] = array('field_id' => $timeField['id'], - 'control_name' => $control_name, - 'label' => $timeField['label'], - 'type' => $timeField['type'], - 'required' => $timeField['required'], - 'value' => $custom_fields->getTimeFieldValue($cl_id, $timeField['id'], $timeField['type'])); - } - } - - $cl_billable = $time_rec['billable']; - $cl_paid = $time_rec['paid']; - - // Add an info message to the form if we are editing an uncompleted record. - if (strlen($cl_start) > 0 && $cl_start == $cl_finish && $cl_duration == '0:00') { - $cl_finish = ''; - $cl_duration = ''; - $msg->add($i18n->get('form.time_edit.uncompleted')); - } -} - -// Initialize elements of 'timeRecordForm'. -$form = new Form('timeRecordForm'); - -// Dropdown for clients in MODE_TIME. Use all active clients. -// Note: for other tracking modes the control is added further below. -if (MODE_TIME == $trackingMode && $showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -// Billable checkbox. -if ($showBillable) - $form->addInput(array('type'=>'checkbox','name'=>'billable','value'=>$cl_billable)); - -// Paid status checkbox. -if ($showPaidStatus) - $form->addInput(array('type'=>'checkbox','name'=>'paid','value'=>$cl_paid)); - -// If we have time custom fields - add controls for them. -if ($custom_fields && $custom_fields->timeFields) { - foreach ($custom_fields->timeFields as $timeField) { - $field_name = 'time_field_'.$timeField['id']; - if ($timeField['type'] == CustomFields::TYPE_TEXT) { - $form->addInput(array('type'=>'text','name'=>$field_name,'value'=>$timeCustomFields[$timeField['id']]['value'])); - } elseif ($timeField['type'] == CustomFields::TYPE_DROPDOWN) { - $form->addInput(array('type'=>'combobox','name'=>$field_name, - 'style'=>'width: 250px;', - 'data'=>CustomFields::getOptions($timeField['id']), - 'value'=>$timeCustomFields[$timeField['id']]['value'], - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } - } -} - -// If we show project dropdown, add controls for project and client. -if ($showProject) { - // Dropdown for projects assigned to user. - $options['include_templates'] = $user->isPluginEnabled('tp') && $config->getDefinedValue('bind_templates_with_projects'); - $project_list = $user->getAssignedProjects($options); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillTaskDropdown(this.value);fillTemplateDropdown(this.value);prepopulateNote();', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($showClient) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - if (is_array($projects_assigned_to_client) && is_array($projects_assigned_to_user)) - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} - -// Task dropdown. -if ($showTask) { - $task_list = ttGroupHelper::getActiveTasks(); - $form->addInput(array('type'=>'combobox', - 'name'=>'task', - 'style'=>'width: 250px;', - 'value'=>$cl_task, - 'data'=>$task_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); -} - -// Start and finish controls. -if ($showStart) { - $form->addInput(array('type'=>'text','name'=>'start','value'=>$cl_start,'onchange'=>"formDisable('start');")); - $form->addInput(array('type'=>'text','name'=>'finish','value'=>$cl_finish,'onchange'=>"formDisable('finish');")); - if ($user->punch_mode && !$user->canOverridePunchMode()) { - // Make the start and finish fields read-only. - $form->getElement('start')->setEnabled(false); - $form->getElement('finish')->setEnabled(false); - } -} - -// Duration control. -if ($showDuration) - $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); - -// Date field. -$form->addInput(array('type'=>'datefield','name'=>'date','maxlength'=>'20','value'=>$cl_date)); - -// If we have templates, add a dropdown to select one. -if ($user->isPluginEnabled('tp')){ - $template_list = ttGroupHelper::getActiveTemplates(); - if (count($template_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillNote(this.value);', - 'name'=>'template', - 'style'=>'width: 250px;', - 'data'=>$template_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $smarty->assign('template_dropdown', 1); - $smarty->assign('bind_templates_with_projects', $config->getDefinedValue('bind_templates_with_projects')); - $smarty->assign('prepopulate_note', $config->getDefinedValue('prepopulate_note')); - $smarty->assign('template_list', $template_list); - } -} - -// Note control. -$form->addInput(array('type'=>'textarea','name'=>'note','class'=>'mobile-textarea','value'=>$cl_note)); - -// Hidden control for record id. -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_id)); - -// A hidden control for today's date from user's browser. -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_save click. - -// Copy button. -$on_click_action = 'browser_today.value=get_date();'; -$form->addInput(array('type'=>'submit','name'=>'btn_copy','onclick'=>$on_click_action,'value'=>$i18n->get('button.copy'))); - -// Save button. -if ($confirm_save) $on_click_action .= 'return(confirmSave());'; -$form->addInput(array('type'=>'submit','name'=>'btn_save','onclick'=>$on_click_action,'value'=>$i18n->get('button.save'))); - -// Delete button. -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - - // Validate user input. - if ($showClient && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - // Validate input in time custom fields. - if ($custom_fields && $custom_fields->timeFields) { - foreach ($timeCustomFields as $timeField) { - // Validation is the same for text and dropdown fields. - if (!ttValidString($timeField['value'], !$timeField['required'])) $err->add($i18n->get('error.field'), htmlspecialchars($timeField['label'])); - } - } - if ($showProject) { - if (!$cl_project) $err->add($i18n->get('error.project')); - } - if ($showTask && $task_required) { - if (!$cl_task) $err->add($i18n->get('error.task')); - } - if (!$cl_duration) { - if ('0' == $cl_duration) - $err->add($i18n->get('error.field'), $i18n->get('label.duration')); - elseif ($cl_start || $cl_finish) { - if (!ttTimeHelper::isValidTime($cl_start)) - $err->add($i18n->get('error.field'), $i18n->get('label.start')); - if ($cl_finish) { - if (!ttTimeHelper::isValidTime($cl_finish)) - $err->add($i18n->get('error.field'), $i18n->get('label.finish')); - if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) - $err->add($i18n->get('error.interval'), $i18n->get('label.finish'), $i18n->get('label.start')); - } - } else { - if ($showStart) { - $err->add($i18n->get('error.empty'), $i18n->get('label.start')); - $err->add($i18n->get('error.empty'), $i18n->get('label.finish')); - } - if ($showDuration) - $err->add($i18n->get('error.empty'), $i18n->get('label.duration')); - } - } else { - if (false === ttTimeHelper::postedDurationToMinutes($cl_duration)) - $err->add($i18n->get('error.field'), $i18n->get('label.duration')); - } - if (!ttValidDate($cl_date)) $err->add($i18n->get('error.field'), $i18n->get('label.date')); - if (!ttValidString($cl_note, true)) $err->add($i18n->get('error.field'), $i18n->get('label.note')); - if ($user->isPluginEnabled('tp') && !ttValidTemplateText($cl_note)) { - $err->add($i18n->get('error.field'), $i18n->get('label.note')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating user input. - - // This is a new date for the time record. - $new_date = new DateAndTime($user->getDateFormat(), $cl_date); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($new_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - - // Save record. - if ($request->getParameter('btn_save')) { - // We need to: - // 1) Prohibit saving locked entries in any form. - // 2) Prohibit saving completed unlocked entries into locked range. - // 3) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. - - // Now, step by step. - if ($err->no()) { - // 1) Prohibit saving locked entries in any form. - if ($user->isDateLocked($item_date)) - $err->add($i18n->get('error.range_locked')); - - // 2) Prohibit saving completed unlocked entries into locked range. - if ($err->no() && $user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // 3) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. - $uncompleted = ($cl_finish == '' && $cl_duration == ''); - if ($uncompleted) { - $not_completed_rec = ttTimeHelper::getUncompleted($user_id); - if ($not_completed_rec && ($time_rec['id'] <> $not_completed_rec['id'])) { - // We have another not completed record. - $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); - } - } - } - - // Prohibit creating an overlapping record. - if ($err->no()) { - if (ttTimeHelper::overlaps($user_id, $new_date->toString(DB_DATEFORMAT), $cl_start, $cl_finish, $cl_id)) - $err->add($i18n->get('error.overlap')); - } - - // Now, an update. - if ($err->no()) { - $res = ttTimeHelper::update(array( - 'id'=>$cl_id, - 'date'=>$new_date->toString(DB_DATEFORMAT), - 'client'=>$cl_client, - 'project'=>$cl_project, - 'task'=>$cl_task, - 'start'=>$cl_start, - 'finish'=>$cl_finish, - 'duration'=>$cl_duration, - 'note'=>$cl_note, - 'billable'=>$cl_billable, - 'paid'=>$cl_paid)); - - // Update time custom fields if we have them. - if ($res && $custom_fields && $custom_fields->timeFields) { - $res = $custom_fields->updateTimeFields($cl_id, $timeCustomFields); - } - if ($res) - { - header('Location: time.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } - } - } - - // Copy record. - if ($request->getParameter('btn_copy')) { - // We need to: - // 1) Prohibit saving into locked range. - // 2) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. - - // Now, step by step. - if ($err->no()) { - // 1) Prohibit saving into locked range. - if ($user->isDateLocked($new_date)) - $err->add($i18n->get('error.range_locked')); - - // 2) Prohibit saving uncompleted unlocked entries when another uncompleted entry exists. - $uncompleted = ($cl_finish == '' && $cl_duration == ''); - if ($uncompleted) { - $not_completed_rec = ttTimeHelper::getUncompleted($user_id); - if ($not_completed_rec) { - // We have another not completed record. - $err->add($i18n->get('error.uncompleted_exists')." ".$i18n->get('error.goto_uncompleted').""); - } - } - } - - // Prohibit creating an overlapping record. - if ($err->no()) { - if (ttTimeHelper::overlaps($user_id, $new_date->toString(DB_DATEFORMAT), $cl_start, $cl_finish)) - $err->add($i18n->get('error.overlap')); - } - - // Now, a new insert. - if ($err->no()) { - - $id = ttTimeHelper::insert(array( - 'date'=>$new_date->toString(DB_DATEFORMAT), - 'client'=>$cl_client, - 'project'=>$cl_project, - 'task'=>$cl_task, - 'start'=>$cl_start, - 'finish'=>$cl_finish, - 'duration'=>$cl_duration, - 'note'=>$cl_note, - 'billable'=>$cl_billable, - 'paid'=>$cl_paid)); - - // Insert time custom fields if we have them. - $res = true; - if ($id && $custom_fields && $custom_fields->timeFields) { - $res = $custom_fields->insertTimeFields($id, $timeCustomFields); - } - if ($id && $res) { - header('Location: time.php?date='.$new_date->toString(DB_DATEFORMAT)); - exit(); - } - $err->add($i18n->get('error.db')); - } - } - - if ($request->getParameter('btn_delete')) { - header("Location: time_delete.php?id=$cl_id"); - exit(); - } -} // isPost - -if ($confirm_save) { - $smarty->assign('confirm_save', true); - $smarty->assign('entry_date', $cl_date); -} -$smarty->assign('show_client', $showClient); -$smarty->assign('show_billable', $showBillable);+ -$smarty->assign('show_paid_status', $showPaidStatus); -$smarty->assign('show_project', $showProject); -$smarty->assign('show_task', $showTask); -$smarty->assign('task_required', $taskRequired); -$smarty->assign('show_start', $showStart); -$smarty->assign('show_duration', $showDuration); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('task_list', $task_list); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="fillDropdowns()"'); -$smarty->assign('title', $i18n->get('title.edit_time_record')); -$smarty->assign('content_page_name', 'mobile/time_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/user_add.php b/mobile/user_add.php deleted file mode 100644 index ed017de8a..000000000 --- a/mobile/user_add.php +++ /dev/null @@ -1,186 +0,0 @@ -isPluginEnabled('mq'); -if ($user->isPluginEnabled('cl')) - $clients = ttGroupHelper::getActiveClients(); - -$assigned_projects = array(); -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_login = trim($request->getParameter('login')); - if (!$auth->isPasswordExternal()) { - $cl_password1 = $request->getParameter('pas1'); - $cl_password2 = $request->getParameter('pas2'); - } - $cl_email = trim($request->getParameter('email')); - $cl_role_id = $request->getParameter('role'); - $cl_client_id = $request->getParameter('client'); - $cl_rate = $request->getParameter('rate'); - $cl_quota_percent = $request->getParameter('quota_percent'); - $cl_projects = $request->getParameter('projects'); - if (is_array($cl_projects)) { - foreach ($cl_projects as $p) { - if (ttValidFloat($request->getParameter('rate_'.$p), true)) { - $project_with_rate = array(); - $project_with_rate['id'] = $p; - $project_with_rate['rate'] = $request->getParameter('rate_'.$p); - $assigned_projects[] = $project_with_rate; - } else - $err->add($i18n->get('error.field'), 'rate_'.$p); - } - } -} - -$form = new Form('userForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','value'=>$cl_login)); -if (!$auth->isPasswordExternal()) { - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas1','value'=>$cl_password1)); - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas2','value'=>$cl_password2)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email)); - -$active_roles = ttTeamHelper::getActiveRolesForUser(); -$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles,'datakeys'=>array('id', 'name'))); -if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); - -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -if ($show_quota) - $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); - -$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); -if ($show_projects) { - $projects = ttGroupHelper::getActiveProjects(); - if (count($projects) == 0) $show_projects = false; -} - -// Define classes for the projects table. -class NameCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200,'valign'=>'top')); - $this->setValue(''); - return $this->toString(); - } -} -class RateCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $assigned_projects; - $field = new FloatField('rate_'.$table->getValueAtName($row, 'id')); - $field->setFormName($table->getFormName()); - $field->setSize(5); - $field->setFormat('.2'); - foreach ($assigned_projects as $p) { - if ($p['id'] == $table->getValueAtName($row,'id')) $field->setValue($p['rate']); - } - $this->setValue($field->getHtml()); - return $this->toString(); - } -} -// Create projects table. -$table = new Table('projects'); -$table->setIAScript('setDefaultRate'); -$table->setTableOptions(array('width'=>'250','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); -$table->setData($projects); -$table->setKeyField('id'); -$table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); -$form->addInputElement($table); - -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.submit'))); - -if ($request->isPost()) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); - if (!$auth->isPasswordExternal()) { - if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); - } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); - if (!ttUserHelper::canAdd()) $err->add($i18n->get('error.user_count')); - - if ($err->no()) { - if (!ttUserHelper::getUserByLogin($cl_login)) { - $fields = array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'rate' => $cl_rate, - 'quota_percent' => $cl_quota_percent, - 'group_id' => $user->getGroup(), - 'org_id' => $user->org_id, - 'role_id' => $cl_role_id, - 'client_id' => $cl_client_id, - 'projects' => $assigned_projects, - 'email' => $cl_email); - if (ttUserHelper::insert($fields)) { - header('Location: users.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.user_exists')); - } -} // isPost - -$smarty->assign('auth_external', $auth->isPasswordExternal()); -$smarty->assign('active_roles', $active_roles); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('show_quota', $show_quota); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('title', $i18n->get('title.add_user')); -$smarty->assign('content_page_name', 'mobile/user_add.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/user_delete.php b/mobile/user_delete.php deleted file mode 100644 index 132f73022..000000000 --- a/mobile/user_delete.php +++ /dev/null @@ -1,87 +0,0 @@ -getParameter('id'); -$user_details = $user->getUserDetails($user_id); -if (!$user_details) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$smarty->assign('user_to_delete', $user_details['name']." (".$user_details['login'].")"); - -// Create confirmation form. -$form = new Form('userDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); -$form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_delete')) { - if ($user->markUserDeleted($user_id)) { - // If we deleted the "on behalf" user reset its info in session. - if ($user_id == $user->behalf_id) { - unset($_SESSION['behalf_id']); - unset($_SESSION['behalf_name']); - } - // If we deleted our own account, do housekeeping and logout. - if ($user->id == $user_id) { - // Remove LOGIN_COOKIE_NAME cookie that stores login name. - unset($_COOKIE[LOGIN_COOKIE_NAME]); - setcookie(LOGIN_COOKIE_NAME, NULL, -1); - - $auth->doLogout(); - header('Location: login.php'); - } else { - header('Location: users.php'); - } - exit(); - } else { - $err->add($i18n->get('error.db')); - } - } - if ($request->getParameter('btn_cancel')) { - header('Location: users.php'); - exit(); - } -} // isPost - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('title', $i18n->get('title.delete_user')); -$smarty->assign('content_page_name', 'mobile/user_delete.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/user_edit.php b/mobile/user_edit.php deleted file mode 100644 index 58de5e8ab..000000000 --- a/mobile/user_edit.php +++ /dev/null @@ -1,245 +0,0 @@ -getParameter('id'); -$user_details = $user->getUserDetails($user_id); -if (!$user_details) { - header('Location: access_denied.php'); - exit(); -} -// End of access checks. - -$show_quota = $user->isPluginEnabled('mq'); -if ($user->isPluginEnabled('cl')) - $clients = ttGroupHelper::getActiveClients(); - -$show_projects = MODE_PROJECTS == $user->getTrackingMode() || MODE_PROJECTS_AND_TASKS == $user->getTrackingMode(); -if ($show_projects) { - $projects = ttGroupHelper::getActiveProjects(); - if (count($projects) == 0) $show_projects = false; -} -$assigned_projects = array(); - -if ($request->isPost()) { - $cl_name = trim($request->getParameter('name')); - $cl_login = trim($request->getParameter('login')); - if (!$auth->isPasswordExternal()) { - $cl_password1 = $request->getParameter('pas1'); - $cl_password2 = $request->getParameter('pas2'); - } - $cl_email = trim($request->getParameter('email')); - $cl_role_id = $request->getParameter('role'); - $cl_client_id = $request->getParameter('client'); - $cl_status = $request->getParameter('status'); - $cl_rate = $request->getParameter('rate'); - $cl_quota_percent = $request->getParameter('quota_percent'); - $cl_projects = $request->getParameter('projects'); - if (is_array($cl_projects)) { - foreach ($cl_projects as $p) { - if (ttValidFloat($request->getParameter('rate_'.$p), true)) { - $project_with_rate = array(); - $project_with_rate['id'] = $p; - $project_with_rate['rate'] = $request->getParameter('rate_'.$p); - $assigned_projects[] = $project_with_rate; - } else - $err->add($i18n->get('error.field'), 'rate_'.$p); - } - } -} else { - $cl_name = $user_details['name']; - $cl_login = $user_details['login']; - $cl_email = $user_details['email']; - $cl_rate = str_replace('.', $user->getDecimalMark(), $user_details['rate']); - $cl_quota_percent = str_replace('.', $user->getDecimalMark(), $user_details['quota_percent']); - $cl_role_id = $user_details['role_id']; - $cl_client_id = $user_details['client_id']; - $cl_status = $user_details['status']; - $cl_projects = array(); - $assigned_projects = ttProjectHelper::getAssignedProjects($user_id); - foreach($assigned_projects as $p) { - $cl_projects[] = $p['id']; - } -} - -$form = new Form('userForm'); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','value'=>$cl_name)); -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'login','value'=>$cl_login)); -if (!$auth->isPasswordExternal()) { - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas1','value'=>$cl_password1)); - $form->addInput(array('type'=>'password','maxlength'=>'30','name'=>'pas2','value'=>$cl_password2)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'email','value'=>$cl_email)); - -$active_roles = ttTeamHelper::getActiveRolesForUser(); -$form->addInput(array('type'=>'combobox','onchange'=>'handleClientControl()','name'=>'role','value'=>$cl_role_id,'data'=>$active_roles,'datakeys'=>array('id', 'name'))); -if ($user->isPluginEnabled('cl')) - $form->addInput(array('type'=>'combobox','name'=>'client','value'=>$cl_client_id,'data'=>$clients,'datakeys'=>array('id', 'name'),'empty'=>array(''=>$i18n->get('dropdown.select')))); - -$form->addInput(array('type'=>'combobox','name'=>'status','value'=>$cl_status, - 'data'=>array(ACTIVE=>$i18n->get('dropdown.status_active'),INACTIVE=>$i18n->get('dropdown.status_inactive')))); -$form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'rate','format'=>'.2','value'=>$cl_rate)); -if ($show_quota) - $form->addInput(array('type'=>'floatfield','maxlength'=>'10','name'=>'quota_percent','format'=>'.2','value'=>$cl_quota_percent)); - -// Define classes for the projects table. -class NameCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - $this->setOptions(array('width'=>200,'valign'=>'top')); - $this->setValue(''); - return $this->toString(); - } -} -class RateCellRenderer extends DefaultCellRenderer { - function render(&$table, $value, $row, $column, $selected = false) { - global $assigned_projects; - $field = new FloatField('rate_'.$table->getValueAtName($row,'id')); - $field->setFormName($table->getFormName()); - $field->setSize(5); - $field->setFormat('.2'); - foreach ($assigned_projects as $p) { - if ($p['id'] == $table->getValueAtName($row,'id')) $field->setValue($p['rate']); - } - $this->setValue($field->getHtml()); - return $this->toString(); - } -} -// Create projects table. -$table = new Table('projects'); -$table->setIAScript('setRate'); -$table->setTableOptions(array('width'=>'250','cellspacing'=>'1','cellpadding'=>'3','border'=>'0')); -$table->setRowOptions(array('valign'=>'top','class'=>'tableHeader')); -$table->setData($projects); -$table->setKeyField('id'); -$table->setValue($cl_projects); -$table->addColumn(new TableColumn('name', $i18n->get('label.project'), new NameCellRenderer())); -$table->addColumn(new TableColumn('p_rate', $i18n->get('form.users.rate'), new RateCellRenderer())); -$form->addInputElement($table); - -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$user_id)); -$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->get('button.save'))); -$form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); - -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Validate user input. - if (!ttValidString($cl_name)) $err->add($i18n->get('error.field'), $i18n->get('label.person_name')); - if (!ttValidString($cl_login)) $err->add($i18n->get('error.field'), $i18n->get('label.login')); - if (!$auth->isPasswordExternal() && ($cl_password1 || $cl_password2)) { - if (!ttValidString($cl_password1)) $err->add($i18n->get('error.field'), $i18n->get('label.password')); - if (!ttValidString($cl_password2)) $err->add($i18n->get('error.field'), $i18n->get('label.confirm_password')); - if ($cl_password1 !== $cl_password2) - $err->add($i18n->get('error.not_equal'), $i18n->get('label.password'), $i18n->get('label.confirm_password')); - } - if (!ttValidEmail($cl_email, true)) $err->add($i18n->get('error.field'), $i18n->get('label.email')); - if (!ttValidFloat($cl_rate, true)) $err->add($i18n->get('error.field'), $i18n->get('form.users.default_rate')); - if (!ttValidFloat($cl_quota_percent, true)) $err->add($i18n->get('error.field'), $i18n->get('label.quota')); - - if ($err->no()) { - $existing_user = ttUserHelper::getUserByLogin($cl_login); - if (!$existing_user || ($user_id == $existing_user['id'])) { - - $fields = array( - 'name' => $cl_name, - 'login' => $cl_login, - 'password' => $cl_password1, - 'email' => $cl_email, - 'status' => $cl_status, - 'rate' => $cl_rate, - 'quota_percent' => $cl_quota_percent, - 'projects' => $assigned_projects); - if (in_array('manage_users', $user->rights)) { - $fields['role_id'] = $cl_role_id; - $fields['client_id'] = $cl_client_id; - } - - if (ttUserHelper::update($user_id, $fields)) { - - // If our own login changed, set new one in cookie to remember it. - if (($user_id == $user->id) && ($user->login != $cl_login)) { - setcookie(LOGIN_COOKIE_NAME, $cl_login, time() + COOKIE_EXPIRE, '/'); - } - - // In case the name of the "on behalf" user has changed - set it in session. - if (($user->behalf_id == $user_id) && ($user->behalf_name != $cl_name)) { - $_SESSION['behalf_name'] = $cl_name; - } - - // If we deactivated our own account, do housekeeping and logout. - if ($user->id == $user_id && !is_null($cl_status) && $cl_status == INACTIVE) { - // Remove LOGIN_COOKIE_NAME cookie that stores login name. - unset($_COOKIE[LOGIN_COOKIE_NAME]); - setcookie(LOGIN_COOKIE_NAME, NULL, -1); - - $auth->doLogout(); - header('Location: login.php'); - exit(); - } - - header('Location: users.php'); - exit(); - - } else - $err->add($i18n->get('error.db')); - } else - $err->add($i18n->get('error.user_exists')); - } - } - - if ($request->getParameter('btn_delete')) { - header("Location: user_delete.php?id=$user_id"); - exit(); - } -} // isPost - -$rates = ttProjectHelper::getRates($user_id); -$smarty->assign('rates', $rates); - -$smarty->assign('auth_external', $auth->isPasswordExternal()); -$smarty->assign('active_roles', $active_roles); -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('onload', 'onLoad="document.userForm.name.focus();handleClientControl();"'); -$smarty->assign('show_quota', $show_quota); -$smarty->assign('show_projects', $show_projects); -$smarty->assign('user_id', $user_id); -$smarty->assign('title', $i18n->get('title.edit_user')); -$smarty->assign('content_page_name', 'mobile/user_edit.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/users.php b/mobile/users.php index d51cafcab..0e52072fb 100644 --- a/mobile/users.php +++ b/mobile/users.php @@ -32,6 +32,11 @@ import('ttGroupHelper'); import('ttTimeHelper'); +// Mobile pages are no longer separate. Redirect to main page. +header('Location: ../users.php'); +exit(); +// Below is no longer used code. + // Access checks. if (!(ttAccessAllowed('view_users') || ttAccessAllowed('manage_users'))) { header('Location: access_denied.php'); From 5ba5e875dcf313422b5ab1ad90fc112218deea40 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 7 Dec 2020 18:13:07 +0000 Subject: [PATCH 219/652] Cosmetic style improvement. --- default.css | 2 ++ initialize.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/default.css b/default.css index 595967e64..95f56094b 100644 --- a/default.css +++ b/default.css @@ -424,6 +424,8 @@ div.section-header { text-align: center; margin-left: auto; margin-right: auto; + margin-top: .5rem; + margin-bottom: .5rem; } /* div for a group of items in site map */ diff --git a/initialize.php b/initialize.php index 265d13aea..47f069ba8 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5407"); +define("APP_VERSION", "1.19.23.5408"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 1a4d9c3418ce261883057554887f2b36f0c5425b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 8 Dec 2020 13:00:38 +0000 Subject: [PATCH 220/652] Improved mobile presentation of vertically stacked checkboxes. --- WEB-INF/templates/client_add2.tpl | 2 +- WEB-INF/templates/client_edit2.tpl | 2 +- WEB-INF/templates/project_add2.tpl | 4 ++-- WEB-INF/templates/project_edit2.tpl | 4 ++-- WEB-INF/templates/task_add2.tpl | 2 +- WEB-INF/templates/task_edit2.tpl | 2 +- default.css | 6 ++++++ initialize.php | 2 +- 8 files changed, 15 insertions(+), 9 deletions(-) diff --git a/WEB-INF/templates/client_add2.tpl b/WEB-INF/templates/client_add2.tpl index 2704a133c..ac7a63efc 100644 --- a/WEB-INF/templates/client_add2.tpl +++ b/WEB-INF/templates/client_add2.tpl @@ -28,7 +28,7 @@ License: See license.txt *} {$i18n.label.projects}: {$i18n.label.projects}: - {$forms.clientForm.projects.control} + {$forms.clientForm.projects.control}
{/if} diff --git a/WEB-INF/templates/client_edit2.tpl b/WEB-INF/templates/client_edit2.tpl index 67b79ecdf..39c965ae0 100644 --- a/WEB-INF/templates/client_edit2.tpl +++ b/WEB-INF/templates/client_edit2.tpl @@ -34,7 +34,7 @@ License: See license.txt *} {$i18n.label.projects}: {$i18n.label.projects}: - {$forms.clientForm.projects.control} + {$forms.clientForm.projects.control}
{/if} diff --git a/WEB-INF/templates/project_add2.tpl b/WEB-INF/templates/project_add2.tpl index cd900cf36..8cc43fcaa 100644 --- a/WEB-INF/templates/project_add2.tpl +++ b/WEB-INF/templates/project_add2.tpl @@ -28,7 +28,7 @@ License: See license.txt *} {$i18n.label.users}: {$i18n.label.users}: - {$forms.projectForm.users.control} + {$forms.projectForm.users.control}
{/if} @@ -37,7 +37,7 @@ License: See license.txt *} {$i18n.label.tasks}: {$i18n.label.tasks}: - {$forms.projectForm.tasks.control} + {$forms.projectForm.tasks.control}
{/if} diff --git a/WEB-INF/templates/project_edit2.tpl b/WEB-INF/templates/project_edit2.tpl index f7b23a9ac..3ecc85a84 100644 --- a/WEB-INF/templates/project_edit2.tpl +++ b/WEB-INF/templates/project_edit2.tpl @@ -26,7 +26,7 @@ License: See license.txt *} {$i18n.label.users}: {$i18n.label.users}: - {$forms.projectForm.users.control} + {$forms.projectForm.users.control}
{/if} @@ -35,7 +35,7 @@ License: See license.txt *} {$i18n.label.tasks}: {$i18n.label.tasks}: - {$forms.projectForm.tasks.control} + {$forms.projectForm.tasks.control}
{/if} diff --git a/WEB-INF/templates/task_add2.tpl b/WEB-INF/templates/task_add2.tpl index 1b1c4e42e..d933160af 100644 --- a/WEB-INF/templates/task_add2.tpl +++ b/WEB-INF/templates/task_add2.tpl @@ -20,7 +20,7 @@ License: See license.txt *} {$i18n.label.projects}: {$i18n.label.projects}: - {$forms.taskForm.projects.control} + {$forms.taskForm.projects.control}
{/if} diff --git a/WEB-INF/templates/task_edit2.tpl b/WEB-INF/templates/task_edit2.tpl index 9292ad151..c6e433b73 100644 --- a/WEB-INF/templates/task_edit2.tpl +++ b/WEB-INF/templates/task_edit2.tpl @@ -26,7 +26,7 @@ License: See license.txt *} {$i18n.label.projects}: {$i18n.label.projects}: - {$forms.taskForm.projects.control} + {$forms.taskForm.projects.control}
{/if} diff --git a/default.css b/default.css index 95f56094b..377197f28 100644 --- a/default.css +++ b/default.css @@ -233,6 +233,12 @@ div.record-list { text-align: left; } +/* a table cell containing a set ov vertically stacked checkboxes */ +.td-with-checkboxes { + text-align: left; + width: 300px; +} + /* div containing how to contribute message */ div.contribute-msg { text-align: center; diff --git a/initialize.php b/initialize.php index 47f069ba8..6ccd4533e 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5408"); +define("APP_VERSION", "1.19.23.5409"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 7e9111012d54e0feae92598b508f99cb035167d0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Wed, 20 Jan 2021 17:26:27 +0000 Subject: [PATCH 221/652] Dutch translation improved. --- WEB-INF/resources/nl.lang.php | 12 +++--------- initialize.php | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/WEB-INF/resources/nl.lang.php b/WEB-INF/resources/nl.lang.php index 6d51082c7..70750349d 100644 --- a/WEB-INF/resources/nl.lang.php +++ b/WEB-INF/resources/nl.lang.php @@ -390,16 +390,12 @@ // Login form. See example at https://timetracker.anuko.com/login.php. 'form.login.forgot_password' => 'Wachtwoord vergeten?', - // TODO: re-translate form.login.about as it has changed. - // 'form.login.about' => 'Anuko Time Tracker is an open source time tracking system.', -'form.login.about' => 'Anuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem.', +'form.login.about' => 'Anuko Time Tracker is een open source tijdregistratiesysteem.', // Resetting Password form. See example at https://timetracker.anuko.com/password_reset.php. 'form.reset_password.message' => 'Het verzoek om het wachtwoord te herstellen is verzonden per email.', 'form.reset_password.email_subject' => 'Anuko Time Tracker wachtwoord herstel verzoek', -// TODO: retranslate form.reset_password.email_body as the string has changed. -// 'form.reset_password.email_body' => "Dear User,\n\nSomeone from IP %s requested your Anuko Time Tracker password reset. Please visit this link if you want to reset your password.\n\n%s\n\nAnuko Time Tracker is an open source time tracking system. Visit https://www.anuko.com for more information.\n\n", -'form.reset_password.email_body' => "Geachte medewerker,\n\nIemand, met IP adres %s, heeft verzocht uw wachtwoord in Anuko Time Tracker te herstellen. Klik op deze link als u uw wachtwoord wil wijzigen.\n\n%s\n\nAnuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek https://www.anuko.com voor meer informatie.\n\n", +'form.reset_password.email_body' => "Beste gebruiker,\n\nIemand, met IP adres %s, heeft verzocht uw wachtwoord in Anuko Time Tracker te herstellen. Klik op deze link als u uw wachtwoord wil wijzigen.\n\n%s\n\nAnuko Time Tracker is een open source tijdregistratiesysteem. Bezoek https://www.anuko.com voor meer informatie.\n\n", // Changing Password form. See example at https://timetracker.anuko.com/password_change.php?ref=1. 'form.change_password.tip' => 'Voer het nieuwe wachtwoord in en klik op Bewaren.', @@ -546,9 +542,7 @@ // Mail form. See example at https://timetracker.anuko.com/report_send.php when emailing a report. 'form.mail.to' => 'Aan', 'form.mail.report_subject' => 'Time Tracker rapport', -// TODO: retranslate form.mail.footer as the English string has changed. -// 'form.mail.footer' => 'Anuko Time Tracker is an open source
time tracking system. Visit www.anuko.com for more information.', -'form.mail.footer' => 'Anuko Time Tracker is een eenvoudig en gemakkelijk te gebruiken open source tijdregistratiesysteem. Bezoek www.anuko.com voor meer informatie.', +'form.mail.footer' => 'Anuko Time Tracker is een open source tijdregistratiesysteem. Bezoek www.anuko.com voor meer informatie.', 'form.mail.report_sent' => 'Rapport is verzonden.', 'form.mail.invoice_sent' => 'Factuur is verzonden.', diff --git a/initialize.php b/initialize.php index 6ccd4533e..f955479f7 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5409"); +define("APP_VERSION", "1.19.23.5410"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 13ad968d9729dbff50acdeb652bba5e298633c0e Mon Sep 17 00:00:00 2001 From: Josh Bowers Date: Wed, 27 Jan 2021 07:06:47 -0800 Subject: [PATCH 222/652] extra '+' character and end of line causing error (#105) PHP Fatal error: Uncaught TypeError: Unsupported operand types: Smarty * int in ./time_edit.php:453 --- time_edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/time_edit.php b/time_edit.php index 89988409b..4065bf08f 100644 --- a/time_edit.php +++ b/time_edit.php @@ -449,7 +449,7 @@ $smarty->assign('entry_date', $cl_date); } $smarty->assign('show_client', $showClient); -$smarty->assign('show_billable', $showBillable);+ +$smarty->assign('show_billable', $showBillable); $smarty->assign('show_paid_status', $showPaidStatus); $smarty->assign('show_project', $showProject); $smarty->assign('show_task', $showTask); From 87b5c171f0ddb7ba24e5cf86a5238f1564e12459 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 20 Feb 2021 21:03:38 +0000 Subject: [PATCH 223/652] A couple of minor fixes to remove some php8 warnings. --- WEB-INF/lib/DateAndTime.class.php | 3 ++- WEB-INF/lib/ttUser.class.php | 1 + initialize.php | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WEB-INF/lib/DateAndTime.class.php b/WEB-INF/lib/DateAndTime.class.php index 20f274265..1184bd853 100644 --- a/WEB-INF/lib/DateAndTime.class.php +++ b/WEB-INF/lib/DateAndTime.class.php @@ -325,6 +325,7 @@ function preprocessFormatString($format) { // replace locale-dependent strings $format = str_replace('%a', mb_substr($i18n->getWeekDayName($this->mDay), 0, 3, 'utf-8'), $format); $format = str_replace('%A', $i18n->getWeekDayName($this->mDay), $format); + /* This block is commented out because we currently do not use these formatters. $abbrev_month = mb_substr($i18n->monthNames[$this->mMonth], 0, 3, 'utf-8'); $format = str_replace('%b', $abbrev_month, $format); $format = str_replace('%h', $abbrev_month, $format); @@ -332,7 +333,7 @@ function preprocessFormatString($format) { $format = str_replace('%Z', date('O'), $format); // format as 'O' for consistency with JS strftime if (strpos($format, '%c') !== false) { $format = str_replace('%c', $this->preprocessFormatString('%a %d %b %Y %T %Z'), $format); - } + }*/ return $format; } diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index 72b829d31..c006350fd 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -488,6 +488,7 @@ function getUsers($options) { $includeSelf = isset($options['include_self']); $select_part = 'select u.id, u.group_id, u.name'; + $include_quota = false; if (isset($options['include_login'])) { $select_part .= ', u.login'; // Piggy-back on include_login to see if we must also include quota_percent. diff --git a/initialize.php b/initialize.php index f955479f7..55b1a1034 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5410"); +define("APP_VERSION", "1.19.23.5411"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From f3f9921ce9d15b84658b40bf1cefe4870490e0ab Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 20 Feb 2021 21:56:04 +0000 Subject: [PATCH 224/652] A couple more fixes for php8. --- WEB-INF/lib/form/Calendar.class.php | 2 +- WEB-INF/lib/ttUser.class.php | 4 +++- initialize.php | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/WEB-INF/lib/form/Calendar.class.php b/WEB-INF/lib/form/Calendar.class.php index d335e1503..337737f1c 100644 --- a/WEB-INF/lib/form/Calendar.class.php +++ b/WEB-INF/lib/form/Calendar.class.php @@ -80,7 +80,7 @@ function getHtml() { $firstOfPreviousMonth = strftime(DB_DATEFORMAT, $firstOfPreviousMonth2AM); // Print calendar header. - $html .= "\n\n\n"; + $html = "\n\n\n"; $html .= ''."\n"; $html .= '
'; $html .= '
'; diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index c006350fd..b01ffe687 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -347,7 +347,9 @@ function getAssignedProjects($options = null) $group_id = $this->getGroup(); $org_id = $this->org_id; - if ($options['include_files']) { + $filePart = ''; + $fileJoin = ''; + if (isset($options['include_files'])) { $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; $fileJoin = " left join (select distinct entity_id from tt_files". " where entity_type = 'project' and group_id = $group_id and org_id = $org_id and status = 1) Sub1". diff --git a/initialize.php b/initialize.php index 55b1a1034..1aa264cca 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5411"); +define("APP_VERSION", "1.19.23.5412"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 6a5b24018a7c9d5744c84e8135d588b81b9ae6cf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 20 Feb 2021 23:11:47 +0000 Subject: [PATCH 225/652] Updated smarty to version 3.1.39 for better php8 support. --- WEB-INF/lib/smarty/Smarty.class.php | 7 +++---- WEB-INF/lib/smarty/SmartyBC.class.php | 2 +- .../smarty_internal_compile_function.php | 5 +++++ ...internal_compile_private_special_variable.php | 8 ++++++-- .../smarty_internal_config_file_compiler.php | 4 ++-- .../sysplugins/smarty_internal_errorhandler.php | 2 +- .../smarty_internal_parsetree_template.php | 16 ++++++++-------- WEB-INF/templates/time2.tpl | 2 ++ initialize.php | 2 +- 9 files changed, 29 insertions(+), 19 deletions(-) diff --git a/WEB-INF/lib/smarty/Smarty.class.php b/WEB-INF/lib/smarty/Smarty.class.php index 9e0ca7670..375bab133 100644 --- a/WEB-INF/lib/smarty/Smarty.class.php +++ b/WEB-INF/lib/smarty/Smarty.class.php @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * version 3.0 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -27,7 +27,6 @@ * @author Uwe Tews * @author Rodney Rehm * @package Smarty - * @version 3.1.34-dev */ /** * set SMARTY_DIR to absolute path to Smarty library files. @@ -112,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.36'; + const SMARTY_VERSION = '3.1.39'; /** * define variable scopes */ @@ -800,7 +799,7 @@ public function addTemplateDir($template_dir, $key = null, $isConfig = false) * @param mixed $index index of directory to get, null to get all * @param bool $isConfig true for config_dir * - * @return array list of template directories, or directory of $index + * @return array|string list of template directories, or directory of $index */ public function getTemplateDir($index = null, $isConfig = false) { diff --git a/WEB-INF/lib/smarty/SmartyBC.class.php b/WEB-INF/lib/smarty/SmartyBC.class.php index 836f98153..0550e46dc 100644 --- a/WEB-INF/lib/smarty/SmartyBC.class.php +++ b/WEB-INF/lib/smarty/SmartyBC.class.php @@ -6,7 +6,7 @@ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. + * version 3.0 of the License, or (at your option) any later version. * This library 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 diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php index 6e408ca72..d0f2b0f4a 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_function.php @@ -58,6 +58,11 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler) } unset($_attr[ 'nocache' ]); $_name = trim($_attr[ 'name' ], '\'"'); + + if (!preg_match('/^[a-zA-Z0-9_\x80-\xff]+$/', $_name)) { + $compiler->trigger_template_error("Function name contains invalid characters: {$_name}", null, true); + } + $compiler->parent_compiler->tpl_function[ $_name ] = array(); $save = array( $_attr, $compiler->parser->current_buffer, $compiler->template->compiled->has_nocache_code, diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_special_variable.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_special_variable.php index b317c9f33..d53ef51ff 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_special_variable.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_compile_private_special_variable.php @@ -81,6 +81,10 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $ case 'template': return 'basename($_smarty_tpl->source->filepath)'; case 'template_object': + if (isset($compiler->smarty->security_policy)) { + $compiler->trigger_template_error("(secure mode) template_object not permitted"); + break; + } return '$_smarty_tpl'; case 'current_dir': return 'dirname($_smarty_tpl->source->filepath)'; @@ -94,9 +98,9 @@ public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $ break; } if (strpos($_index[ 1 ], '$') === false && strpos($_index[ 1 ], '\'') === false) { - return "@constant('{$_index[1]}')"; + return "(defined('{$_index[1]}') ? constant('{$_index[1]}') : null)"; } else { - return "@constant({$_index[1]})"; + return "(defined({$_index[1]}) ? constant({$_index[1]}) : null)"; } // no break case 'config': diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php index a842fa8f3..90c5dcefa 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_config_file_compiler.php @@ -115,7 +115,7 @@ public function compileTemplate(Smarty_Internal_Template $template) $this->smarty->_debug->start_compile($this->template); } // init the lexer/parser to compile the config file - /* @var Smarty_Internal_ConfigFileLexer $this ->lex */ + /* @var Smarty_Internal_ConfigFileLexer $this->lex */ $this->lex = new $this->lexer_class( str_replace( array( @@ -127,7 +127,7 @@ public function compileTemplate(Smarty_Internal_Template $template) ) . "\n", $this ); - /* @var Smarty_Internal_ConfigFileParser $this ->parser */ + /* @var Smarty_Internal_ConfigFileParser $this->parser */ $this->parser = new $this->parser_class($this->lex, $this); if (function_exists('mb_internal_encoding') && function_exists('ini_get') diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php index 0ba00659d..56dca18fa 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_errorhandler.php @@ -65,7 +65,7 @@ public static function muteExpectedErrors() * * @return bool */ - public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) + public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext = array()) { $_is_muted_directory = false; // add the SMARTY_DIR to the list of muted directories diff --git a/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php b/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php index 477232ef8..ab4c3ec3b 100644 --- a/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php +++ b/WEB-INF/lib/smarty/sysplugins/smarty_internal_parsetree_template.php @@ -127,12 +127,12 @@ public function to_smarty_php(Smarty_Internal_Templateparser $parser) } private function getChunkedSubtrees() { - $chunks = []; + $chunks = array(); $currentMode = null; - $currentChunk = []; + $currentChunk = array(); for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) { - if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, ['textstripped', 'text', 'tag'])) { + if ($this->subtrees[ $key ]->data === '' && in_array($currentMode, array('textstripped', 'text', 'tag'))) { continue; } @@ -150,19 +150,19 @@ private function getChunkedSubtrees() { if ($newMode == $currentMode) { $currentChunk[] = $this->subtrees[ $key ]; } else { - $chunks[] = [ + $chunks[] = array( 'mode' => $currentMode, 'subtrees' => $currentChunk - ]; + ); $currentMode = $newMode; - $currentChunk = [$this->subtrees[ $key ]]; + $currentChunk = array($this->subtrees[ $key ]); } } if ($currentMode && $currentChunk) { - $chunks[] = [ + $chunks[] = array( 'mode' => $currentMode, 'subtrees' => $currentChunk - ]; + ); } return $chunks; } diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 487bff7cf..65216efb8 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -234,3 +234,5 @@ License: See license.txt *} {/if}
+ +{$smarty.version} diff --git a/initialize.php b/initialize.php index 1aa264cca..771995d88 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5412"); +define("APP_VERSION", "1.19.23.5413"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 85823f48d86f438909af947b57038a1090283030 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 26 Feb 2021 16:24:51 +0000 Subject: [PATCH 226/652] A minor fix to dbinstall.php to address a migration issue with custom fields. --- dbinstall.php | 4 ++-- initialize.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dbinstall.php b/dbinstall.php index 59d3923f8..9960e1ade 100644 --- a/dbinstall.php +++ b/dbinstall.php @@ -691,10 +691,10 @@ function ttGenerateKeys() { print "Updated $clients_updated clients...
\n"; } - // The update_custom_fields function updates option_id field field in tt_custom_field_log table. + // The update_custom_fields function updates option_id field in tt_custom_field_log table. if ($_POST['update_custom_fields']) { $mdb2 = getConnection(); - $sql = "update tt_custom_field_log set option_id = value where field_id in (select id from tt_custom_fields where type = 2)"; + $sql = "update tt_custom_field_log set option_id = value where option_id is null and value is not null and field_id in (select id from tt_custom_fields where type = 2)"; $affected = $mdb2->exec($sql); if (is_a($affected, 'PEAR_Error')) die($affected->getMessage()); diff --git a/initialize.php b/initialize.php index 771995d88..5323d00b8 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5413"); +define("APP_VERSION", "1.19.23.5414"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 40f3d9345adc20e6f28eb9f59e2489aff87fecf5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 16:00:53 +0000 Subject: [PATCH 227/652] Fixed a critical security vulnerability with password resets. --- WEB-INF/templates/report.tpl | 4 ++++ initialize.php | 2 +- password_reset.php | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/WEB-INF/templates/report.tpl b/WEB-INF/templates/report.tpl index f7ef4ff2e..0a13ea83a 100644 --- a/WEB-INF/templates/report.tpl +++ b/WEB-INF/templates/report.tpl @@ -117,6 +117,7 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} + {* {* column for edit icons *}   {/if} @@ -171,6 +172,7 @@ {if 1 == $item.type}{/if} {if 2 == $item.type}{/if} {/if} + {* {$i18n.label.edit}{* column for edit icons *} {if $note_on_separate_row && $bean->getAttribute('chnote') && $item.note} @@ -220,6 +222,7 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} + {* {* column for edit icons *} {/if} @@ -261,6 +264,7 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} + {* {* column for edit icons *} {/if} diff --git a/initialize.php b/initialize.php index 5323d00b8..e2aeb6c85 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.23.5414"); +define("APP_VERSION", "1.19.24.5415"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/password_reset.php b/password_reset.php index 5beafb7fc..53099b9af 100644 --- a/password_reset.php +++ b/password_reset.php @@ -46,7 +46,10 @@ if ($err->no()) { // Prepare and save a temporary reference for user. - $temp_ref = md5(uniqid()); + $cryptographically_strong = true; + $random_bytes = openssl_random_pseudo_bytes(16, $cryptographically_strong); + if ($random_bytes === false) die ("openssl_random_pseudo_bytes function call failed..."); + $temp_ref = bin2hex($random_bytes); ttUserHelper::saveTmpRef($temp_ref, $user->id); $user_i18n = null; From 1339c3a043a916cd7f5142c3aec4a956b598f69c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 16:19:09 +0000 Subject: [PATCH 228/652] Added protection against brute force guessing of random codes used in password resets. --- WEB-INF/lib/ttUserHelper.class.php | 5 +++++ initialize.php | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index eac057304..accabe1fe 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -82,6 +82,11 @@ static function getUserByEmail($email) { static function getUserIdByTmpRef($ref) { $mdb2 = getConnection(); + // Some protection for brute force attacks to guess a reference for user. + // This limits an available window for brute force guessing to 1 hour. + $sql = "delete from tt_tmp_refs where created < now() - interval 1 hour"; + $affected = $mdb2->exec($sql); + $sql = "select user_id from tt_tmp_refs where ref = ".$mdb2->quote($ref); $res = $mdb2->query($sql); diff --git a/initialize.php b/initialize.php index e2aeb6c85..63215b71e 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.24.5415"); +define("APP_VERSION", "1.19.24.5416"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 9a8ee13a037931d29130379c9ad193613b45998c Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 17:35:22 +0000 Subject: [PATCH 229/652] Fixed SQL injection vulnerability in group_edit.php. --- group_edit.php | 6 ++++-- initialize.php | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/group_edit.php b/group_edit.php index c8ad2e142..f60a11331 100644 --- a/group_edit.php +++ b/group_edit.php @@ -32,15 +32,17 @@ import('ttRoleHelper'); import('ttConfigHelper'); +$id = (int)$request->getParameter('id'); + // Access checks. // There are 4 distinct situations: // 1) Editing home group in get or post. // 2) Editing a subgroup in get or post. // We'll check access separately as it is about different right checks. if ($request->isGet()) { - $group_id = $request->getParameter('id') ? $request->getParameter('id') : $user->getGroup(); + $group_id = $request->getParameter('id') ? (int)$request->getParameter('id') : $user->getGroup(); } else { - $group_id = $request->getParameter('group') ? $request->getParameter('group') : $user->getGroup(); + $group_id = $request->getParameter('group') ? (int)$request->getParameter('group') : $user->getGroup(); } $home_group = $user->group_id == $group_id; if ($home_group) { diff --git a/initialize.php b/initialize.php index 63215b71e..f069495f9 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.24.5416"); +define("APP_VERSION", "1.19.25.5417"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2b34dc2006121e466513b50015262c6936c876bf Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 17:37:58 +0000 Subject: [PATCH 230/652] Removed garbage introduced in previous commit. --- group_edit.php | 2 -- initialize.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/group_edit.php b/group_edit.php index f60a11331..49bd1e613 100644 --- a/group_edit.php +++ b/group_edit.php @@ -32,8 +32,6 @@ import('ttRoleHelper'); import('ttConfigHelper'); -$id = (int)$request->getParameter('id'); - // Access checks. // There are 4 distinct situations: // 1) Editing home group in get or post. diff --git a/initialize.php b/initialize.php index f069495f9..7863d0aba 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.25.5417"); +define("APP_VERSION", "1.19.25.5418"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From fdf67755ae8396162b19332e3b10763c9ea274b2 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 17:49:19 +0000 Subject: [PATCH 231/652] More protection against sql injections. --- group_edit.php | 28 ++-------------------------- groups.php | 30 +++--------------------------- initialize.php | 2 +- 3 files changed, 6 insertions(+), 54 deletions(-) diff --git a/group_edit.php b/group_edit.php index 49bd1e613..d972ba387 100644 --- a/group_edit.php +++ b/group_edit.php @@ -1,30 +1,6 @@ isPost()) { - $group_id = $request->getParameter('group'); + $group_id = (int)$request->getParameter('group'); $user->setOnBehalfGroup($group_id); } else { $group_id = $user->getGroup(); diff --git a/initialize.php b/initialize.php index 7863d0aba..40ccda78d 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.25.5418"); +define("APP_VERSION", "1.19.25.5419"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 00885b9872c31eb3298b047ee2a27b278248d4c5 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 18:22:24 +0000 Subject: [PATCH 232/652] Added casts to int to sanitize some post parameters. --- admin_group_add.php | 28 ++-------------------------- admin_group_delete.php | 28 ++-------------------------- admin_group_edit.php | 28 ++-------------------------- admin_groups.php | 28 ++-------------------------- admin_options.php | 28 ++-------------------------- cf_custom_field_add.php | 36 +++++------------------------------- initialize.php | 2 +- 7 files changed, 16 insertions(+), 162 deletions(-) diff --git a/admin_group_add.php b/admin_group_add.php index c42644f09..45aa32261 100644 --- a/admin_group_add.php +++ b/admin_group_add.php @@ -1,30 +1,6 @@ isPost()) { $cl_field_name = trim($request->getParameter('name')); - $cl_entity_type = $request->getParameter('entity'); - $cl_field_type = $request->getParameter('type'); - $cl_required = $request->getParameter('required'); - if (!$cl_required) - $cl_required = 0; + $cl_entity_type = (int)$request->getParameter('entity'); + $cl_field_type = (int)$request->getParameter('type'); + $cl_required = (int)$request->getParameter('required'); } $form = new Form('fieldForm'); diff --git a/initialize.php b/initialize.php index 40ccda78d..c5edb812a 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.25.5419"); +define("APP_VERSION", "1.19.25.5420"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From bc006920353e50e27d815a8f5d529269080db40e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 27 Feb 2021 18:50:14 +0000 Subject: [PATCH 233/652] More sanitizing of user input. --- cf_custom_field_delete.php | 28 ++-------------------------- cf_custom_field_edit.php | 28 ++-------------------------- cf_custom_fields.php | 28 ++-------------------------- cf_dropdown_option_add.php | 28 ++-------------------------- cf_dropdown_option_delete.php | 30 +++--------------------------- cf_dropdown_option_edit.php | 30 +++--------------------------- cf_dropdown_options.php | 28 ++-------------------------- 7 files changed, 16 insertions(+), 184 deletions(-) diff --git a/cf_custom_field_delete.php b/cf_custom_field_delete.php index c8a133692..ba222c657 100644 --- a/cf_custom_field_delete.php +++ b/cf_custom_field_delete.php @@ -1,30 +1,6 @@ getParameter('id'); +$cl_id = (int)$request->getParameter('id'); $option = CustomFields::getOptionName($cl_id); if (!$option) { header('Location: access_denied.php'); diff --git a/cf_dropdown_option_edit.php b/cf_dropdown_option_edit.php index 4f1103d7b..4cea7358f 100644 --- a/cf_dropdown_option_edit.php +++ b/cf_dropdown_option_edit.php @@ -1,30 +1,6 @@ getParameter('id'); +$cl_id = (int)$request->getParameter('id'); $cl_name = CustomFields::getOptionName($cl_id); if (!$cl_name) { header('Location: access_denied.php'); diff --git a/cf_dropdown_options.php b/cf_dropdown_options.php index 3b4663f8c..06f53a7d8 100644 --- a/cf_dropdown_options.php +++ b/cf_dropdown_options.php @@ -1,30 +1,6 @@ Date: Sat, 27 Feb 2021 23:13:24 +0000 Subject: [PATCH 234/652] Added edit icons on reports to allow for quick edits. --- WEB-INF/lib/ttExpenseHelper.class.php | 66 ++++++++++++++++----------- WEB-INF/lib/ttReportHelper.class.php | 14 +++--- WEB-INF/lib/ttTimeHelper.class.php | 66 ++++++++++++++++----------- WEB-INF/lib/ttUserHelper.class.php | 28 +----------- WEB-INF/templates/report.tpl | 13 ++++-- expense_edit.php | 1 + initialize.php | 2 +- time_edit.php | 1 + 8 files changed, 102 insertions(+), 89 deletions(-) diff --git a/WEB-INF/lib/ttExpenseHelper.class.php b/WEB-INF/lib/ttExpenseHelper.class.php index 303ca5767..0de7eca11 100644 --- a/WEB-INF/lib/ttExpenseHelper.class.php +++ b/WEB-INF/lib/ttExpenseHelper.class.php @@ -1,30 +1,6 @@ isUserValid($user_id); + + if (!$user_valid) return false; + + // Set on behalf user. + $user->setOnBehalfUser($user_id); + // Get on behalf record. + return ttExpenseHelper::getItem($id); + } + + // getUserForItem - retrieves user id for an expense item. + static function getUserForItem($id) { + global $user; + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $mdb2 = getConnection(); + + // Obtain user_id for the expense item. + $sql = "select ei.user_id from tt_expense_items ei ". + " where ei.id = $id and ei.group_id = $group_id and ei.org_id = $org_id and ei.status = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return false; + if (!$res->numRows()) return false; + + $val = $res->fetchRow(); + $user_id = $val['user_id']; + return $user_id; + } + // getItemForFileView - retrieves an expense item identified by its id for // attachment view operation. // diff --git a/WEB-INF/lib/ttReportHelper.class.php b/WEB-INF/lib/ttReportHelper.class.php index 294225e0c..b24890e7d 100644 --- a/WEB-INF/lib/ttReportHelper.class.php +++ b/WEB-INF/lib/ttReportHelper.class.php @@ -350,9 +350,10 @@ static function getItems($options) { array_push($fields, "cast(l.billable * coalesce(upb.rate, 0) * time_to_sec(l.duration)/3600 as decimal(10,2)) as cost"); // Use project rate for user. array_push($fields, "null as expense"); } - // Add approved. - if ($options['show_approved']) - array_push($fields, 'l.approved'); + // Add the fields used to determine if we show an edit icon for record. + array_push($fields, 'l.approved'); + array_push($fields, 'l.timesheet_id'); + array_push($fields, 'l.invoice_id'); // Add paid status. if ($canViewReports && $options['show_paid']) array_push($fields, 'l.paid'); @@ -513,9 +514,10 @@ static function getItems($options) { array_push($fields, 'ei.name as note'); array_push($fields, 'ei.cost as cost'); array_push($fields, 'ei.cost as expense'); - // Add approved. - if ($options['show_approved']) - array_push($fields, 'ei.approved'); + // Add the fields used to determine if we show an edit icon for record. + array_push($fields, 'ei.approved'); + array_push($fields, 'null as timesheet_id'); + array_push($fields, 'ei.invoice_id'); // Add paid status. if ($canViewReports && $options['show_paid']) array_push($fields, 'ei.paid'); diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index faa1197cd..f0b1ea100 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -1,30 +1,6 @@ isUserValid($user_id); + + if (!$user_valid) return false; + + // Set on behalf user. + $user->setOnBehalfUser($user_id); + // Get on behalf record. + return ttTimeHelper::getRecord($id); + } + + // getUserForRecord - retrieves user id for a time record. + static function getUserForRecord($id) { + global $user; + + $group_id = $user->getGroup(); + $org_id = $user->org_id; + + $mdb2 = getConnection(); + + // Obtain user_id for the time record. + $sql = "select l.user_id from tt_log l ". + " where l.id = $id and l.group_id = $group_id and l.org_id = $org_id and l.status = 1"; + $res = $mdb2->query($sql); + if (is_a($res, 'PEAR_Error')) return false; + if (!$res->numRows()) return false; + + $val = $res->fetchRow(); + $user_id = $val['user_id']; + return $user_id; + } + // getRecordForFileView - retrieves a time record identified by its id for // attachment view operation. // diff --git a/WEB-INF/lib/ttUserHelper.class.php b/WEB-INF/lib/ttUserHelper.class.php index accabe1fe..d4fc8d804 100644 --- a/WEB-INF/lib/ttUserHelper.class.php +++ b/WEB-INF/lib/ttUserHelper.class.php @@ -1,30 +1,6 @@ getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} - {* {* column for edit icons *} + {* column for edit icons *}   {/if} @@ -172,7 +172,12 @@ {if 1 == $item.type}{/if} {if 2 == $item.type}{/if} {/if} - {* {$i18n.label.edit}{* column for edit icons *} + {if $item.approved || $item.timesheet_id || $item.invoice_id} +   + {else} + {if 1 == $item.type}{$i18n.label.edit}{/if} + {if 2 == $item.type}{$i18n.label.edit}{/if} + {/if} {if $note_on_separate_row && $bean->getAttribute('chnote') && $item.note} @@ -222,7 +227,7 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} - {* {* column for edit icons *} + {* column for edit icons *} {/if} @@ -264,7 +269,7 @@ {if $bean->getAttribute('chtimesheet')}{/if} {if $bean->getAttribute('chfiles')}{/if} {if $use_checkboxes}{/if} - {* {* column for edit icons *} + {* column for edit icons *} {/if} diff --git a/expense_edit.php b/expense_edit.php index 092f33c11..5d1e75044 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -21,6 +21,7 @@ $cl_id = (int)$request->getParameter('id'); // Get the expense item we are editing. $expense_item = ttExpenseHelper::getItem($cl_id); +if (!$expense_item) $expense_item = ttExpenseHelper::getOnBehalfItem($cl_id); if (!$expense_item || $expense_item['approved'] || $expense_item['invoice_id']) { // Prohibit editing not ours, approved, or invoiced items. header('Location: access_denied.php'); diff --git a/initialize.php b/initialize.php index c5edb812a..3a08a9e78 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.25.5420"); +define("APP_VERSION", "1.19.26.5421"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time_edit.php b/time_edit.php index 4065bf08f..774add2c6 100644 --- a/time_edit.php +++ b/time_edit.php @@ -18,6 +18,7 @@ } $cl_id = (int)$request->getParameter('id'); $time_rec = ttTimeHelper::getRecord($cl_id); +if (!$time_rec) $time_rec = ttTimeHelper::getOnBehalfRecord($cl_id); if (!$time_rec || $time_rec['approved'] || $time_rec['timesheet_id'] || $time_rec['invoice_id']) { // Prohibit editing not ours, approved, assigned to timesheet, or invoiced records. header('Location: access_denied.php'); From 9c9e7d7976fed5b80c0d9dd74b7424f890584fc8 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Mar 2021 21:06:24 +0000 Subject: [PATCH 235/652] Sanitizing of user input on charts.php. --- WEB-INF/templates/time2.tpl | 2 -- charts.php | 4 ++-- initialize.php | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 65216efb8..487bff7cf 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -234,5 +234,3 @@ License: See license.txt *} {/if} - -{$smarty.version} diff --git a/charts.php b/charts.php index d4fb52b3b..026f97463 100644 --- a/charts.php +++ b/charts.php @@ -35,7 +35,7 @@ exit(); } if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { + if (!$user->isUserValid((int)$request->getParameter('user'))) { header('Location: access_denied.php'); // Wrong user id on post. exit(); } @@ -45,7 +45,7 @@ // Determine user for which we display this page. $userChanged = $request->getParameter('user_changed'); if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/initialize.php b/initialize.php index 3a08a9e78..faa912032 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5421"); +define("APP_VERSION", "1.19.26.5422"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From d0af0f472a64e19dfb48473cca1c374363fb6471 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Fri, 5 Mar 2021 21:24:18 +0000 Subject: [PATCH 236/652] Some more sanitizing of post parameters. --- charts.php | 6 +++--- initialize.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/charts.php b/charts.php index 026f97463..9dc29f588 100644 --- a/charts.php +++ b/charts.php @@ -43,7 +43,7 @@ // End of access checks. // Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); +$userChanged = (int)$request->getParameter('user_changed'); if ($request->isPost() && $userChanged) { $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); @@ -63,12 +63,12 @@ $_SESSION['date'] = $cl_date; if ($request->isPost()) { - $cl_interval = $request->getParameter('interval'); + $cl_interval = (int)$request->getParameter('interval'); if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH; $_SESSION['chart_interval'] = $cl_interval; $uc->setValue(SYSC_CHART_INTERVAL, $cl_interval); - $cl_type = $request->getParameter('type'); + $cl_type = (int)$request->getParameter('type'); if (!$cl_type) $cl_type = ttChartHelper::adjustType($cl_type); $_SESSION['chart_type'] = $cl_type; $uc->setValue(SYSC_CHART_TYPE, $cl_type); diff --git a/initialize.php b/initialize.php index faa912032..f54941375 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5422"); +define("APP_VERSION", "1.19.26.5423"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 2eaab13803846b91c90d49680099968731d4718e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 6 Mar 2021 15:12:37 +0000 Subject: [PATCH 237/652] A bit more of sanitizing work for posts. --- WEB-INF/lib/ttUser.class.php | 14 ++++++++------ cron.php | 28 ++-------------------------- custom_css.php | 28 ++-------------------------- dbinstall.php | 28 ++-------------------------- display_options.php | 36 ++++++------------------------------ initialize.php | 2 +- 6 files changed, 21 insertions(+), 115 deletions(-) diff --git a/WEB-INF/lib/ttUser.class.php b/WEB-INF/lib/ttUser.class.php index b01ffe687..fcfc1b9d5 100644 --- a/WEB-INF/lib/ttUser.class.php +++ b/WEB-INF/lib/ttUser.class.php @@ -617,6 +617,7 @@ function getUserDetails($user_id) { $mdb2 = getConnection(); $group_id = $this->getGroup(); $org_id = $this->org_id; + $uid = (int)$user_id; // Determine max rank. If we are searching in on behalf group // then rank restriction does not apply. @@ -624,7 +625,7 @@ function getUserDetails($user_id) { $sql = "select u.id, u.name, u.login, u.role_id, u.client_id, u.status, u.rate, u.quota_percent, u.email from tt_users u". " left join tt_roles r on (u.role_id = r.id)". - " where u.id = $user_id and u.group_id = $group_id and u.org_id = $org_id and u.status is not null". + " where u.id = $uid and u.group_id = $group_id and u.org_id = $org_id and u.status is not null". " and (r.rank < $max_rank or (r.rank = $max_rank and u.id = $this->id))"; // Users with lesser roles or self. $res = $mdb2->query($sql); if (!is_a($res, 'PEAR_Error')) { @@ -897,6 +898,7 @@ function setOnBehalfGroup($group_id) { // setOnBehalfUser sets on behalf user both the object and the session. function setOnBehalfUser($user_id) { + $uid = (int)$user_id; // In case we forgot to sanitize $user_id before getting here. // Unset things first. $this->behalf_id = null; @@ -906,16 +908,16 @@ function setOnBehalfUser($user_id) { unset($_SESSION['behalf_name']); // No need to set if user is us. - if ($user_id == $this->id) return; + if ($uid == $this->id) return; // No need to set if user id is not valid. - if (!$this->isUserValid($user_id)) return; + if (!$this->isUserValid($uid)) return; // We are good to set on behalf user. - $onBehalfUserName = ttUserHelper::getUserName($user_id); - $_SESSION['behalf_id'] = $user_id; + $onBehalfUserName = ttUserHelper::getUserName($uid); + $_SESSION['behalf_id'] = $uid; $_SESSION['behalf_name'] = $onBehalfUserName; - $this->behalf_id = $user_id; + $this->behalf_id = $uid; $this->behalf_name = $onBehalfUserName; $this->behalfUser = new ttBehalfUser($this->behalf_id, $this->org_id); diff --git a/cron.php b/cron.php index 331b4f36e..5adced71e 100644 --- a/cron.php +++ b/cron.php @@ -1,30 +1,6 @@ getConfigHelper(); if ($request->isPost()) { - $cl_time_note_on_separate_row = $request->getParameter('time_note_on_separate_row'); - $cl_time_not_complete_days = $request->getParameter('time_not_complete_days'); - $cl_record_custom_fields = $request->getParameter('record_custom_fields'); - $cl_report_note_on_separate_row = $request->getParameter('report_note_on_separate_row'); + $cl_time_note_on_separate_row = (bool)$request->getParameter('time_note_on_separate_row'); + $cl_time_not_complete_days = (bool)$request->getParameter('time_not_complete_days'); + $cl_record_custom_fields = (bool)$request->getParameter('record_custom_fields'); + $cl_report_note_on_separate_row = (bool)$request->getParameter('report_note_on_separate_row'); $cl_custom_css = trim($request->getParameter('custom_css')); } else { $cl_time_note_on_separate_row = $config->getDefinedValue('time_note_on_separate_row'); diff --git a/initialize.php b/initialize.php index f54941375..eb9fd4b94 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5423"); +define("APP_VERSION", "1.19.26.5424"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 477f47a63e8e476f6c84edff830bba03c7610667 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 6 Mar 2021 15:55:04 +0000 Subject: [PATCH 238/652] Some more sanitizing. --- expense_edit.php | 4 ++-- expenses.php | 6 +++--- initialize.php | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/expense_edit.php b/expense_edit.php index 5d1e75044..9c85bdb79 100644 --- a/expense_edit.php +++ b/expense_edit.php @@ -43,14 +43,14 @@ $cl_item_name = trim($request->getParameter('item_name')); $cl_cost = trim($request->getParameter('cost')); if ($user->isPluginEnabled('ps')) - $cl_paid = $request->getParameter('paid'); + $cl_paid = (bool)$request->getParameter('paid'); } else { $cl_date = $item_date->toString($user->getDateFormat()); $cl_client = $expense_item['client_id']; $cl_project = $expense_item['project_id']; $cl_item_name = $expense_item['name']; $cl_cost = $expense_item['cost']; - $cl_paid = $expense_item['paid']; + $cl_paid = (bool)$expense_item['paid']; } // Initialize elements of 'expenseItemForm'. diff --git a/expenses.php b/expenses.php index 170f0cd3b..e82d9d379 100644 --- a/expenses.php +++ b/expenses.php @@ -33,7 +33,7 @@ exit(); } if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { + if (!$user->isUserValid((int)$request->getParameter('user'))) { header('Location: access_denied.php'); // Wrong user id on post. exit(); } @@ -41,9 +41,9 @@ // End of access checks. // Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); +$userChanged = (int)$request->getParameter('user_changed'); if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/initialize.php b/initialize.php index eb9fd4b94..344ec8229 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5424"); +define("APP_VERSION", "1.19.26.5425"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 3a3c14ffd3a4266aeac52e7da19d7c0fa684792d Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 6 Mar 2021 17:57:57 +0000 Subject: [PATCH 239/652] A bit more sanitizing of post parameters. --- export.php | 28 ++-------------------------- file_download.php | 28 ++-------------------------- group_add.php | 28 ++-------------------------- group_advanced_edit.php | 28 ++-------------------------- group_delete.php | 28 ++-------------------------- group_edit.php | 12 ++++++------ import.php | 28 ++-------------------------- initialize.php | 2 +- invoice_add.php | 30 +++--------------------------- invoice_delete.php | 28 ++-------------------------- invoice_send.php | 28 ++-------------------------- invoice_view.php | 28 ++-------------------------- invoices.php | 28 ++-------------------------- 13 files changed, 30 insertions(+), 294 deletions(-) diff --git a/export.php b/export.php index 2206def2d..2bcba2dce 100644 --- a/export.php +++ b/export.php @@ -1,30 +1,6 @@ getParameter('group_changed'); +$groupChanged = (bool)$request->getParameter('group_changed'); if ($request->isPost() && $groupChanged) { $user->setOnBehalfGroup($group_id); } @@ -62,11 +62,11 @@ $cl_tracking_mode = $request->getParameter('tracking_mode'); $cl_project_required = $request->getParameter('project_required'); $cl_record_type = $request->getParameter('record_type'); - $cl_punch_mode = $request->getParameter('punch_mode'); - $cl_allow_overlap = $request->getParameter('allow_overlap'); - $cl_future_entries = $request->getParameter('future_entries'); - $cl_uncompleted_indicators = $request->getParameter('uncompleted_indicators'); - $cl_confirm_save = $request->getParameter('confirm_save'); + $cl_punch_mode = (bool)$request->getParameter('punch_mode'); + $cl_allow_overlap = (bool)$request->getParameter('allow_overlap'); + $cl_future_entries = (bool)$request->getParameter('future_entries'); + $cl_uncompleted_indicators = (bool)$request->getParameter('uncompleted_indicators'); + $cl_confirm_save = (bool)$request->getParameter('confirm_save'); } else { $cl_currency = ($group['currency'] == '' ? CURRENCY_DEFAULT : $group['currency']); $cl_lang = $group['lang']; diff --git a/import.php b/import.php index 938fdb3dd..b743b3f5a 100644 --- a/import.php +++ b/import.php @@ -1,30 +1,6 @@ isPost()) { $cl_date = $request->getParameter('date'); - $cl_client = $request->getParameter('client'); + $cl_client = (int)$request->getParameter('client'); $cl_project = $request->getParameter('project'); $cl_number = trim($request->getParameter('number')); $cl_start = $request->getParameter('start'); diff --git a/invoice_delete.php b/invoice_delete.php index 89ea372a3..5b473dfa0 100644 --- a/invoice_delete.php +++ b/invoice_delete.php @@ -1,30 +1,6 @@ Date: Sat, 6 Mar 2021 21:19:21 +0000 Subject: [PATCH 240/652] Some more sanitizing work. --- locking.php | 28 ++---------------- login.php | 28 ++---------------- logout.php | 28 ++---------------- notification_add.php | 28 ++---------------- notification_delete.php | 28 ++---------------- notification_edit.php | 28 ++---------------- notifications.php | 28 ++---------------- password_change.php | 28 ++---------------- plugins.php | 64 +++++++++++++---------------------------- 9 files changed, 36 insertions(+), 252 deletions(-) diff --git a/locking.php b/locking.php index 9b23c876a..04c8d9419 100644 --- a/locking.php +++ b/locking.php @@ -1,30 +1,6 @@ doLogout(); diff --git a/notification_add.php b/notification_add.php index b7f743256..83cd7a538 100644 --- a/notification_add.php +++ b/notification_add.php @@ -1,30 +1,6 @@ isPost()) { // Plugins that user wants to save for the current group. - $cl_charts = $request->getParameter('charts'); - $cl_clients = $request->getParameter('clients'); - $cl_client_required = $request->getParameter('client_required'); - $cl_invoices = $request->getParameter('invoices'); - $cl_paid_status = $request->getParameter('paid_status'); - $cl_custom_fields = $request->getParameter('custom_fields'); - $cl_expenses = $request->getParameter('expenses'); - $cl_tax_expenses = $request->getParameter('tax_expenses'); - $cl_notifications = $request->getParameter('notifications'); - $cl_locking = $request->getParameter('locking'); - $cl_quotas = $request->getParameter('quotas'); - $cl_week_view = $request->getParameter('week_view'); - $cl_work_units = $request->getParameter('work_units'); - $cl_approval = $request->getParameter('approval'); - $cl_timesheets = $request->getParameter('timesheets'); - $cl_templates = $request->getParameter('templates'); - $cl_attachments = $request->getParameter('attachments'); - $cl_work = $request->getParameter('work'); + $cl_charts = (bool)$request->getParameter('charts'); + $cl_clients = (bool)$request->getParameter('clients'); + $cl_client_required = (bool)$request->getParameter('client_required'); + $cl_invoices = (bool)$request->getParameter('invoices'); + $cl_paid_status = (bool)$request->getParameter('paid_status'); + $cl_custom_fields = (bool)$request->getParameter('custom_fields'); + $cl_expenses = (bool)$request->getParameter('expenses'); + $cl_tax_expenses = (bool)$request->getParameter('tax_expenses'); + $cl_notifications = (bool)$request->getParameter('notifications'); + $cl_locking = (bool)$request->getParameter('locking'); + $cl_quotas = (bool)$request->getParameter('quotas'); + $cl_week_view = (bool)$request->getParameter('week_view'); + $cl_work_units = (bool)$request->getParameter('work_units'); + $cl_approval = (bool)$request->getParameter('approval'); + $cl_timesheets = (bool)$request->getParameter('timesheets'); + $cl_templates = (bool)$request->getParameter('templates'); + $cl_attachments = (bool)$request->getParameter('attachments'); + $cl_work = (bool)$request->getParameter('work'); } else { // Note: we get here in get, and also in post when group changes. // Which plugins do we have enabled in currently selected group? From 5a9248484ea3248963da71b955449ce6f354580b Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sat, 6 Mar 2021 21:27:05 +0000 Subject: [PATCH 241/652] Some cosmetic refactoring. --- initialize.php | 2 +- predefined_expense_add.php | 28 ++------------------------- predefined_expense_delete.php | 36 ++++++----------------------------- predefined_expense_edit.php | 30 +++-------------------------- predefined_expenses.php | 28 ++------------------------- 5 files changed, 14 insertions(+), 110 deletions(-) diff --git a/initialize.php b/initialize.php index 22d73352c..c454c8337 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5426"); +define("APP_VERSION", "1.19.26.5427"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/predefined_expense_add.php b/predefined_expense_add.php index 2a0ab6be9..e300fa43e 100644 --- a/predefined_expense_add.php +++ b/predefined_expense_add.php @@ -1,30 +1,6 @@ getParameter('id'); -$predefined_expense = ttPredefinedExpenseHelper::get($cl_predefined_expense_id); +$predefined_expense_id = (int)$request->getParameter('id'); +$predefined_expense = ttPredefinedExpenseHelper::get($predefined_expense_id); if (!$predefined_expense) { header('Location: access_denied.php'); exit(); @@ -51,13 +27,13 @@ $predefined_expense_to_delete = $predefined_expense['name']; $form = new Form('predefinedExpenseDeleteForm'); -$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$cl_predefined_expense_id)); +$form->addInput(array('type'=>'hidden','name'=>'id','value'=>$predefined_expense_id)); $form->addInput(array('type'=>'submit','name'=>'btn_delete','value'=>$i18n->get('label.delete'))); $form->addInput(array('type'=>'submit','name'=>'btn_cancel','value'=>$i18n->get('button.cancel'))); if ($request->isPost()) { if ($request->getParameter('btn_delete')) { - if (ttPredefinedExpenseHelper::delete($cl_predefined_expense_id)) { + if (ttPredefinedExpenseHelper::delete($predefined_expense_id)) { header('Location: predefined_expenses.php'); exit(); } else diff --git a/predefined_expense_edit.php b/predefined_expense_edit.php index 3f0cb0c8c..1eca3a2c7 100644 --- a/predefined_expense_edit.php +++ b/predefined_expense_edit.php @@ -1,30 +1,6 @@ getParameter('id'); +$predefined_expense_id = (int)$request->getParameter('id'); $predefined_expense = ttPredefinedExpenseHelper::get($predefined_expense_id); if (!$predefined_expense) { header('Location: access_denied.php'); diff --git a/predefined_expenses.php b/predefined_expenses.php index e1c14d802..9f94bd1cc 100644 --- a/predefined_expenses.php +++ b/predefined_expenses.php @@ -1,30 +1,6 @@ Date: Sat, 6 Mar 2021 22:24:50 +0000 Subject: [PATCH 242/652] Cosmetic. --- WEB-INF/lib/ttRoleHelper.class.php | 2 +- initialize.php | 2 +- profile_edit.php | 28 ++------------------------ quotas.php | 28 ++------------------------ report.php | 32 ++++-------------------------- report_send.php | 28 ++------------------------ reports.php | 28 ++------------------------ role_add.php | 28 ++------------------------ role_delete.php | 28 ++------------------------ role_edit.php | 28 ++------------------------ 10 files changed, 20 insertions(+), 212 deletions(-) diff --git a/WEB-INF/lib/ttRoleHelper.class.php b/WEB-INF/lib/ttRoleHelper.class.php index 7fa9f8fb2..a3753d238 100644 --- a/WEB-INF/lib/ttRoleHelper.class.php +++ b/WEB-INF/lib/ttRoleHelper.class.php @@ -149,7 +149,7 @@ static function delete($role_id) { $group_id = $user->getGroup(); $org_id = $user->org_id; - // Mark the task as deleted. + // Mark the role as deleted. $sql = "update tt_roles set status = NULL where id = $role_id and group_id = $group_id and org_id = $org_id"; $affected = $mdb2->exec($sql); return (!is_a($affected, 'PEAR_Error')); diff --git a/initialize.php b/initialize.php index c454c8337..fc27cbaaa 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5427"); +define("APP_VERSION", "1.19.26.5428"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/profile_edit.php b/profile_edit.php index d0d3de5fe..26091823f 100644 --- a/profile_edit.php +++ b/profile_edit.php @@ -1,30 +1,6 @@ getAttribute('chapproved') && ($user->can('approve_reports') || $user->can('approve_all_reports'))) @@ -199,7 +175,7 @@ $item_ids = ttReportHelper::getFromSession(); $time_log_ids = $item_ids['report_item_ids']; $expense_item_ids = $item_ids['report_item_expense_ids']; - // The above code is here beacues the arrays are used in both "Mark paid" and "Assign to invoice" handlers below. + // The above code is here because the arrays are used in both "Mark paid" and "Assign to invoice" handlers below. } if ($err->no()) { diff --git a/report_send.php b/report_send.php index e837f3e50..a2747b957 100644 --- a/report_send.php +++ b/report_send.php @@ -1,30 +1,6 @@ Date: Sun, 7 Mar 2021 17:35:27 +0000 Subject: [PATCH 243/652] Finished work on sanitizing post parameters to reduce risk of SQL injections. --- initialize.php | 2 +- mobile/expenses.php | 30 +++--------------------------- mobile/index.php | 28 ++-------------------------- mobile/login.php | 28 ++-------------------------- mobile/projects.php | 28 ++-------------------------- mobile/tasks.php | 28 ++-------------------------- mobile/time.php | 34 +++++----------------------------- mobile/timer.php | 28 ++-------------------------- mobile/users.php | 28 ++-------------------------- roles.php | 28 ++-------------------------- site_map.php | 28 ++-------------------------- success.php | 28 ++-------------------------- template_add.php | 28 ++-------------------------- template_delete.php | 30 +++--------------------------- template_edit.php | 30 +++--------------------------- templates.php | 28 ++-------------------------- time.php | 6 +++--- timesheet_add.php | 28 ++-------------------------- timesheet_edit.php | 28 ++-------------------------- timesheet_view.php | 28 ++-------------------------- timesheets.php | 34 +++++----------------------------- tofile.php | 28 ++-------------------------- topdf.php | 28 ++-------------------------- week.php | 34 +++++----------------------------- week_view.php | 36 ++++++------------------------------ work_units.php | 34 +++++----------------------------- 26 files changed, 71 insertions(+), 647 deletions(-) diff --git a/initialize.php b/initialize.php index fc27cbaaa..fca2f15a5 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5428"); +define("APP_VERSION", "1.19.26.5429"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/expenses.php b/mobile/expenses.php index 463671f4a..4f3b097fd 100644 --- a/mobile/expenses.php +++ b/mobile/expenses.php @@ -1,30 +1,6 @@ isPost() && $request->getParameter('user')) { - if (!$user->isUserValid($request->getParameter('user'))) { + if (!$user->isUserValid((int)$request->getParameter('user'))) { header('Location: access_denied.php'); // Wrong user id on post. exit(); } diff --git a/mobile/index.php b/mobile/index.php index 88408af23..4da5fab10 100644 --- a/mobile/index.php +++ b/mobile/index.php @@ -1,30 +1,6 @@ isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { header('Location: access_denied.php'); // User changed, but no right or wrong user id. exit(); } @@ -64,7 +40,7 @@ // Determine user for whom we display this page. if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/mobile/timer.php b/mobile/timer.php index e301716a4..1d870b1ca 100644 --- a/mobile/timer.php +++ b/mobile/timer.php @@ -1,30 +1,6 @@ getParameter('id'); +$cl_template_id = (int)$request->getParameter('id'); $template = ttTemplateHelper::get($cl_template_id); if (!$template) { header('Location: access_denied.php'); diff --git a/template_edit.php b/template_edit.php index 117b8166b..e3fa38947 100644 --- a/template_edit.php +++ b/template_edit.php @@ -1,30 +1,6 @@ getParameter('id'); +$cl_template_id = (int)$request->getParameter('id'); $template = ttTemplateHelper::get($cl_template_id); if (!$template) { header('Location: access_denied.php'); diff --git a/templates.php b/templates.php index 45ea2e477..636d4bc10 100644 --- a/templates.php +++ b/templates.php @@ -1,30 +1,6 @@ isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { header('Location: access_denied.php'); // User changed, but no right or wrong user id. exit(); } @@ -36,7 +36,7 @@ // Determine user for whom we display this page. if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/timesheet_add.php b/timesheet_add.php index 7c7633c6c..536241d62 100644 --- a/timesheet_add.php +++ b/timesheet_add.php @@ -1,30 +1,6 @@ isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { header('Location: access_denied.php'); // Group changed, but no rght or wrong user id. exit(); } @@ -59,7 +35,7 @@ // Determine user for whom we display this page. if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/tofile.php b/tofile.php index 996ffe9fd..b10bdee02 100644 --- a/tofile.php +++ b/tofile.php @@ -1,30 +1,6 @@ isPost()) { - $userChanged = $request->getParameter('user_changed'); // Reused in multiple places below. - if ($userChanged && !($user->can('track_time') && $user->isUserValid($request->getParameter('user')))) { + $userChanged = (bool)$request->getParameter('user_changed'); // Reused in multiple places below. + if ($userChanged && !($user->can('track_time') && $user->isUserValid((int)$request->getParameter('user')))) { header('Location: access_denied.php'); // User changed, but no right or wrong user id. exit(); } @@ -66,7 +42,7 @@ // Determine user for whom we display this page. if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); + $user_id = (int)$request->getParameter('user'); $user->setOnBehalfUser($user_id); } else { $user_id = $user->getUser(); diff --git a/week_view.php b/week_view.php index 149842e87..1718afd4b 100644 --- a/week_view.php +++ b/week_view.php @@ -1,30 +1,6 @@ getConfigHelper(); if ($request->isPost()) { - $cl_week_menu = $request->getParameter('week_menu'); - $cl_week_note = $request->getParameter('week_note'); - $cl_week_list = $request->getParameter('week_list'); - $cl_notes = $request->getParameter('notes'); + $cl_week_menu = (bool)$request->getParameter('week_menu'); + $cl_week_note = (bool)$request->getParameter('week_note'); + $cl_week_list = (bool)$request->getParameter('week_list'); + $cl_notes = (bool)$request->getParameter('notes'); } else { $cl_week_menu = $config->getDefinedValue('week_menu'); $cl_week_note = $config->getDefinedValue('week_note'); diff --git a/work_units.php b/work_units.php index e4d198d5c..826f899ab 100644 --- a/work_units.php +++ b/work_units.php @@ -1,30 +1,6 @@ getConfig()); if ($request->isPost()) { - $cl_minutes_in_unit = $request->getParameter('minutes_in_unit'); - $cl_1st_unit_threshold = $request->getParameter('1st_unit_threshold'); - $cl_totals_only = $request->getParameter('totals_only'); + $cl_minutes_in_unit = (int)$request->getParameter('minutes_in_unit'); + $cl_1st_unit_threshold = (int)$request->getParameter('1st_unit_threshold'); + $cl_totals_only = (bool)$request->getParameter('totals_only'); } else { $cl_minutes_in_unit = $user->getConfigInt('minutes_in_unit', 15); $cl_1st_unit_threshold = $user->getConfigInt('1st_unit_threshold', 0); From 464291697900e30ae782477930ef45a9cb8e4cc0 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 7 Mar 2021 18:15:58 +0000 Subject: [PATCH 244/652] Removed some more no longer used mobile pages. --- WEB-INF/templates/mobile/expenses.tpl | 226 ------------------------- WEB-INF/templates/mobile/projects.tpl | 76 --------- WEB-INF/templates/mobile/tasks.tpl | 76 --------- WEB-INF/templates/mobile/users.tpl | 95 ----------- initialize.php | 2 +- mobile/expenses.php | 235 -------------------------- mobile/projects.php | 36 ---- mobile/tasks.php | 35 ---- mobile/users.php | 51 ------ 9 files changed, 1 insertion(+), 831 deletions(-) delete mode 100644 WEB-INF/templates/mobile/expenses.tpl delete mode 100644 WEB-INF/templates/mobile/projects.tpl delete mode 100644 WEB-INF/templates/mobile/tasks.tpl delete mode 100644 WEB-INF/templates/mobile/users.tpl delete mode 100644 mobile/expenses.php delete mode 100644 mobile/projects.php delete mode 100644 mobile/tasks.php delete mode 100644 mobile/users.php diff --git a/WEB-INF/templates/mobile/expenses.tpl b/WEB-INF/templates/mobile/expenses.tpl deleted file mode 100644 index 81d7a214a..000000000 --- a/WEB-INF/templates/mobile/expenses.tpl +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - - - - -
<<{$timestring}>>
- -{$forms.expensesForm.open} - - - - - -
- -{if $user_dropdown} - - - - -{/if} -{if $user->isPluginEnabled('cl')} - - - - -{/if} -{if $show_project} - - - - -{/if} -{if $predefined_expenses} - - - - - - - - -{/if} - - - - - - - - -
{$i18n.label.user}:{$forms.expensesForm.user.control}
{$i18n.label.client}{if $user->isOptionEnabled('client_required')} (*){/if}:{$forms.expensesForm.client.control}
{$i18n.label.project} (*):{$forms.expensesForm.project.control}
{$i18n.label.expense}:{$forms.expensesForm.predefined_expense.control}
{$i18n.label.quantity}:{$forms.expensesForm.quantity.control}
{$i18n.label.item} (*):{$forms.expensesForm.item_name.control}
{$i18n.label.cost} (*):{$forms.expensesForm.cost.control} {$user->getCurrency()|escape}
-
- - - - - -
{$forms.expensesForm.btn_submit.control}
- - - - - -
-{if $expense_items} - - - {if $user->isPluginEnabled('cl')} - - {/if} - {if $show_project} - - {/if} - - - - {foreach $expense_items as $item} - - {if $user->isPluginEnabled('cl')} - - {/if} - {if $show_project} - - {/if} - - - - {/foreach} -
{$i18n.label.client}{$i18n.label.project}{$i18n.label.item}{$i18n.label.cost}
{$item.client|escape}{$item.project|escape} - {if $item.approved || $item.invoice_id} - {$item.item|escape} - {else} - {$item.item|escape} - {/if} - {$item.cost}
- - - - -
{$i18n.label.day_total}: {$user->getCurrency()|escape} {$day_total}
-{/if} -
-{$forms.expensesForm.close} diff --git a/WEB-INF/templates/mobile/projects.tpl b/WEB-INF/templates/mobile/projects.tpl deleted file mode 100644 index 96d27054f..000000000 --- a/WEB-INF/templates/mobile/projects.tpl +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - -
-{if $user->can('manage_projects')} - - {if $inactive_projects} - - {/if} - {if $active_projects} - - - - - {foreach $active_projects as $project} - - - - - {/foreach} - {/if} -
{$i18n.form.projects.active_projects}
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}
- - - - - -

-
-
- - {if $inactive_projects} - - - - - - - {foreach $inactive_projects as $project} - - - - - {/foreach} -
{$i18n.form.projects.inactive_projects}
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}
- - - - - -

-
-
- {/if} -{else} - - - - - - {if $active_projects} - {foreach $active_projects as $project} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$project.name|escape}{$project.description|escape}
-{/if} -
diff --git a/WEB-INF/templates/mobile/tasks.tpl b/WEB-INF/templates/mobile/tasks.tpl deleted file mode 100644 index 3fbee1f7d..000000000 --- a/WEB-INF/templates/mobile/tasks.tpl +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - -
-{if $user->can('manage_tasks')} - - {if $inactive_tasks} - - {/if} - - - - - {if $active_tasks} - {foreach $active_tasks as $task} - - - - - {/foreach} - {/if} -
{$i18n.form.tasks.active_tasks}
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}
- - - - - -

-
-
- - {if $inactive_tasks} - - - - - - - {foreach $inactive_tasks as $task} - - - - - {/foreach} -
{$i18n.form.tasks.inactive_tasks}
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}
- - - - - -

-
-
- {/if} -{else} - - - - - - {if $active_tasks} - {foreach $active_tasks as $task} - - - - - {/foreach} - {/if} -
{$i18n.label.thing_name}{$i18n.label.description}
{$task.name|escape}{$task.description|escape}
- {/if} -
diff --git a/WEB-INF/templates/mobile/users.tpl b/WEB-INF/templates/mobile/users.tpl deleted file mode 100644 index eaeb4770f..000000000 --- a/WEB-INF/templates/mobile/users.tpl +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - -
-{if $user->can('manage_users')} - - {if $inactive_users} - - {/if} - {if $active_users} - - - - - - {foreach $active_users as $u} - - - - - - {/foreach} - {/if} -
{$i18n.label.active_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}
- {if $uncompleted_indicators} - - {/if} - {if $u.group_id != $user->group_id || $u.rank < $user->rank || ($u.rank == $user->rank && $u.id == $user->id)} - {$u.name|escape} - {else} - {$u.name|escape} - {/if} - {$u.login|escape}{$u.role_name|escape}
- - - - - -

-
-
- - {if $inactive_users} - - - - - - - - {foreach $inactive_users as $u} - - - - - - {/foreach} -
{$i18n.label.inactive_users}
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}
- {if $u.group_id != $user->group_id || $u.rank < $user->rank} - {$u.name|escape} - {else} - {$u.name|escape} - {/if} - {$u.login|escape}{$u.role_name|escape}
- - - - - -
-
-
- {/if} -{else} - - - - - - - {foreach $active_users as $u} - - - - - - {/foreach} -
{$i18n.label.person_name}{$i18n.label.login}{$i18n.form.users.role}
{$u.name|escape}{$u.login|escape}{$u.role_name|escape}
-{/if} -
diff --git a/initialize.php b/initialize.php index fca2f15a5..cbdfb3cc1 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5429"); +define("APP_VERSION", "1.19.26.5430"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/mobile/expenses.php b/mobile/expenses.php deleted file mode 100644 index 4f3b097fd..000000000 --- a/mobile/expenses.php +++ /dev/null @@ -1,235 +0,0 @@ -isPluginEnabled('ex')) { - header('Location: feature_disabled.php'); - exit(); -} -if (!$user->exists()) { - header('Location: access_denied.php'); // Nobody to enter expenses for. - exit(); -} -if ($user->behalf_id && (!$user->can('track_expenses') || !$user->checkBehalfId())) { - header('Location: access_denied.php'); // Trying on behalf, but no right or wrong user. - exit(); -} -if (!$user->behalf_id && !$user->can('track_own_expenses') && !$user->adjustBehalfId()) { - header('Location: access_denied.php'); // Trying as self, but no right for self, and noone to work on behalf. - exit(); -} -if ($request->isPost() && $request->getParameter('user')) { - if (!$user->isUserValid((int)$request->getParameter('user'))) { - header('Location: access_denied.php'); // Wrong user id on post. - exit(); - } -} -// End of access checks. - -// Determine user for which we display this page. -$userChanged = $request->getParameter('user_changed'); -if ($request->isPost() && $userChanged) { - $user_id = $request->getParameter('user'); - $user->setOnBehalfUser($user_id); -} else { - $user_id = $user->getUser(); -} - -// Initialize and store date in session. -$cl_date = $request->getParameter('date', @$_SESSION['date']); -$selected_date = new DateAndTime(DB_DATEFORMAT, $cl_date); -if($selected_date->isError()) - $selected_date = new DateAndTime(DB_DATEFORMAT); -if(!$cl_date) - $cl_date = $selected_date->toString(DB_DATEFORMAT); -$_SESSION['date'] = $cl_date; - -// Determine previous and next dates for simple navigation. -$prev_date = date('Y-m-d', strtotime('-1 day', strtotime($cl_date))); -$next_date = date('Y-m-d', strtotime('+1 day', strtotime($cl_date))); - -$tracking_mode = $user->getTrackingMode(); -$show_project = MODE_PROJECTS == $tracking_mode || MODE_PROJECTS_AND_TASKS == $tracking_mode; - -// Initialize variables. -$cl_client = $request->getParameter('client', ($request->isPost() ? null : @$_SESSION['client'])); -$_SESSION['client'] = $cl_client; -$cl_project = $request->getParameter('project', ($request->isPost() ? null : @$_SESSION['project'])); -$_SESSION['project'] = $cl_project; -$cl_item_name = $request->getParameter('item_name'); -$cl_cost = $request->getParameter('cost'); - -// Elements of expensesForm. -$form = new Form('expensesForm'); - -if ($user->can('track_expenses')) { - $rank = $user->getMaxRankForGroup($user->getGroup()); - if ($user->can('track_own_expenses')) - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_self'=>true,'self_first'=>true); - else - $options = array('status'=>ACTIVE,'max_rank'=>$rank); - $user_list = $user->getUsers($options); - if (count($user_list) >= 1) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'this.form.user_changed.value=1;this.form.submit();', - 'name'=>'user', - 'style'=>'width: 250px;', - 'value'=>$user_id, - 'data'=>$user_list, - 'datakeys'=>array('id','name'))); - $form->addInput(array('type'=>'hidden','name'=>'user_changed')); - $smarty->assign('user_dropdown', 1); - } -} - -// Dropdown for clients in MODE_TIME. Use all active clients. -if (MODE_TIME == $tracking_mode && $user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$active_clients, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - // Note: in other modes the client list is filtered to relevant clients only. See below. -} - -if ($show_project) { - // Dropdown for projects assigned to user. - $project_list = $user->getAssignedProjects(); - $form->addInput(array('type'=>'combobox', - // 'onchange'=>'fillTaskDropdown(this.value);', - 'name'=>'project', - 'style'=>'width: 250px;', - 'value'=>$cl_project, - 'data'=>$project_list, - 'datakeys'=>array('id','name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - - // Dropdown for clients if the clients plugin is enabled. - if ($user->isPluginEnabled('cl')) { - $active_clients = ttGroupHelper::getActiveClients(true); - // We need an array of assigned project ids to do some trimming. - foreach($project_list as $project) - $projects_assigned_to_user[] = $project['id']; - - // Build a client list out of active clients. Use only clients that are relevant to user. - // Also trim their associated project list to only assigned projects (to user). - foreach($active_clients as $client) { - $projects_assigned_to_client = explode(',', $client['projects']); - $intersection = array_intersect($projects_assigned_to_client, $projects_assigned_to_user); - if ($intersection) { - $client['projects'] = implode(',', $intersection); - $client_list[] = $client; - } - } - $form->addInput(array('type'=>'combobox', - 'onchange'=>'fillProjectDropdown(this.value);', - 'name'=>'client', - 'style'=>'width: 250px;', - 'value'=>$cl_client, - 'data'=>$client_list, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - } -} -// If predefined expenses are configured, add controls to select an expense and quantity. -$predefined_expenses = ttGroupHelper::getPredefinedExpenses(); -if ($predefined_expenses) { - $form->addInput(array('type'=>'combobox', - 'onchange'=>'recalculateCost();', - 'name'=>'predefined_expense', - 'style'=>'width: 250px;', - 'value'=>$cl_predefined_expense, - 'data'=>$predefined_expenses, - 'datakeys'=>array('id', 'name'), - 'empty'=>array(''=>$i18n->get('dropdown.select')))); - $form->addInput(array('type'=>'text','onchange'=>'recalculateCost();','maxlength'=>'40','name'=>'quantity','style'=>'width: 100px;','value'=>$cl_quantity)); -} -$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'item_name','style'=>'width: 250px;','value'=>$cl_item_name)); -$form->addInput(array('type'=>'text','maxlength'=>'40','name'=>'cost','style'=>'width: 100px;','value'=>$cl_cost)); -$form->addInput(array('type'=>'calendar','name'=>'date','highlight'=>'expenses','value'=>$cl_date)); // calendar -$form->addInput(array('type'=>'hidden','name'=>'browser_today','value'=>'')); // User current date, which gets filled in on btn_submit click. -$form->addInput(array('type'=>'submit','name'=>'btn_submit','onclick'=>'browser_today.value=get_date()','value'=>$i18n->get('button.submit'))); - -// Submit. -if ($request->isPost()) { - if ($request->getParameter('btn_submit')) { - // Validate user input. - if ($user->isPluginEnabled('cl') && $user->isOptionEnabled('client_required') && !$cl_client) - $err->add($i18n->get('error.client')); - if ($show_project && !$cl_project) - $err->add($i18n->get('error.project')); - if (!ttValidString($cl_item_name)) $err->add($i18n->get('error.field'), $i18n->get('label.item')); - if (!ttValidFloat($cl_cost)) $err->add($i18n->get('error.field'), $i18n->get('label.cost')); - - // Prohibit creating entries in future. - if (!$user->isOptionEnabled('future_entries')) { - $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); - if ($selected_date->after($browser_today)) - $err->add($i18n->get('error.future_date')); - } - if (!ttTimeHelper::canAdd()) $err->add($i18n->get('error.expired')); - // Finished validating input data. - - // Prohibit creating entries in locked range. - if ($user->isDateLocked($selected_date)) - $err->add($i18n->get('error.range_locked')); - - // Insert record. - if ($err->no()) { - if (ttExpenseHelper::insert(array('date'=>$cl_date,'client_id'=>$cl_client, - 'project_id'=>$cl_project,'name'=>$cl_item_name,'cost'=>$cl_cost,'status'=>1))) { - header('Location: expenses.php'); - exit(); - } else - $err->add($i18n->get('error.db')); - } - } elseif ($request->getParameter('onBehalfUser')) { - if($user->can('track_expenses')) { - unset($_SESSION['behalf_id']); - unset($_SESSION['behalf_name']); - - if($on_behalf_id != $user->id) { - $_SESSION['behalf_id'] = $on_behalf_id; - $_SESSION['behalf_name'] = ttUserHelper::getUserName($on_behalf_id); - } - header('Location: expenses.php'); - exit(); - } - } -} - -$smarty->assign('forms', array($form->getName()=>$form->toArray())); -$smarty->assign('show_project', $show_project); -$smarty->assign('next_date', $next_date); -$smarty->assign('prev_date', $prev_date); -$smarty->assign('day_total', ttExpenseHelper::getTotalForDay($cl_date)); -$smarty->assign('expense_items', ttExpenseHelper::getItems($cl_date)); -$smarty->assign('predefined_expenses', $predefined_expenses); -$smarty->assign('client_list', $client_list); -$smarty->assign('project_list', $project_list); -$smarty->assign('timestring', $selected_date->toString($user->getDateFormat())); -$smarty->assign('title', $i18n->get('title.expenses')); -$smarty->assign('content_page_name', 'mobile/expenses.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/projects.php b/mobile/projects.php deleted file mode 100644 index c234d984d..000000000 --- a/mobile/projects.php +++ /dev/null @@ -1,36 +0,0 @@ -getTrackingMode() && MODE_PROJECTS_AND_TASKS != $user->getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -if($user->can('manage_projects')) { - $active_projects = ttGroupHelper::getActiveProjects(); - $inactive_projects = ttGroupHelper::getInactiveProjects(); -} else - $active_projects = $user->getAssignedProjects(); - -$smarty->assign('active_projects', $active_projects); -$smarty->assign('inactive_projects', $inactive_projects); -$smarty->assign('title', $i18n->get('title.projects')); -$smarty->assign('content_page_name', 'mobile/projects.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/tasks.php b/mobile/tasks.php deleted file mode 100644 index 98530477d..000000000 --- a/mobile/tasks.php +++ /dev/null @@ -1,35 +0,0 @@ -getTrackingMode()) { - header('Location: feature_disabled.php'); - exit(); -} -// End of access checks. - -if($user->can('manage_tasks')) { - $active_tasks = ttGroupHelper::getActiveTasks(); - $inactive_tasks = ttGroupHelper::getInactiveTasks(); -} else - $active_tasks = $user->getAssignedTasks(); - -$smarty->assign('active_tasks', $active_tasks); -$smarty->assign('inactive_tasks', $inactive_tasks); -$smarty->assign('title', $i18n->get('title.tasks')); -$smarty->assign('content_page_name', 'mobile/tasks.tpl'); -$smarty->display('mobile/index.tpl'); diff --git a/mobile/users.php b/mobile/users.php deleted file mode 100644 index 45be3fcdc..000000000 --- a/mobile/users.php +++ /dev/null @@ -1,51 +0,0 @@ -getMaxRankForGroup($user->getGroup()); -if ($user->can('view_users')) - $options = array('status'=>ACTIVE,'include_clients'=>true,'include_login'=>true,'include_role'=>true); -else /* if ($user->can('manage_users')) */ - $options = array('status'=>ACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_self'=>true,'include_login'=>true,'include_role'=>true); -$active_users = $user->getUsers($options); - -// Prepare a list of inactive users. -if($user->can('manage_users')) { - $options = array('status'=>INACTIVE,'max_rank'=>$rank,'include_clients'=>true,'include_login'=>true,'include_role'=>true); - $inactive_users = $user->getUsers($options); -} - -$uncompleted_indicators = $user->getConfigOption('uncompleted_indicators'); -if ($uncompleted_indicators) { - // Check each active user if they have an uncompleted time entry. - foreach ($active_users as $key => $active_user) { - $active_users[$key]['has_uncompleted_entry'] = (bool) ttTimeHelper::getUncompleted($active_user['id']); - } - $smarty->assign('uncompleted_indicators', true); -} - -$smarty->assign('active_users', $active_users); -$smarty->assign('inactive_users', $inactive_users); -$smarty->assign('can_delete_manager', $can_delete_manager); -$smarty->assign('title', $i18n->get('title.users')); -$smarty->assign('content_page_name', 'mobile/users.tpl'); -$smarty->display('mobile/index.tpl'); From e77be7eea69df5d52e19f9f25b5b89a0e66a5b8e Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Sun, 11 Apr 2021 21:57:58 +0000 Subject: [PATCH 245/652] An attempt to mitigate cross site request forgery vulnerability. --- WEB-INF/config.php.dist | 5 +++++ WEB-INF/lib/common.lib.php | 39 ++++++++++++++++++++++++++++++++++++++ initialize.php | 2 +- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 7b6eabbd2..1b7b32b0a 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -163,6 +163,11 @@ define('AUTH_MODULE', 'db'); // define('DEBUG', false); // Note: enabling DEBUG breaks redirects as debug output is printed before setting redirect header. Do not enable on production systems. +// HTTP_TARGET - defines http target for cross site request forgery protection. +// It can be used when you access the application via a proxy. +// define('HTTP_TARGET', 'localhost'); + + // Group managers can set monthly work hour quota for years between the following values. // define('MONTHLY_QUOTA_YEAR_START', 2010); // If nothing is specified, it falls back to 2015. // define('MONTHLY_QUOTA_YEAR_END', 2025); // If nothing is specified, it falls back to 2030. diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 389b29c94..52589c6e0 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -363,6 +363,10 @@ function ttAccessAllowed($required_right) exit(); } + // Protection against cross site request forgery. + if (!ttMitigateCSRF()) + return false; + // Check IP restriction, if set. if ($user->allow_ip && !$user->can('override_allow_ip')) { $access_allowed = false; @@ -388,6 +392,41 @@ function ttAccessAllowed($required_right) return false; } +// ttMitigateCSRF verifies request headers in an attempt to block cross site request forgery. +function ttMitigateCSRF() { + // No need to do anything for get requests. + global $request; + if ($request->isGet()) + return true; + + $origin = $_SERVER['HTTP_ORIGIN']; + if ($origin) { + $pos = strpos($origin, '//'); + $origin = substr($origin, $pos+2); // Strip protocol. + } + if (!$origin) { + // Try using referer. + $origin = $_SERVER['HTTP_REFERER']; + if ($origin) { + $pos = strpos($origin, '//'); + $origin = substr($origin, $pos+2); // Strip protocol. + $pos = strpos($origin, '/'); + $origin = substr($origin, 0, $pos); // Leave host only. + } + } + error_log("origin: ".$origin); + $target = defined('HTTP_TARGET') ? HTTP_TARGET : $_SERVER['HTTP_HOST']; + error_log("target: ".$target); + if (strcmp($origin, $target)) { + error_log("Potential cross site request forgery. Origin: '$origin' does not match target: '$target'."); + return false; // Origin and target do not match, + } + + // TODO: review and improve this function for custom ports. + return true; +} + + // ttStartsWith functions checks if a string starts with a given substring. function ttStartsWith($string, $startString) { diff --git a/initialize.php b/initialize.php index cbdfb3cc1..aadc0bb07 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.26.5430"); +define("APP_VERSION", "1.19.27.5431"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From e3f8222ee308322942bcebcd86b78ecf19382563 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 12 Apr 2021 17:14:30 +0000 Subject: [PATCH 246/652] Tested CSRF fix for custom ports - it's working, also removed unnecessary logging. --- WEB-INF/config.php.dist | 2 +- WEB-INF/lib/common.lib.php | 5 +---- initialize.php | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 1b7b32b0a..3787cbc94 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -165,7 +165,7 @@ define('AUTH_MODULE', 'db'); // HTTP_TARGET - defines http target for cross site request forgery protection. // It can be used when you access the application via a proxy. -// define('HTTP_TARGET', 'localhost'); +// define('HTTP_TARGET', 'localhost:8080'); // Group managers can set monthly work hour quota for years between the following values. diff --git a/WEB-INF/lib/common.lib.php b/WEB-INF/lib/common.lib.php index 52589c6e0..d5b43f57f 100644 --- a/WEB-INF/lib/common.lib.php +++ b/WEB-INF/lib/common.lib.php @@ -414,15 +414,12 @@ function ttMitigateCSRF() { $origin = substr($origin, 0, $pos); // Leave host only. } } - error_log("origin: ".$origin); $target = defined('HTTP_TARGET') ? HTTP_TARGET : $_SERVER['HTTP_HOST']; - error_log("target: ".$target); if (strcmp($origin, $target)) { error_log("Potential cross site request forgery. Origin: '$origin' does not match target: '$target'."); - return false; // Origin and target do not match, + return false; // Origin and target do not match. } - // TODO: review and improve this function for custom ports. return true; } diff --git a/initialize.php b/initialize.php index aadc0bb07..e8588857f 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.27.5431"); +define("APP_VERSION", "1.19.27.5432"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From ee6312e1a278cfbb240ae1419d6c63eeff0913f6 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Tue, 13 Apr 2021 22:12:35 +0000 Subject: [PATCH 247/652] Added options for secure ldap authentication. --- WEB-INF/config.php.dist | 4 ++++ WEB-INF/lib/auth/Auth_ldap.class.php | 10 ++++++++++ initialize.php | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/WEB-INF/config.php.dist b/WEB-INF/config.php.dist index 3787cbc94..bbf647cec 100644 --- a/WEB-INF/config.php.dist +++ b/WEB-INF/config.php.dist @@ -144,6 +144,8 @@ define('AUTH_MODULE', 'db'); // 'base_dn' => 'ou=People,dc=example,dc=com', // Path of user's base distinguished name in LDAP catalog. // 'user_login_attribute' => 'uid', // LDAP attribute used for login. // 'default_domain' => 'example.com', // Default domain. +// 'tls_cacertdir' => null, // Path to a directory containing CA certificates for secure ldap. +// 'tls_cacertfile' => null, // CA certificate file name for secure ldap. // 'member_of' => array()); // List of groups, membership in which is required for user to be authenticated. @@ -154,6 +156,8 @@ define('AUTH_MODULE', 'db'); // 'type' => 'ad', // Type of server. // 'base_dn' => 'DC=example,DC=com', // Base distinguished name in LDAP catalog. // 'default_domain' => 'example.com', // Default domain. +// 'tls_cacertdir' => null, // Path to a directory containing CA certificates for secure ldap. +// 'tls_cacertfile' => null, // CA certificate file name for secure ldap. // 'member_of' => array()); // List of groups, membership in which is required for user to be authenticated. // Leave it empty if membership is not necessary. Otherwise list CN parts only. // For example: diff --git a/WEB-INF/lib/auth/Auth_ldap.class.php b/WEB-INF/lib/auth/Auth_ldap.class.php index 7f3495737..1ccbb0371 100644 --- a/WEB-INF/lib/auth/Auth_ldap.class.php +++ b/WEB-INF/lib/auth/Auth_ldap.class.php @@ -105,6 +105,16 @@ function authenticate($login, $password) if (isTrue('DEBUG')) { ldap_set_option($lc, LDAP_OPT_DEBUG_LEVEL, 7); } + // Additional options for secure ldap. + // This insert is based on https://www.anuko.com/forum/viewtopic.php?f=4&t=2091 + // I can't test it at the moment. If things break please let us know! + if (isset($this->params['tls_cacertdir'])) { + ldap_set_option(null, LDAP_OPT_X_TLS_CACERTDIR, $this->params['tls_cacertdir']); + } + if (isset($this->params['tls_cacertfile'])) { + ldap_set_option(null, LDAP_OPT_X_TLS_CACERTFILE, $this->params['tls_cacertfile']); + } + // End of addiitional options for secure ldap. // We need to handle Windows AD and OpenLDAP differently. if ($this->params['type'] == 'ad') { diff --git a/initialize.php b/initialize.php index e8588857f..a739b939e 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.27.5432"); +define("APP_VERSION", "1.19.28.5433"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); From 4fdaa18d343d0459391e62b40971843fbd0e5924 Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Apr 2021 21:26:18 +0000 Subject: [PATCH 248/652] Resuming work on php8 warnings. --- WEB-INF/lib/ttTimeHelper.class.php | 2 ++ WEB-INF/templates/header2.tpl | 2 +- WEB-INF/templates/time2.tpl | 2 +- WEB-INF/templates/time_script.tpl | 16 +++++++++------- initialize.php | 2 +- time.php | 1 + 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index f0b1ea100..af2a436a5 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -895,6 +895,8 @@ static function getRecords($date, $includeFiles = false) { $time_fields = ", ".join(', ', $time_fields_array); } + $filePart = ''; + $fileJoin = ''; if ($includeFiles) { $filePart = ', if(Sub1.entity_id is null, 0, 1) as has_files'; $fileJoin = " left join (select distinct entity_id from tt_files". diff --git a/WEB-INF/templates/header2.tpl b/WEB-INF/templates/header2.tpl index 6bc5f65fe..74ccb1adc 100644 --- a/WEB-INF/templates/header2.tpl +++ b/WEB-INF/templates/header2.tpl @@ -6,7 +6,7 @@ -{if $i18n.language.rtl} +{if (isset($i18n.language.rtl) && $i18n.language.rtl)} {/if} {if $user->getCustomCss()} diff --git a/WEB-INF/templates/time2.tpl b/WEB-INF/templates/time2.tpl index 487bff7cf..4a26f9bef 100644 --- a/WEB-INF/templates/time2.tpl +++ b/WEB-INF/templates/time2.tpl @@ -93,7 +93,7 @@ License: See license.txt *}
{/if} -{if $template_dropdown} +{if (isset($template_dropdown) && $template_dropdown)} diff --git a/WEB-INF/templates/time_script.tpl b/WEB-INF/templates/time_script.tpl index 5834ba3cc..67c5062cc 100644 --- a/WEB-INF/templates/time_script.tpl +++ b/WEB-INF/templates/time_script.tpl @@ -46,23 +46,25 @@ var task_names = new Array(); // Prepare an array of template ids for projects. var template_ids = new Array(); -{if $bind_templates_with_projects} +{if (isset($bind_templates_with_projects) && $bind_templates_with_projects)} {foreach $project_list as $project} template_ids[{$project.id}] = "{$project.templates}"; {/foreach} {/if} // Prepare an array of template names. var template_names = new Array(); -{if $bind_templates_with_projects} +{if (isset($bind_templates_with_projects) && $bind_templates_with_projects) && isset($template_list)} {foreach $template_list as $template} template_names[{$template.id}] = "{$template.name|escape:'javascript'}"; {/foreach} {/if} // Prepare an array of template bodies. var template_bodies = new Array(); -{foreach $template_list as $template} - template_bodies[{$template.id}] = "{$template.content|escape:'javascript'}"; -{/foreach} +{if isset($template_list)} + {foreach $template_list as $template} + template_bodies[{$template.id}] = "{$template.content|escape:'javascript'}"; + {/foreach} +{/if} // The fillNote function populates the Note field with a selected template body. function fillNote(id) { @@ -189,7 +191,7 @@ function fillTaskDropdown(id) { // The fillTemplateDropdown function populates the template combo box with // templates associated with a selected project (project id is passed here as id). function fillTemplateDropdown(id) { -{if !$bind_templates_with_projects} +{if (!isset($bind_templates_with_projects) || !$bind_templates_with_projects)} return; // Do nothing if we are not binding templates with projects, {/if} @@ -234,7 +236,7 @@ function fillTemplateDropdown(id) { // The prepopulateNote function populates the note field with first found template body in Template dropdown. function prepopulateNote() { - {if !$prepopulate_note} + {if (!isset($prepopulate_note) || !$prepopulate_note)} return; {/if} var dropdown = document.getElementById("template"); diff --git a/initialize.php b/initialize.php index a739b939e..d34aa56d5 100644 --- a/initialize.php +++ b/initialize.php @@ -13,7 +13,7 @@ ini_set('display_errors', 'Off'); // require_once('init_auth.php'); -define("APP_VERSION", "1.19.28.5433"); +define("APP_VERSION", "1.19.28.5434"); define("APP_DIR", dirname(__FILE__)); define("LIBRARY_DIR", APP_DIR."/WEB-INF/lib"); define("TEMPLATE_DIR", APP_DIR."/WEB-INF/templates"); diff --git a/time.php b/time.php index 66cf4da4b..90d54c0cf 100644 --- a/time.php +++ b/time.php @@ -225,6 +225,7 @@ $largeScreenCalendarRowSpan += 2; // Client dropdown. + $client_list = array(); if ($showClient) { $active_clients = ttGroupHelper::getActiveClients(true); // We need an array of assigned project ids to do some trimming. From 1ce02deaaa3f2c66162a55fe0b62acb1dd94739a Mon Sep 17 00:00:00 2001 From: Nik Okuntseff Date: Mon, 19 Apr 2021 22:11:54 +0000 Subject: [PATCH 249/652] Addressed a few more php8 warnings. --- WEB-INF/lib/ttTimeHelper.class.php | 4 ++-- WEB-INF/templates/header2.tpl | 8 ++++---- WEB-INF/templates/time_edit2.tpl | 2 +- initialize.php | 2 +- time_edit.php | 2 ++ 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index af2a436a5..78e7a2cf5 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -424,10 +424,10 @@ static function insert($fields) $client = $fields['client']; $project = $fields['project']; $task = $fields['task']; - $invoice = $fields['invoice']; + $invoice = isset($fields['invoice']) ? $fields['invoice'] : null; $note = $fields['note']; $billable = $fields['billable']; - $paid = $fields['paid']; + $paid = isset($fields['paid']) ? $fields['paid'] : null; $start = ttTimeHelper::to24HourFormat($start); if ($finish) { diff --git a/WEB-INF/templates/header2.tpl b/WEB-INF/templates/header2.tpl index 74ccb1adc..65af554ee 100644 --- a/WEB-INF/templates/header2.tpl +++ b/WEB-INF/templates/header2.tpl @@ -21,7 +21,7 @@ - +