Skip to content

Commit 098a79f

Browse files
committed
Work in progress creating a repo
Added files in root dir, subdirectories remain...
1 parent 251996a commit 098a79f

55 files changed

Lines changed: 7231 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

charts.php

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
<?php
2+
// +----------------------------------------------------------------------+
3+
// | Anuko Time Tracker
4+
// +----------------------------------------------------------------------+
5+
// | Copyright (c) Anuko International Ltd. (https://www.anuko.com)
6+
// +----------------------------------------------------------------------+
7+
// | LIBERAL FREEWARE LICENSE: This source code document may be used
8+
// | by anyone for any purpose, and freely redistributed alone or in
9+
// | combination with other software, provided that the license is obeyed.
10+
// |
11+
// | There are only two ways to violate the license:
12+
// |
13+
// | 1. To redistribute this code in source form, with the copyright
14+
// | notice or license removed or altered. (Distributing in compiled
15+
// | forms without embedded copyright notices is permitted).
16+
// |
17+
// | 2. To redistribute modified versions of this code in *any* form
18+
// | that bears insufficient indications that the modifications are
19+
// | not the work of the original author(s).
20+
// |
21+
// | This license applies to this document only, not any other software
22+
// | that it may be combined with.
23+
// |
24+
// +----------------------------------------------------------------------+
25+
// | Contributors:
26+
// | https://www.anuko.com/time_tracker/credits.htm
27+
// +----------------------------------------------------------------------+
28+
29+
// Note: This script uses Lichart PHP library and requires GD 2.0.1 or later.
30+
31+
require_once('initialize.php');
32+
import('form.Form');
33+
import('DateAndTime');
34+
import('ttChartHelper');
35+
import('ttSysConfig');
36+
import('PieChartEx');
37+
import('ttUserHelper');
38+
import('ttTeamHelper');
39+
40+
// Access check.
41+
if (!ttAccessCheck(right_view_charts)) {
42+
header('Location: access_denied.php');
43+
exit();
44+
}
45+
46+
// Initialize and store date in session.
47+
$cl_date = $request->getParameter('date', @$_SESSION['date']);
48+
if(!$cl_date) {
49+
$now = new DateAndTime(DB_DATEFORMAT);
50+
$cl_date = $now->toString(DB_DATEFORMAT);
51+
}
52+
$_SESSION['date'] = $cl_date;
53+
54+
// Initialize chart interval.
55+
$cl_interval = $_SESSION['chart_interval'];
56+
if (!$cl_interval) {
57+
$sc = new ttSysConfig($user->id);
58+
$cl_interval = $sc->getValue(SYSC_CHART_INTERVAL);
59+
}
60+
if (!$cl_interval) $cl_interval = INTERVAL_THIS_MONTH;
61+
$_SESSION['chart_interval'] = $cl_interval;
62+
63+
// Initialize chart type.
64+
$cl_type = $_SESSION['chart_type'];
65+
if (!$cl_type) {
66+
$sc = new ttSysConfig($user->id);
67+
$cl_type = $sc->getValue(SYSC_CHART_TYPE);
68+
}
69+
if (MODE_TIME == $user->tracking_mode) {
70+
if (in_array('cl', explode(',', $user->plugins)))
71+
$cl_type = CHART_CLIENTS;
72+
} else {
73+
if ($cl_type == CHART_CLIENTS) {
74+
if (!in_array('cl', explode(',', $user->plugins)))
75+
$cl_type = CHART_PROJECTS;
76+
} else if ($cl_type == CHART_TASKS) {
77+
if (MODE_PROJECTS_AND_TASKS != $user->tracking_mode)
78+
$cl_type = CHART_PROJECTS;
79+
}
80+
}
81+
if (!$cl_type) $cl_type = CHART_PROJECTS;
82+
$_SESSION['chart_type'] = $cl_type;
83+
84+
// Who do we draw charts for?
85+
$on_behalf_id = $request->getParameter('onBehalfUser', (isset($_SESSION['behalf_id'])? $_SESSION['behalf_id'] : $user->id));
86+
87+
if ($request->getMethod( )== 'POST') {
88+
// If chart interval changed - save it.
89+
$cl_interval = $request->getParameter('interval');
90+
if ($cl_interval) {
91+
// Save in the session
92+
$_SESSION['chart_interval'] = $cl_interval;
93+
// and permanently.
94+
$sc = new ttSysConfig($user->id);
95+
$sc->setValue(SYSC_CHART_INTERVAL, $cl_interval);
96+
}
97+
// If chart type changed - save it.
98+
$cl_type = $request->getParameter('type');
99+
if ($cl_type) {
100+
// Save in the session
101+
$_SESSION['chart_type'] = $cl_type;
102+
// and permanently.
103+
$sc = new ttSysConfig($user->id);
104+
$sc->setValue(SYSC_CHART_TYPE, $cl_type);
105+
}
106+
// If user has changed - set behalf_id accordingly in the session.
107+
if ($request->getParameter('onBehalfUser')) {
108+
if($user->canManageTeam()) {
109+
unset($_SESSION['behalf_id']);
110+
unset($_SESSION['behalf_name']);
111+
112+
if($on_behalf_id != $user->id) {
113+
$_SESSION['behalf_id'] = $on_behalf_id;
114+
$_SESSION['behalf_name'] = ttUserHelper::getUserName($on_behalf_id);
115+
}
116+
header('Location: charts.php');
117+
exit();
118+
}
119+
}
120+
}
121+
122+
// Elements of chartForm.
123+
$chart_form = new Form('chartForm');
124+
125+
// User dropdown. Changes the user "on behalf" of whom we are working.
126+
if ($user->canManageTeam()) {
127+
$user_list = ttTeamHelper::getActiveUsers(array('putSelfFirst'=>true));
128+
if (count($user_list) > 1) {
129+
$chart_form->addInput(array('type'=>'combobox',
130+
'onchange'=>'this.form.submit();',
131+
'name'=>'onBehalfUser',
132+
'value'=>$on_behalf_id,
133+
'data'=>$user_list,
134+
'datakeys'=>array('id','name'),
135+
));
136+
$smarty->assign('on_behalf_control', 1);
137+
}
138+
}
139+
140+
// Chart interval options.
141+
$intervals = array();
142+
$intervals[INTERVAL_THIS_DAY] = $i18n->getKey('dropdown.this_day');
143+
$intervals[INTERVAL_THIS_WEEK] = $i18n->getKey('dropdown.this_week');
144+
$intervals[INTERVAL_THIS_MONTH] = $i18n->getKey('dropdown.this_month');
145+
$intervals[INTERVAL_THIS_YEAR] = $i18n->getKey('dropdown.this_year');
146+
$intervals[INTERVAL_ALL_TIME] = $i18n->getKey('dropdown.all_time');
147+
148+
// Chart interval dropdown.
149+
$chart_form->addInput(array('type' => 'combobox',
150+
'onchange' => 'if(this.form) this.form.submit();',
151+
'name' => 'interval',
152+
'value' => $cl_interval,
153+
'data' => $intervals
154+
));
155+
156+
// Chart type options.
157+
$chart_selector = (MODE_PROJECTS_AND_TASKS == $user->tracking_mode
158+
|| in_array('cl', explode(',', $user->plugins)));
159+
if ($chart_selector) {
160+
$types = array();
161+
if (MODE_PROJECTS == $user->tracking_mode || MODE_PROJECTS_AND_TASKS == $user->tracking_mode)
162+
$types[CHART_PROJECTS] = $i18n->getKey('dropdown.projects');
163+
if (MODE_PROJECTS_AND_TASKS == $user->tracking_mode)
164+
$types[CHART_TASKS] = $i18n->getKey('dropdown.tasks');
165+
if (in_array('cl', explode(',', $user->plugins)))
166+
$types[CHART_CLIENTS] = $i18n->getKey('dropdown.clients');
167+
168+
// Add chart type dropdown.
169+
$chart_form->addInput(array('type' => 'combobox',
170+
'onchange' => 'if(this.form) this.form.submit();',
171+
'name' => 'type',
172+
'value' => $cl_type,
173+
'data' => $types
174+
));
175+
}
176+
177+
// Calendar.
178+
$chart_form->addInput(array('type'=>'calendar','name'=>'date','value'=>$cl_date)); // calendar
179+
180+
// Get data for our chart.
181+
$totals = ttChartHelper::getTotals($on_behalf_id, $cl_type, $cl_date, $cl_interval);
182+
$smarty->assign('totals', $totals);
183+
184+
// Prepare chart for drawing.
185+
/*
186+
* We use libchart.php library to draw chart images. It can draw chart labels, too (embed in the image).
187+
* But quality of such auto-scaled text is not good. Therefore, we only use libchart to draw a pie-chart picture with
188+
* auto-calculated percentage markers around it. We print labels (to the side of the picture) ourselves,
189+
* using the same colors libchart is using. For labels printout, the $totals array (which is used for picture points)
190+
* is also passed to charts.tpl Smarty template.
191+
*
192+
* To make all of the above possible with only one database call to obtain $totals we have to print the chart image
193+
* to a file here (see code below). Once the image is available as a .png file, the charts.tpl can render it.
194+
*
195+
* PieChartEx class is a little extension to libchart-provided PieChart class. It allows us to print the chart
196+
* without title, logo, and labels.
197+
*/
198+
$chart = new PieChartEx(300, 300);
199+
$data_set = new XYDataSet();
200+
foreach($totals as $total) {
201+
$data_set->addPoint(new Point( $total['name'], $total['time']));
202+
}
203+
$chart->setDataSet($data_set);
204+
205+
// Prepare a file name.
206+
$img_dir = TEMPLATE_DIR.'_c/'; // Directory.
207+
$file_name = uniqid('chart_').'.png'; // Short file name. Unique ID here is to avoid problems with browser caching.
208+
$img_ref = 'WEB-INF/templates_c/'.$file_name; // Image reference for html.
209+
$file_name = $img_dir.$file_name; // Full file name.
210+
211+
// Clean up the file system from older images.
212+
$img_files = glob($img_dir.'chart_*.png');
213+
foreach($img_files as $file) {
214+
// If the create time of file is older than 1 minute, delete it.
215+
if (filemtime($file) < (time() - 60)) {
216+
unlink($file);
217+
}
218+
}
219+
220+
// Write chart image to file system.
221+
$chart->renderEx(array('fileName'=>$file_name,'hideLogo'=>true,'hideTitle'=>true,'hideLabel'=>true));
222+
// At this point libchart usage is complete and we have chart image on disk.
223+
224+
$smarty->assign('img_file_name', $img_ref);
225+
$smarty->assign('chart_selector', $chart_selector);
226+
$smarty->assign('forms', array($chart_form->getName() => $chart_form->toArray()));
227+
$smarty->assign('title', $i18n->getKey('title.charts'));
228+
$smarty->assign('content_page_name', 'charts.tpl');
229+
$smarty->display('index.tpl');
230+
?>

