From 8ecf916786c15d7bbe18bbb512b183c622be0bb4 Mon Sep 17 00:00:00 2001 From: anuko Date: Sun, 24 Dec 2017 16:03:25 +0000 Subject: [PATCH] More work in progress on week view. --- WEB-INF/lib/ttTimeHelper.class.php | 85 ++++++ WEB-INF/templates/week.tpl | 99 +++++++ time.php | 6 +- week.php | 397 +++++++++++++++++++++++++++++ 4 files changed, 584 insertions(+), 3 deletions(-) create mode 100644 WEB-INF/templates/week.tpl create mode 100644 week.php diff --git a/WEB-INF/lib/ttTimeHelper.class.php b/WEB-INF/lib/ttTimeHelper.class.php index 02faa216..ec05537f 100644 --- a/WEB-INF/lib/ttTimeHelper.class.php +++ b/WEB-INF/lib/ttTimeHelper.class.php @@ -677,4 +677,89 @@ class ttTimeHelper { return $result; } + // getRecordsForInterval - returns time records for a user for a given interval of dates. + static function getRecordsForInterval($user_id, $start_date, $end_date) { + global $user; + $sql_time_format = "'%k:%i'"; // 24 hour format. + if ('%I:%M %p' == $user->time_format) + $sql_time_format = "'%h:%i %p'"; // 12 hour format for MySQL TIME_FORMAT function. + + $result = array(); + $mdb2 = getConnection(); + + $client_field = null; + if ($user->isPluginEnabled('cl')) + $client_field = ", c.id as client_id, c.name as client"; + + $left_joins = " left join tt_projects p on (l.project_id = p.id)". + " left join tt_tasks t on (l.task_id = t.id)"; + if ($user->isPluginEnabled('cl')) + $left_joins .= " left join tt_clients c on (l.client_id = c.id)"; + + $sql = "select l.id as id, l.date as date, TIME_FORMAT(l.start, $sql_time_format) as start, + TIME_FORMAT(sec_to_time(time_to_sec(l.start) + time_to_sec(l.duration)), $sql_time_format) as finish, + TIME_FORMAT(l.duration, '%k:%i') as duration, p.id as project_id, p.name as project, + t.id as task_id, t.name as task, l.comment, l.billable, l.invoice_id $client_field + from tt_log l + $left_joins + where l.date >= '$start_date' and l.date <= '$end_date' and l.user_id = $user_id and l.status = 1 + order by p.name, t.name, l.date, l.start, l.id"; + $res = $mdb2->query($sql); + if (!is_a($res, 'PEAR_Error')) { + while ($val = $res->fetchRow()) { + if($val['duration']=='0:00') + $val['finish'] = ''; + $result[] = $val; + } + } else return false; + + return $result; + } + + // getGroupedRecordsForInterval - returns time records for a user for a given interval of dates grouped in an array of dates. + // Example: for a week view we want one row representing the same attributes to have 7 values for each day of week. + // We identify simlar records by a combination of client, billable, project, task, and custom field values. + // + // "cl:546,bl:0,pr:23456,ts:27464,cf_1:example text" + // The above means client 546, billable, project 23456, task 27464, custom field value: example text. + // + // "cl:546,bl:1,pr:23456,ts:27464,cf_1:7623" + // The above means client 546, not billable, project 23456, task 27464, custom field option value 7623. + // This will allow us to extend the feature when more custom fields are added. + static function getGroupedRecordsForInterval($user_id, $start_date, $end_date) { + // Start by obtaining all records in interval. + // Then, iterate through them to build an array. + $records = ttTimeHelper::getRecordsForInterval($user_id, $start_date, $end_date); + foreach ($records as $record) { + $record_identifier = ttTimeHelper::makeRecordIdentifier($record); + } + + return null; // Work in progress, not implemented. + } + + // makeRecordIdentifier - builds a string identifying a record for a grouped display (such as a week view). + // For example: + // "cl:546,bl:0,pr:23456,ts:27464,cf_1:example text" + // "cl:546,bl:1,pr:23456,ts:27464,cf_1:7623" + // See comment for getGroupedRecordsForInterval. + static function makeRecordIdentifier($record) { + global $user; + // Start with client. + if ($user->isPluginEnabled('cl')) { + $record_identifier = 'cl:'; + $record_identifier .= $record['client_id'] ? $record['client_id'] : '0'; + } + // Add billable flag. + if (!empty($record_identifier)) $record_identifier .= ','; + $record_identifier .= 'bl:'.$record['billable']; + // Add project. + $record_identifier .= ',pr:'; + $record_identifier .= $record['project_id'] ? $record['project_id'] : '0'; + // Add task. + $record_identifier .= ',ts:'; + $record_identifier .= $record['task_id'] ? $record['task_id'] : '0'; + // Add custom field 1. This requires modifying the query to get the data we need. + + return $record_identifier; + } } diff --git a/WEB-INF/templates/week.tpl b/WEB-INF/templates/week.tpl new file mode 100644 index 00000000..fff4bfa4 --- /dev/null +++ b/WEB-INF/templates/week.tpl @@ -0,0 +1,99 @@ +{include file="time_script.tpl"} + + + +{$forms.timeRecordForm.open} + +{if defined(WEEK_VIEW_DEBUG)} + + + +{/if} + + + + +
+ {$i18n.label.day_view} / {$i18n.label.week_view} +
+ +{if $on_behalf_control} + + + + +{/if} +
{$i18n.label.user}:{$forms.timeRecordForm.onBehalfUser.control}
+
+ + +
{$forms.timeRecordForm.date.control}
+
+ + + + + +
+{if $time_records} + + + {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + + {/if} + {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + + {/if} + + + + + + + + + {foreach $time_records as $record} + + {if ($smarty.const.MODE_PROJECTS == $user->tracking_mode || $smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + + {/if} + {if ($smarty.const.MODE_PROJECTS_AND_TASKS == $user->tracking_mode)} + + {/if} + + + + {/foreach} +
{$i18n.label.project}{$i18n.label.task}{$day_header_0}{$day_header_1}{$day_header_2}{$day_header_3}{$day_header_4}{$day_header_5}{$day_header_6}
{$record.project|escape}{$record.task|escape}{$record.date}{if ($record.duration == '0:00' && $record.start <> '')}{$i18n.form.time.uncompleted}{else}{$record.duration}{/if}
+{/if} +
+ + + + + +
{$forms.timeRecordForm.btn_submit.control}
+{$forms.timeRecordForm.close} diff --git a/time.php b/time.php index fe3a8e3d..c001f21f 100644 --- a/time.php +++ b/time.php @@ -88,7 +88,7 @@ if ($user->isPluginEnabled('iv')) { if ($request->isPost()) { $cl_billable = $request->getParameter('billable'); $_SESSION['billable'] = (int) $cl_billable; - } else + } else if (isset($_SESSION['billable'])) $cl_billable = $_SESSION['billable']; } @@ -146,7 +146,7 @@ if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->t // Dropdown for clients if the clients plugin is enabled. if ($user->isPluginEnabled('cl')) { $active_clients = ttTeamHelper::getActiveClients($user->team_id, true); - // We need an array of assigned project ids to do some trimming. + // We need an array of assigned project ids to do some trimming. foreach($project_list as $project) $projects_assigned_to_user[] = $project['id']; @@ -196,7 +196,7 @@ if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); if (!defined('NOTE_INPUT_HEIGHT')) - define('NOTE_INPUT_HEIGHT', 40); + define('NOTE_INPUT_HEIGHT', 40); $form->addInput(array('type'=>'textarea','name'=>'note','style'=>'width: 600px; height:'.NOTE_INPUT_HEIGHT.'px;','value'=>$cl_note)); $form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar if ($user->isPluginEnabled('iv')) diff --git a/week.php b/week.php new file mode 100644 index 00000000..c2e85161 --- /dev/null +++ b/week.php @@ -0,0 +1,397 @@ +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($user->team_id); + $smarty->assign('custom_fields', $custom_fields); +} + +// TODO: how is this plugin supposed to work for week view? +if ($user->isPluginEnabled('mq')){ + require_once('plugins/MonthlyQuota.class.php'); + $quota = new MonthlyQuota(); + $month_quota = $quota->get($selected_date->mYear, $selected_date->mMonth); + $month_total = ttTimeHelper::getTimeForMonth($user->getActiveUser(), $selected_date); + $minutes_left = ttTimeHelper::toMinutes($month_quota) - ttTimeHelper::toMinutes($month_total); + + $smarty->assign('month_total', $month_total); + $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')); +// Custom field. +$cl_cf_1 = trim($request->getParameter('cf_1', ($request->getMethod()=='POST'? null : @$_SESSION['cf_1']))); +$_SESSION['cf_1'] = $cl_cf_1; +$cl_billable = 1; +if ($user->isPluginEnabled('iv')) { + if ($request->isPost()) { + $cl_billable = $request->getParameter('billable'); + $_SESSION['billable'] = (int) $cl_billable; + } else + if (isset($_SESSION['billable'])) + $cl_billable = $_SESSION['billable']; +} +$on_behalf_id = $request->getParameter('onBehalfUser', (isset($_SESSION['behalf_id'])? $_SESSION['behalf_id'] : $user->id)); +$cl_client = $request->getParameter('client', ($request->getMethod()=='POST'? null : @$_SESSION['client'])); +$_SESSION['client'] = $cl_client; +$cl_project = $request->getParameter('project', ($request->getMethod()=='POST'? null : @$_SESSION['project'])); +$_SESSION['project'] = $cl_project; +$cl_task = $request->getParameter('task', ($request->getMethod()=='POST'? null : @$_SESSION['task'])); +$_SESSION['task'] = $cl_task; + +// Elements of timeRecordForm. +$form = new Form('timeRecordForm'); + +if ($user->canManageTeam()) { + $user_list = ttTeamHelper::getActiveUsers(array('putSelfFirst'=>true)); + if (count($user_list) > 1) { + $form->addInput(array('type'=>'combobox', + 'onchange'=>'this.form.submit();', + 'name'=>'onBehalfUser', + 'style'=>'width: 250px;', + 'value'=>$on_behalf_id, + 'data'=>$user_list, + 'datakeys'=>array('id','name'))); + $smarty->assign('on_behalf_control', 1); + } +} + +// Dropdown for clients in MODE_TIME. Use all active clients. +if (MODE_TIME == $user->tracking_mode && $user->isPluginEnabled('cl')) { + $active_clients = ttTeamHelper::getActiveClients($user->team_id, 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->getKey('dropdown.select')))); + // Note: in other modes the client list is filtered to relevant clients only. See below. +} + +if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { + // 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->getKey('dropdown.select')))); + + // Dropdown for clients if the clients plugin is enabled. + if ($user->isPluginEnabled('cl')) { + $active_clients = ttTeamHelper::getActiveClients($user->team_id, 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->getKey('dropdown.select')))); + } +} + +if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { + $task_list = ttTeamHelper::getActiveTasks($user->team_id); + $form->addInput(array('type'=>'combobox', + 'name'=>'task', + 'style'=>'width: 250px;', + 'value'=>$cl_task, + 'data'=>$task_list, + 'datakeys'=>array('id','name'), + 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); +} + +// Add other controls. +if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { + $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->canManageTeam() && defined('READONLY_START_FINISH') && isTrue(READONLY_START_FINISH)) { + // Make the start and finish fields read-only. + $form->getElement('start')->setEnabled(false); + $form->getElement('finish')->setEnabled(false); + } +} +if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) + $form->addInput(array('type'=>'text','name'=>'duration','value'=>$cl_duration,'onchange'=>"formDisable('duration');")); +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)); +$form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar +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->getKey('button.submit'))); + +// If we have custom fields - add controls for them. +if ($custom_fields && $custom_fields->fields[0]) { + // Only one custom field is supported at this time. + if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) { + $form->addInput(array('type'=>'text','name'=>'cf_1','value'=>$cl_cf_1)); + } elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) { + $form->addInput(array('type'=>'combobox','name'=>'cf_1', + 'style'=>'width: 250px;', + 'value'=>$cl_cf_1, + 'data'=>$custom_fields->options, + 'empty'=>array(''=>$i18n->getKey('dropdown.select')))); + } +} + +// Submit. +if ($request->isPost()) { + if ($request->getParameter('btn_submit')) { + + // Validate user input. + if ($user->isPluginEnabled('cl') && $user->isPluginEnabled('cm') && !$cl_client) + $err->add($i18n->getKey('error.client')); + if ($custom_fields) { + if (!ttValidString($cl_cf_1, !$custom_fields->fields[0]['required'])) $err->add($i18n->getKey('error.field'), $custom_fields->fields[0]['label']); + } + if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode) { + if (!$cl_project) $err->add($i18n->getKey('error.project')); + } + if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode && $user->task_required) { + if (!$cl_task) $err->add($i18n->getKey('error.task')); + } + if (strlen($cl_duration) == 0) { + if ($cl_start || $cl_finish) { + if (!ttTimeHelper::isValidTime($cl_start)) + $err->add($i18n->getKey('error.field'), $i18n->getKey('label.start')); + if ($cl_finish) { + if (!ttTimeHelper::isValidTime($cl_finish)) + $err->add($i18n->getKey('error.field'), $i18n->getKey('label.finish')); + if (!ttTimeHelper::isValidInterval($cl_start, $cl_finish)) + $err->add($i18n->getKey('error.interval'), $i18n->getKey('label.finish'), $i18n->getKey('label.start')); + } + } else { + if ((TYPE_START_FINISH == $user->record_type) || (TYPE_ALL == $user->record_type)) { + $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.start')); + $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.finish')); + } + if ((TYPE_DURATION == $user->record_type) || (TYPE_ALL == $user->record_type)) + $err->add($i18n->getKey('error.empty'), $i18n->getKey('label.duration')); + } + } else { + if (!ttTimeHelper::isValidDuration($cl_duration)) + $err->add($i18n->getKey('error.field'), $i18n->getKey('label.duration')); + } + if (!ttValidString($cl_note, true)) $err->add($i18n->getKey('error.field'), $i18n->getKey('label.note')); + // Finished validating user input. + + // Prohibit creating entries in future. + if (defined('FUTURE_ENTRIES') && !isTrue(FUTURE_ENTRIES)) { + $browser_today = new DateAndTime(DB_DATEFORMAT, $request->getParameter('browser_today', null)); + if ($selected_date->after($browser_today)) + $err->add($i18n->getKey('error.future_date')); + } + + // Prohibit creating entries in locked range. + if ($user->isDateLocked($selected_date)) + $err->add($i18n->getKey('error.range_locked')); + + // Prohibit creating another uncompleted record. + if ($err->no()) { + if (($not_completed_rec = ttTimeHelper::getUncompleted($user->getActiveUser())) && (($cl_finish == '') && ($cl_duration == ''))) + $err->add($i18n->getKey('error.uncompleted_exists')." ".$i18n->getKey('error.goto_uncompleted').""); + } + + // Prohibit creating an overlapping record. + if ($err->no()) { + if (ttTimeHelper::overlaps($user->getActiveUser(), $cl_date, $cl_start, $cl_finish)) + $err->add($i18n->getKey('error.overlap')); + } + + // Insert record. + if ($err->no()) { + $id = ttTimeHelper::insert(array( + 'date' => $cl_date, + 'user_id' => $user->getActiveUser(), + '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 a custom field if we have it. + $result = true; + if ($id && $custom_fields && $cl_cf_1) { + if ($custom_fields->fields[0]['type'] == CustomFields::TYPE_TEXT) + $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], null, $cl_cf_1); + elseif ($custom_fields->fields[0]['type'] == CustomFields::TYPE_DROPDOWN) + $result = $custom_fields->insert($id, $custom_fields->fields[0]['id'], $cl_cf_1, null); + } + if ($id && $result) { + header('Location: time.php'); + exit(); + } + $err->add($i18n->getKey('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, $user->getActiveUser()); + $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->getActiveUser(), $browser_date, $record['start'], $browser_time)) { // no overlap + $res = ttTimeHelper::update(array( + 'id'=>$record['id'], + 'date'=>$record['date'], + 'user_id'=>$user->getActiveUser(), + '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->getKey('error.db')); + } else { + // Cannot complete, redirect for manual edit. + header('Location: time_edit.php?id='.$record_id); + exit(); + } + } + elseif ($request->getParameter('onBehalfUser')) { + if($user->canManageTeam()) { + 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: week.php'); + exit(); + } + } +} // isPost + +$week_total = ttTimeHelper::getTimeForWeek($user->getActiveUser(), $selected_date); + +// Determine selected week start and end dates. +$weekStartDay = $user->week_start; +$t_arr = localtime($selected_date->getTimestamp()); +$t_arr[5] = $t_arr[5] + 1900; +if ($t_arr[6] < $weekStartDay) + $startWeekBias = $weekStartDay - 7; +else + $startWeekBias = $weekStartDay; +$startDate = new DateAndTime(); +$startDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+$startWeekBias,$t_arr[5])); +$endDate = new DateAndTime(); +$endDate->setTimestamp(mktime(0,0,0,$t_arr[4]+1,$t_arr[3]-$t_arr[6]+6+$startWeekBias,$t_arr[5])); +// The above is needed to set date range (timestring) in page title. Consider refactoring, possibly moving into a function. + +$smarty->assign('selected_date', $selected_date); +$smarty->assign('week_total', $week_total); +$smarty->assign('day_total', ttTimeHelper::getTimeForDay($user->getActiveUser(), $cl_date)); +$smarty->assign('time_records', ttTimeHelper::getGroupedRecordsForInterval($user->getActiveUser(), $startDate->toString(DB_DATEFORMAT), $endDate->toString(DB_DATEFORMAT))); +$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('timestring', $startDate->toString($user->date_format).' - '.$endDate->toString($user->date_format)); + +// Prepare and assign date headers. Note how startDate moves to the end of the week, so it no longer holds correct start week value. +$smarty->assign('day_header_0', $startDate->toString($user->date_format)); +$startDate->incDay(); +$smarty->assign('day_header_1', $startDate->toString($user->date_format)); +$startDate->incDay(); +$smarty->assign('day_header_2', $startDate->toString($user->date_format)); +$startDate->incDay(); +$smarty->assign('day_header_3', $startDate->toString($user->date_format)); +$startDate->incDay(); +$smarty->assign('day_header_4', $startDate->toString($user->date_format)); +$startDate->incDay(); +$smarty->assign('day_header_5', $startDate->toString($user->date_format)); +$startDate->incDay(); +$smarty->assign('day_header_6', $startDate->toString($user->date_format)); + +$smarty->assign('title', $i18n->getKey('title.time')); +$smarty->assign('content_page_name', 'week.tpl'); +$smarty->display('index.tpl'); -- 2.20.1