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.
11 // | There are only two ways to violate the license:
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).
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).
21 // | This license applies to this document only, not any other software
22 // | that it may be combined with.
24 // +----------------------------------------------------------------------+
26 // | https://www.anuko.com/time_tracker/credits.htm
27 // +----------------------------------------------------------------------+
29 import('form.FormElement');
30 import('DateAndTime');
32 class Calendar extends FormElement {
33 var $holidays = array();
34 var $showHolidays = true;
35 var $weekStartDay = 0;
37 var $mHeader = "padding: 5px; font-size: 8pt; color: #333333; background-color: #d9d9d9;";
38 var $mDayCell = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #333333; background-color: #ffffff;";
39 var $mDaySelected = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #666666; background-color: #a6ccf7;";
40 var $mDayWeekend = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #666666; background-color: #f7f7f7;";
41 var $mDayHoliday = "padding: 5px; border: 1px solid silver; font-size: 8pt; color: #666666; background-color: #f7f7f7;";
42 var $mDayHeader = "padding: 5px; border: 1px solid white; font-size: 8pt; color: #333333;";
43 var $mDayHeaderWeekend = "padding: 5px; border: 1px solid white; font-size: 8pt; color: #999999;";
45 var $controlName = "";
46 var $highlight = "time"; // Determines what type of active days to highlight ("time" or "expenses").
47 // var $mAllDays = true;
48 var $cClassName = "Calendar";
50 function __construct($name) {
51 $this->controlName = $name;
52 $this->mMonthNames = array('January','February','March','April','May','June','July','August','September','October','November','December');
53 $this->mWeekDayShortNames = array('Su','Mo','Tu','We','Th','Fr','Sa');
56 function setHighlight($highlight) {
57 if ($highlight && $highlight != 'time')
58 $this->highlight = $highlight;
61 function setLocalization($i18n) {
64 FormElement::setLocalization($i18n);
65 $this->mMonthNames = $i18n->monthNames;
66 $this->mWeekDayShortNames = $i18n->weekdayShortNames;
67 if (is_array($i18n->holidays)) {
68 foreach ($i18n->holidays as $fday) {
69 $date_a = explode("/",$fday); // format mm/dd
70 $this->holidays[] = mktime(0,0,0, $date_a[0], $date_a[1], date("Y"));// + 7200;
73 $this->weekStartDay = $user->week_start;
76 function setStyle($style) { $this->mStyle = $style; }
77 function setCellStyle($style) { $this->mCellStyle = $style; }
78 function setACellStyle($style) { $this->mACellStyle = $style; }
79 function setLinkStyle($style) { $this->mLinkStyle = $style; }
81 function setShowHolidays($value) {
82 $this->showHolidays = $value;
88 * @desc Enter description here...
90 function toString($date="") {
93 $indate = $this->mValue;
94 if (!$indate) $indate = strftime(DB_DATEFORMAT);
96 if (!$this->isRenderable()) return "";
98 //current year and month
99 if ( strlen ( $indate ) > 0 ) {
100 $indateObj = new DateAndTime(DB_DATEFORMAT, $indate);
101 $thismonth = $indateObj->getMonth();
102 $thisyear = $indateObj->getYear();
104 $thismonth = date("m");
105 $thisyear = date("Y");
108 // next date, month, year
109 $next = mktime ( 2, 0, 0, $thismonth + 1, 1, $thisyear );
110 $nextyear = date ( "Y", $next );
111 $nextmonth = date ( "m", $next );
112 $nextdate = strftime (DB_DATEFORMAT, $next );
114 // prev date, month, year
115 $prev = mktime ( 2, 0, 0, $thismonth - 1, 1, $thisyear );
116 $prevyear = date ( "Y", $prev );
117 $prevmonth = date ( "m", $prev );
118 $prevdate = strftime(DB_DATEFORMAT, $prev );
120 $str = $this->_genStyles();
122 $str .= '<table cellpadding="0" cellspacing="0" border="0" width="100%">
123 <tr><td align="center"><div class="CalendarHeader">'.
124 //'<a href="?date='.$prevyear.'"><<</a> '.
125 '<a href="?date='.$prevdate.'" tabindex="-1"><<<</a> '.
126 $this->mMonthNames[$thismonth-1].' '.$thisyear.
127 ' <a href="?date='.$nextdate.'" tabindex="-1">>>></a>'.
128 //' <a href="?date='.$nextyear.'">>></a>'.
133 <table border="0" cellpadding="1" cellspacing="1" width="100%">
138 $weekend_start = 6 - $this->weekStartDay; // Saturday by default.
139 $weekend_end = (7 - $this->weekStartDay) % 7; // Sunday by default.
140 if (defined('WEEKEND_START_DAY')) {
141 $weekend_start = (7 + WEEKEND_START_DAY - $this->weekStartDay) % 7;
142 $weekend_end = (7 + WEEKEND_START_DAY + 1 - $this->weekStartDay) % 7;
145 for ( $i=0; $i<7; $i++ ) {
146 $weekdayNameIdx = ($i + $this->weekStartDay) % 7;
147 if ($i==$weekend_start || $i==$weekend_end) {
148 $str .= '<td class="CalendarDayHeaderWeekend">'.$this->mWeekDayShortNames[$weekdayNameIdx].'</td>';
150 $str .= '<td class="CalendarDayHeader">'.$this->mWeekDayShortNames[$weekdayNameIdx].'</td>';
156 list($wkstart,$monthstart,$monthend,$start_date) = $this->_getWeekDayBefore( $thisyear, $thismonth );
158 $active_dates = $this->_getActiveDates($monthstart, $monthend);
160 for ( $i = $wkstart; $i<=$monthend; $i=mktime(0,0,0,$thismonth,$start_date+=7,$thisyear) ) {
162 for ( $j = 0; $j < 7; $j++ ) {
163 $date = mktime(0,0,0,$thismonth,$start_date+$j,$thisyear);
164 if (($date >= $monthstart) && ($date <= $monthend)) {
170 if ($j==$weekend_start || $j==$weekend_end) {
171 $stl_cell = ' class="CalendarDayWeekend"';
172 $stl_link = ' class="CalendarLinkWeekend"';
174 $stl_cell = ' class="CalendarDay"';
178 if ($this->showHolidays) {
179 foreach ($this->holidays as $day) {
181 $stl_cell = ' class="CalendarDayHoliday"';
182 $stl_link = ' class="CalendarLinkHoliday"';
188 if ( $indate == strftime(DB_DATEFORMAT, $date))
189 $stl_cell = ' class="CalendarDaySelected"';
192 $str .= '<td'.$stl_cell.'>';
196 if( in_array(strftime(DB_DATEFORMAT, $date), $active_dates) )
197 $stl_link = ' class="CalendarLinkRecordsExist"';
200 $str .= "<a".$stl_link." href=\"?".$this->controlName."=".strftime(DB_DATEFORMAT, $date)."\" tabindex=\"-1\">".date("d",$date)."</a>";
205 $str .= "<TD> </TD>\n";
211 $str .= "<tr><td colspan=\"7\" align=\"center\"><a id=\"today_link\" href=\"?".$this->controlName."=".strftime(DB_DATEFORMAT)."\" tabindex=\"-1\">".$i18n->getKey('label.today')."</a></td></tr>\n";
212 $str .= "</table>\n";
214 $str .= "<input type=\"hidden\" name=\"$this->controlName\" value=\"$indate\">\n";
216 // Add script to adjust today link to match browser today, as PHP may run in a different timezone.
217 $str .= "<script>\n";
218 $str .= "function adjustToday() {\n";
219 $str .= " var browser_today = new Date();\n";
220 $str .= " document.getElementById('today_link').href = '?$this->controlName='+browser_today.strftime('".DB_DATEFORMAT."');\n";
222 $str .= "adjustToday();\n";
223 $str .= "</script>\n";
228 function toStringControl() {
229 return $this->toString();
232 function _getWeekDayBefore($year, $month) {
233 $weekday = date ( "w", mktime ( 2, 0, 0, $month, 1 - $this->weekStartDay, $year ) );
235 mktime ( 0, 0, 0, $month, 1 - $weekday, $year ),
236 mktime ( 0, 0, 0, $month, 1, $year ),
237 mktime ( 0, 0, 0, $month + 1, 0, $year ),
242 function _genStyles() {
244 $str .= ".CalendarHeader {". $this->mHeader ."}\n";
245 $str .= ".CalendarDay {". $this->mDayCell ."}\n";
246 $str .= ".CalendarDaySelected {". $this->mDaySelected ."}\n";
247 $str .= ".CalendarDayWeekend {". $this->mDayWeekend ."}\n";
248 $str .= ".CalendarDayHoliday {". $this->mDayHoliday ."}\n";
249 $str .= ".CalendarDayHeader {". $this->mDayHeader ."}\n";
250 $str .= ".CalendarDayHeaderWeekend {". $this->mDayHeaderWeekend ."}\n";
252 $str .= ".CalendarLinkWeekend {color: #999999;}\n";
253 $str .= ".CalendarLinkHoliday {color: #999999;}\n";
254 $str .= ".CalendarLinkRecordsExist {color: #FF0000;}\n";
255 $str .= "</style>\n";
259 // _getActiveDates returns an array of dates, for which entries exist for user.
260 // Type of entries (time or expenses) is determined by $this->highlight value.
261 function _getActiveDates($start, $end) {
264 $user_id = $user->getActiveUser();
266 $table = ($this->highlight == 'expenses') ? 'tt_expense_items' : 'tt_log';
268 $mdb2 = getConnection();
270 $start_date = date("Y-m-d", $start);
271 $end_date = date("Y-m-d", $end);
272 $sql = "SELECT date FROM $table WHERE date >= '$start_date' AND date <= '$end_date' AND user_id = $user_id AND status = 1";
273 $res = $mdb2->query($sql);
274 if (!is_a($res, 'PEAR_Error')) {
275 while ($row = $res->fetchRow()) {
276 $out[] = date('Y-m-d', strtotime($row['date']));