client_add.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
// +----------------------------------------------------------------------+
3+
// | Anuko Time Tracker
4+
// +----------------------------------------------------------------------+
5+
// | Copyright (c) Anuko International Ltd. (https://www.anuko.com)
6+
// +----------------------------------------------------------------------+
7+
// | LIBERAL FREEWARE LICENSE: This source code document may be used
8+
// | by anyone for any purpose, and freely redistributed alone or in
9+
// | combination with other software, provided that the license is obeyed.
10+
// |
11+
// | There are only two ways to violate the license:
12+
// |
13+
// | 1. To redistribute this code in source form, with the copyright
14+
// | notice or license removed or altered. (Distributing in compiled
15+
// | forms without embedded copyright notices is permitted).
16+
// |
17+
// | 2. To redistribute modified versions of this code in *any* form
18+
// | that bears insufficient indications that the modifications are
19+
// | not the work of the original author(s).
20+
// |
21+
// | This license applies to this document only, not any other software
22+
// | that it may be combined with.
23+
// |
24+
// +----------------------------------------------------------------------+
25+
// | Contributors:
26+
// | https://www.anuko.com/time_tracker/credits.htm
27+
// +----------------------------------------------------------------------+
28+
29+
require_once('initialize.php');
30+
import('form.Form');
31+
import('ttClientHelper');
32+
import('ttTeamHelper');
33+
34+
// Access check.
35+
if (!ttAccessCheck(right_manage_team)) {
36+
header('Location: access_denied.php');
37+
exit();
38+
}
39+
40+
$projects = ttTeamHelper::getActiveProjects($user->team_id);
41+
42+
if ($request->getMethod() == 'POST') {
43+
$cl_name = trim($request->getParameter('name'));
44+
$cl_address = trim($request->getParameter('address'));
45+
$cl_tax = $request->getParameter('tax');
46+
$cl_projects = $request->getParameter('projects');
47+
} else {
48+
// Do not assign all projects to a new client by default. This should help to reduce clutter.
49+
// foreach ($projects as $project_item)
50+
// $cl_projects[] = $project_item['id'];
51+
}
52+
53+
$form = new Form('clientForm');
54+
$form->addInput(array('type'=>'text','maxlength'=>'100','name'=>'name','style'=>'width: 350px;','value'=>$cl_name));
55+
$form->addInput(array('type'=>'textarea','name'=>'address','maxlength'=>'255','style'=>'width: 350px;','cols'=>'55','rows'=>'5','value'=>$cl_address));
56+
$form->addInput(array('type'=>'floatfield','name'=>'tax','size'=>'10','format'=>'.2','value'=>$cl_tax));
57+
$form->addInput(array('type'=>'checkboxgroup','name'=>'projects','data'=>$projects,'layout'=>'H','datakeys'=>array('id','name'),'value'=>$cl_projects));
58+
$form->addInput(array('type'=>'submit','name'=>'btn_submit','value'=>$i18n->getKey('button.add')));
59+
60+
if ($request->getMethod() == 'POST') {
61+
// Validate user input.
62+
if (!ttValidString($cl_name)) $errors->add($i18n->getKey('error.field'), $i18n->getKey('label.client_name'));
63+
if (!ttValidString($cl_address, true)) $errors->add($i18n->getKey('error.field'), $i18n->getKey('label.client_address'));
64+
if (!ttValidFloat($cl_tax, true)) $errors->add($i18n->getKey('error.field'), $i18n->getKey('label.tax'));
65+
66+
if ($errors->isEmpty()) {
67+
if (!ttClientHelper::getClientByName($cl_name)) {
68+
if (ttClientHelper::insert(array(
69+
'team_id' => $user->team_id,
70+
'name' => $cl_name,
71+
'address' => $cl_address,
72+
'tax' => $cl_tax,
73+
'projects' => $cl_projects,
74+
'status' => ACTIVE))) {
75+
header('Location: clients.php');
76+
exit();
77+
} else
78+
$errors->add($i18n->getKey('error.db'));
79+
} else
80+
$errors->add($i18n->getKey('error.client_exists'));
81+
}
82+
} // post
83+
84+
$smarty->assign('forms', array($form->getName()=>$form->toArray()));
85+
$smarty->assign('onload', 'onLoad="document.clientForm.name.focus()"');
86+
$smarty->assign('title', $i18n->getKey('title.add_client'));
87+
$smarty->assign('content_page_name', 'client_add.tpl');
88+
$smarty->display('index.tpl');
89+
?>

0 commit comments

Comments
 (0)