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"). 
 
  48     function __construct($name) {
 
  49       $this->class = 'Calendar';
 
  50       $this->controlName = $name; // TODO: why controlName? Other classes have "name".
 
  51       $this->mMonthNames = array('January','February','March','April','May','June','July','August','September','October','November','December');
 
  52       $this->mWeekDayShortNames = array('Su','Mo','Tu','We','Th','Fr','Sa');
 
  55     function setHighlight($highlight) {
 
  56         if ($highlight && $highlight != 'time')
 
  57           $this->highlight = $highlight;
 
  60     function localize($i18n) {
 
  63       $this->mMonthNames = $i18n->monthNames;
 
  64       $this->mWeekDayShortNames = $i18n->weekdayShortNames;
 
  65       if (is_array($i18n->holidays)) {
 
  66         foreach ($i18n->holidays as $fday) {
 
  67           $date_a = explode("/",$fday); // format mm/dd
 
  68           $this->holidays[] = mktime(0,0,0, $date_a[0], $date_a[1], date("Y"));// + 7200;
 
  71       $this->weekStartDay = $user->week_start;
 
  74     function setStyle($style) { $this->style = $style; }
 
  75     function setCellStyle($style) { $this->mCellStyle = $style; }
 
  76     function setACellStyle($style) { $this->mACellStyle = $style; }
 
  77     function setLinkStyle($style) { $this->mLinkStyle = $style; }
 
  79     function setShowHolidays($value) {
 
  80       $this->showHolidays = $value;
 
  86      * @desc Enter description here...
 
  88     function toString($date="") {
 
  91       $indate = $this->value;
 
  92       if (!$indate) $indate = strftime(DB_DATEFORMAT);
 
  94       //current year and month
 
  95       if ( strlen ( $indate ) > 0 ) {
 
  96         $indateObj = new DateAndTime(DB_DATEFORMAT, $indate);
 
  97         $thismonth = $indateObj->getMonth();
 
  98         $thisyear = $indateObj->getYear();
 
 100         $thismonth = date("m");
 
 101         $thisyear = date("Y");
 
 104       // next date, month, year
 
 105       $next = mktime ( 2, 0, 0, $thismonth + 1, 1, $thisyear );
 
 106       $nextyear = date ( "Y", $next );
 
 107       $nextmonth = date ( "m", $next );
 
 108       $nextdate = strftime (DB_DATEFORMAT, $next );
 
 110       // prev date, month, year
 
 111       $prev = mktime ( 2, 0, 0, $thismonth - 1, 1, $thisyear );
 
 112       $prevyear = date ( "Y", $prev );
 
 113       $prevmonth = date ( "m", $prev );
 
 114       $prevdate = strftime(DB_DATEFORMAT, $prev );
 
 116       $str = $this->_genStyles();
 
 118       $str .= '<table cellpadding="0" cellspacing="0" border="0" width="100%">
 
 119           <tr><td align="center"><div class="CalendarHeader">'.
 
 120           //'<a href="?date='.$prevyear.'"><<</a> '.
 
 121           '<a href="?date='.$prevdate.'" tabindex="-1"><<<</a>  '.
 
 122           $this->mMonthNames[$thismonth-1].' '.$thisyear.
 
 123           '  <a href="?date='.$nextdate.'" tabindex="-1">>>></a>'.
 
 124           //' <a href="?date='.$nextyear.'">>></a>'.
 
 129           <table border="0" cellpadding="1" cellspacing="1" width="100%">
 
 134       $weekend_start = 6 - $this->weekStartDay;      // Saturday by default.
 
 135       $weekend_end = (7 - $this->weekStartDay) % 7;  // Sunday by default.
 
 136       if (defined('WEEKEND_START_DAY')) {
 
 137         $weekend_start = (7 + WEEKEND_START_DAY - $this->weekStartDay) % 7;
 
 138         $weekend_end = (7 + WEEKEND_START_DAY + 1 - $this->weekStartDay) % 7;
 
 141       for ( $i=0; $i<7; $i++ ) {
 
 142         $weekdayNameIdx = ($i + $this->weekStartDay) % 7;
 
 143         if ($i==$weekend_start || $i==$weekend_end) {
 
 144           $str .= '<td class="CalendarDayHeaderWeekend">'.$this->mWeekDayShortNames[$weekdayNameIdx].'</td>';
 
 146           $str .= '<td class="CalendarDayHeader">'.$this->mWeekDayShortNames[$weekdayNameIdx].'</td>';
 
 152       list($wkstart,$monthstart,$monthend,$start_date) = $this->_getWeekDayBefore( $thisyear, $thismonth );
 
 154       $active_dates = $this->_getActiveDates($monthstart, $monthend);
 
 156       for ( $i = $wkstart; $i<=$monthend;  $i=mktime(0,0,0,$thismonth,$start_date+=7,$thisyear) ) {
 
 158           for ( $j = 0; $j < 7; $j++ ) {
 
 159             $date = mktime(0,0,0,$thismonth,$start_date+$j,$thisyear);
 
 160             if (($date >= $monthstart) && ($date <= $monthend)) {
 
 166             if ($j==$weekend_start || $j==$weekend_end) {
 
 167               $stl_cell = ' class="CalendarDayWeekend"';
 
 168               $stl_link = ' class="CalendarLinkWeekend"';
 
 170               $stl_cell = ' class="CalendarDay"';
 
 174               if ($this->showHolidays) {
 
 175               foreach ($this->holidays as $day) {
 
 177                   $stl_cell = ' class="CalendarDayHoliday"';
 
 178                   $stl_link = ' class="CalendarLinkHoliday"';
 
 184             if ( $indate == strftime(DB_DATEFORMAT, $date))
 
 185               $stl_cell = ' class="CalendarDaySelected"';
 
 188             $str .= '<td'.$stl_cell.'>';
 
 192               if( in_array(strftime(DB_DATEFORMAT, $date), $active_dates) )
 
 193                 $stl_link = ' class="CalendarLinkRecordsExist"';
 
 196             $str .= "<a".$stl_link." href=\"?".$this->controlName."=".strftime(DB_DATEFORMAT, $date)."\" tabindex=\"-1\">".date("d",$date)."</a>";
 
 201             $str .= "<TD> </TD>\n";
 
 207       $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";
 
 208       $str .= "</table>\n";
 
 210       $str .= "<input type=\"hidden\" name=\"$this->controlName\" value=\"$indate\">\n";
 
 212       // Add script to adjust today link to match browser today, as PHP may run in a different timezone.
 
 213       $str .= "<script>\n";
 
 214       $str .= "function adjustToday() {\n";
 
 215       $str .= "  var browser_today = new Date();\n";
 
 216       $str .= "  document.getElementById('today_link').href = '?$this->controlName='+browser_today.strftime('".DB_DATEFORMAT."');\n";
 
 218       $str .= "adjustToday();\n";
 
 219       $str .= "</script>\n";
 
 225         return $this->toString();
 
 228     function _getWeekDayBefore($year, $month) {
 
 229       $weekday = date ( "w", mktime ( 2, 0, 0, $month, 1 - $this->weekStartDay, $year ) );
 
 231         mktime ( 0, 0, 0, $month, 1 - $weekday, $year ),
 
 232         mktime ( 0, 0, 0, $month, 1, $year ),
 
 233       mktime ( 0, 0, 0, $month + 1, 0, $year ),
 
 238     function _genStyles() {
 
 240       $str .= ".CalendarHeader {". $this->mHeader ."}\n";
 
 241       $str .= ".CalendarDay {". $this->mDayCell  ."}\n";
 
 242       $str .= ".CalendarDaySelected {". $this->mDaySelected  ."}\n";
 
 243       $str .= ".CalendarDayWeekend {". $this->mDayWeekend ."}\n";
 
 244       $str .= ".CalendarDayHoliday {". $this->mDayHoliday ."}\n";
 
 245       $str .= ".CalendarDayHeader {". $this->mDayHeader ."}\n";
 
 246       $str .= ".CalendarDayHeaderWeekend {". $this->mDayHeaderWeekend ."}\n";
 
 248       $str .= ".CalendarLinkWeekend {color: #999999;}\n";
 
 249       $str .= ".CalendarLinkHoliday {color: #999999;}\n";
 
 250       $str .= ".CalendarLinkRecordsExist {color: #FF0000;}\n";
 
 251         $str .= "</style>\n";
 
 255     // _getActiveDates returns an array of dates, for which entries exist for user.
 
 256     // Type of entries (time or expenses) is determined by $this->highlight value.
 
 257     function _getActiveDates($start, $end) {
 
 260       $user_id = $user->getActiveUser();
 
 262       $table = ($this->highlight == 'expenses') ? 'tt_expense_items' : 'tt_log';
 
 264       $mdb2 = getConnection();
 
 266       $start_date = date("Y-m-d", $start);
 
 267       $end_date = date("Y-m-d", $end);
 
 268       $sql = "SELECT date FROM $table WHERE date >= '$start_date' AND date <= '$end_date' AND user_id = $user_id AND status = 1";
 
 269       $res = $mdb2->query($sql);
 
 270       if (!is_a($res, 'PEAR_Error')) {
 
 271         while ($row = $res->fetchRow()) {
 
 272           $out[] = date('Y-m-d', strtotime($row['date']));