commit a6ccd8cd1fe2072945419cab93a2deab45301f8f Author: Josh Holtrop Date: Fri Jun 15 00:53:46 2007 +0000 initial import git-svn-id: svn://anubis/tipman@1 ce01c143-e732-0410-ac0e-c064f6e6c7ef diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..7da11e3 --- /dev/null +++ b/.htaccess @@ -0,0 +1,6 @@ +DirectoryIndex login.php index.html + + + Order allow,deny + Deny from all + diff --git a/functions.inc b/functions.inc new file mode 100644 index 0000000..737d461 --- /dev/null +++ b/functions.inc @@ -0,0 +1,165 @@ +'; + } + + + function spacer($w = 1, $h = 1) + { + return 'blank'; + } + + + function round_table($body, $center = 0) + { + $bi = blank_image(); + return <<< EOE + + + + + + + + + + + + + + +
tl $bi tr
$bi + $body + $bi
bl $bi br
+EOE; + } + + + /* return a footer for the page */ + function footer() + { + return round_table(' Generated by PHP at ' . date('Y-m-d H:i:s') . '', 1); + } + + + /* connect to the database, return a handle */ + function connect_db() + { + global $MYSQL_SERVER, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DB; + $dbc = mysql_connect($MYSQL_SERVER, $MYSQL_USER, $MYSQL_PASSWORD); + if (!$dbc) + die('Could not connect to MySQL server: ' . mysql_error()); + if (!mysql_select_db($MYSQL_DB)) + die('Could not select database: ' . mysql_error()); + return $dbc; + } + + + /* perform a query on the MySQL database */ + function do_query($query, $dbc) + { + $qr = mysql_query($query, $dbc); + if (!$qr) + die('Invalid query: ' . mysql_error()); + return $qr; + } + + + /* returns the user's ID */ + function get_userID($user) + { + $dbc = connect_db(); + $qr = do_query("SELECT * FROM `users` WHERE `name` = '$user'", $dbc); + $ra = mysql_fetch_assoc($qr); + if (!$ra) + return -1; + return $ra['id']; + mysql_close($dbc); + } + + + /* Returns a 31-element array of tip values for the given month */ + function get_tips($month, $year, $userID) + { + $month = sprintf("%02d", $month); + $tips = array(); + for ($i = 0; $i < 31; $i++) + $tips[] = 0.0; + $dbc = connect_db(); + $q = do_query("SELECT * FROM `tips` WHERE `user` = '$userID' AND `date` LIKE '$year-$month%'", $dbc); + while ($ra = mysql_fetch_assoc($q)) + { + $dt = substr($ra['date'], 8, 2); + $tips[$dt - 1] = $ra['amount']; + } + mysql_free_result($q); + mysql_close($dbc); + return $tips; + } + + + /* Returns an assoc-array of check values + * (hours1, amount1, hours2, amount2) for the given month + */ + function get_checks($month, $year, $userID) + { + $month = sprintf("%02d", $month); + if (strlen($month) < 2) + $month = '0' . $month; + $checks = array(); + $dbc = connect_db(); + $q = do_query("SELECT * FROM `checks` WHERE `user` = '$userID' AND `date` LIKE '$year-$month%'", $dbc); + $dim = date('t', mktime(0, 0, 0, $month, 1, $year)); + while ($ra = mysql_fetch_assoc($q)) + { + $dt = substr($ra['date'], 8, 2); + if ($dt == 15) + { + $checks['hours1'] = $ra['hours']; + $checks['amount1'] = $ra['amount']; + } + elseif ($dt == $dim) + { + $checks['hours2'] = $ra['hours']; + $checks['amount2'] = $ra['amount']; + } + } + mysql_free_result($q); + mysql_close($dbc); + return $checks; + } + + + /* Return a string for the previous month */ + function get_back_month($month) + { + $mth = substr($month, 0, 2); + $yr = substr($month, 2, 4); + $mth = (($mth + 10) % 12) + 1; + if ($mth == 12) + $yr--; + if (strlen($mth) < 2) + $mth = "0$mth"; + return $mth . $yr; + } + + + /* Return a string for the next month */ + function get_next_month($month) + { + $mth = substr($month, 0, 2); + $yr = substr($month, 2, 4); + $mth = ($mth % 12) + 1; + if ($mth == 1) + $yr++; + if (strlen($mth) < 2) + $mth = "0$mth"; + return $mth . $yr; + } + + +?> diff --git a/functions.js b/functions.js new file mode 100644 index 0000000..3f0d8fc --- /dev/null +++ b/functions.js @@ -0,0 +1,111 @@ + +var show_tips_array = new Array('show_tips01', 'show_tips02', 'show_tips03', 'nav_tips0', 'nav_tips1', 'nav_tips2', 'nav_tips3', 'nav_tips4'); +var show_stats_array = new Array('show_stats01', 'show_stats02', 'show_stats03', 'show_stats04', 'nav_stats0', 'nav_stats1', 'nav_stats2', 'nav_stats3', 'nav_stats4'); + +var nav_month_vals = new Array('nav_month0', 'nav_month1', 'nav_month2', 'nav_month3', 'nav_month4'); +var nav_links = new Array('nav_link0', 'nav_link1', 'nav_link2', 'nav_link3', 'nav_link4'); + +var month_names = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); + +function showTips() +{ + var a = document.getElementById("calendar"); + a.style.display = 'block'; + a = document.getElementById("no-calendar"); + a.style.display = 'none'; + for (var i = 0; i < show_tips_array.length; i++) + document.getElementById(show_tips_array[i]).value = "1"; +} + +function hideTips() +{ + var a = document.getElementById("calendar"); + a.style.display = 'none'; + a = document.getElementById("no-calendar"); + a.style.display = 'block'; + for (var i = 0; i < show_tips_array.length; i++) + document.getElementById(show_tips_array[i]).value = "0"; +} + +function showStats() +{ + var a = document.getElementById("stats"); + a.style.display = 'block'; + a = document.getElementById("no-stats"); + a.style.display = 'none'; + for (var i = 0; i < show_stats_array.length; i++) + document.getElementById(show_stats_array[i]).value = "1"; +} + +function hideStats() +{ + var a = document.getElementById("stats"); + a.style.display = 'none'; + a = document.getElementById("no-stats"); + a.style.display = 'block'; + for (var i = 0; i < show_stats_array.length; i++) + document.getElementById(show_stats_array[i]).value = "0"; +} + +function nav_up() +{ + var navFirstMth = new String(navFirstMonth); + var theMonth = navFirstMth.substring(0,2); + var theYear = navFirstMth.substring(2,6); + theMonth--; + if (theMonth == 0) + { + theMonth = 12; + theYear--; + } + var newMonth = new String(theMonth); + if (newMonth.length < 2) + newMonth = "0" + newMonth; + navFirstMonth = newMonth.concat(theYear); + navIndex++; + regen_navbar(); +} + +function nav_down() +{ + var navFirstMth = new String(navFirstMonth); + var theMonth = navFirstMth.substring(0,2); + var theYear = navFirstMth.substring(2,6); + theMonth++; + if (theMonth == 13) + { + theMonth = 1; + theYear++; + } + var newMonth = new String(theMonth); + if (newMonth.length < 2) + newMonth = "0" + newMonth; + navFirstMonth = newMonth.concat(theYear); + navIndex--; + regen_navbar(); +} + +function regen_navbar() +{ + var theMonth = navFirstMonth.substring(0,2); + var theYear = navFirstMonth.substring(2,6); + for (var i = 0; i < 5; i++) + { + theMonth = new String(theMonth); + if (theMonth.length < 2) + theMonth = "0" + theMonth; + var m = document.getElementById(nav_month_vals[i]); + m.value = theMonth.concat(theYear); + m = document.getElementById(nav_links[i]); + if (i == navIndex) + m.innerHTML = '' + month_names[theMonth - 1] + ", " + theYear + ' + + + + + + + + +
+Welcome to $APP_TITLE! +EOF +, 1 +); + echo '
'; + echo round_table( <<< EOF +
+

+EOF +. (isset($failed_login) ? 'Invalid login!

' : '') . <<< EOF + User name: +

+ Password: +

+   +

+
+ +EOF +, 1 +); + +?>
+ + + + + diff --git a/main.css b/main.css new file mode 100644 index 0000000..ee53d61 --- /dev/null +++ b/main.css @@ -0,0 +1,80 @@ + +body +{ + margin: 0px; + margin-left: 12em; + padding: 1em; +} + +div.nav +{ + position: absolute; + top: 1em; + left: 1em; + width: 11em; +} + +table.cal +{ + margin-left: auto; + margin-right: auto; + border-style: outset; + border-width: 1px; +} + +td.cal +{ + margin: 0px; + padding: 2px; + padding-bottom: 2px; + border-style: inset; + border-width: 1px; + font-size: smaller; + font-weight: bold; + text-align: center; +} + +table.stat +{ + margin-left: auto; + margin-right: auto; +} + +td.statbar +{ + padding-left: 5px; +} + +td.stat +{ + text-align: center; + font-size: smaller; + width: 35; +} + +.hideable +{ + border-style: solid; + border-width: 1px; + display: block; +} + +a.switch +{ + text-decoration: none; + color: #000; +} + +a.switch:hover { color: #666; } + +a.nav_link +{ + display: block; + text-decoration: none; + color: #000; +} + +a.nav_link:hover +{ + color: #666; +} diff --git a/main.php b/main.php new file mode 100644 index 0000000..1363707 --- /dev/null +++ b/main.php @@ -0,0 +1,378 @@ +'; + echo '
'; + echo round_table('up', + 1) . '
'; + echo spacer(1, 10); + for ($i = 0; $i < 5; $i++) + { + $month_cap = date('F', mktime(1, 1, 1, substr($month_val, 0, 2))) . + ', ' . substr($month_val, 2, 4); + echo round_table( + '', + 1); + echo spacer(1, 10); + $month_val = get_next_month($month_val); + } + echo '
'; + echo round_table('up', 1) . '
'; + ################### + # Show year total # + ################### + $year_total = 0.0; + for ($i = 1; $i < 13; $i++) + { + $tips = get_tips($i, $_SESSION['year'], $userID); + for ($j = 0; $j < 31; $j++) + $year_total += $tips[$j]; + $checks = get_checks($i, $_SESSION['year'], $userID); + $year_total += $checks['amount1']; + $year_total += $checks['amount2']; + } + echo spacer(1,20); + echo '
' . + round_table($_SESSION['year'] . ' total: $' . $year_total, 1) . '
'; + echo spacer(1, 30); + echo '
' . round_table('Logout', 1) . '
'; + echo ''; + } + + + /* Returns calendar HTML */ + function calendar($month, $year, $tipVals, $showStats) + { + $day_captions = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); + $dateStamp = mktime(0, 0, 0, $month, 1, $year); + $dow = date('w', $dateStamp); /* 0-6 */ + $ret = '

' . + '' . + '' . + '' . + '' . + '' . + ''; + for ($i = 0; $i < 7; $i++) + $ret .= ''; + $ret .= ''; + for($i = 0; $i < $dow; $i++) + $ret .= ''; /* pad beginning of month */ + $col = $dow; + $dim = date('t', $dateStamp); + for ($i = 0; $i < $dim; $i++) + { + if ($tipVals[$i] == 0) + $tipVals[$i] = ''; + $io = $i + 1; + if ($col == 0) + $ret .= ''; + $ret .= <<< EOE + +EOE; + $col++; + if ($col == 7) + { + $ret .= "\n"; + $col = 0; + } + } + if ($col > 0) + { + for (; $col < 7; $col++) + $ret .= ''; + $ret .= ''; + } + $ret .= '
' . $day_captions[$i] . '
 
$io
+ +
 

 
'; + return $ret; + } + + + /* Returns statistics HTML */ + function stats($month, $year, $tipVals) + { + $MAX_HEIGHT = 100; + $day_captions = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); + $dayCounts = array(); + $tipTotals = array(); + for ($i = 0; $i < 7; $i++) + { + $dayCounts[] = 0; + $tipTotals[] = 0.0; + } + $dateStamp = mktime(0, 0, 0, $month, 1, $year); + $dow = date('w', $dateStamp); /* 0-6 */ + for ($i = 0; $i < 31; $i++) + { + if (isset($tipVals[$i])) + { + $dayCounts[$dow]++; + $tipTotals[$dow] += $tipVals[$i]; + } + $dow = ($dow + 1) % 7; + } + $tipAverages = array(); + for ($i = 0; $i < 7; $i++) + $tipAverages[$i] = $tipTotals[$i] / $dayCounts[$dow]; + $max = $tipAverages[0]; + if ($max == 0) + $max = 1; + for ($i = 0; $i < 7; $i++) + if ($tipAverages[$i] > $max) + $max = $tipAverages[$i]; + $ret = ''; + $ret .= ''; + for ($i = 0; $i < 7; $i++) + $ret .= ''; + $ret .= ''; + for ($i = 0; $i < 7; $i++) + $ret .= ''; + $ret .= '
$' . ((int) $max) . ' - bar
$' . + ((int)($max / 2)) . ' -
$0 - ' . $day_captions[$i] . '
'; + return $ret; + } + + + /* Initialization */ + if (!isset($_SESSION['year'])) + $_SESSION['year'] = date('Y'); + if (!isset($_SESSION['month'])) + $_SESSION['month'] = date('m'); + + + $userID = get_userID($_SESSION['user']); + + /* Handle POST form input */ + if ($_POST['action'] == 'change_month') + { + if (preg_match('/^\d{6}$/', $_POST['new_month'])) + { + $_SESSION['month'] = substr($_POST['new_month'], 0, 2); + $_SESSION['year'] = substr($_POST['new_month'], 2, 4); + } + } + elseif ($_POST['action'] == 'save_tips') + { + $dbc = connect_db(); + for ($i = 0; $i < 31; $i++) + { + if (isset($_POST['tip' . $i])) + { + $val = $_POST['tip' . $i]; + if (preg_match('/^\d*\.?\d{0,2}$/', $val)) + { + $day = $i + 1; + if (strlen($day) < 2) + $day = "0$day"; + do_query("DELETE FROM `tips` WHERE `date` = '$_SESSION[year]-$_SESSION[month]-$day' AND `user` = '$userID'", $dbc); + if ($val != 0) + do_query("INSERT INTO `tips` VALUES('', $userID, '$_SESSION[year]-$_SESSION[month]-$day', '$val')", $dbc); + } + } + } + mysql_close($dbc); + } + elseif ($_POST['action'] == 'save_checks') + { + $dbc = connect_db(); + $pattern = '/^\d*\.?\d{0,2}$/'; + $h = $_POST['hours1']; + $a = $_POST['amount1']; + if (preg_match($pattern, $h) && preg_match($pattern, $a)) + { + do_query("DELETE FROM `checks` WHERE `date` = '$_SESSION[year]-$_SESSION[month]-15' AND `user` = '$userID'", $dbc); + if ( ($h != 0) || ($a != 0) ) + do_query("INSERT INTO `checks` VALUES('', '$userID', '$_SESSION[year]-$_SESSION[month]-15', '$h', '$a')", $dbc); + } + $h = $_POST['hours2']; + $a = $_POST['amount2']; + if (preg_match($pattern, $h) && preg_match($pattern, $a)) + { + $dim = date('t', mktime(1, 1, 1, $_SESSION['month'], 1, $_SESSION['year'])); + do_query("DELETE FROM `checks` WHERE `date` = '$_SESSION[year]-$_SESSION[month]-$dim' AND `user` = '$userID'", $dbc); + if ( ($h != 0) || ($a != 0) ) + do_query("INSERT INTO `checks` VALUES('', '$userID', '$_SESSION[year]-$_SESSION[month]-$dim', '$h', '$a')", $dbc); + } + mysql_close($dbc); + } + + /* Set us up some variables for user later on */ + $thisMonth = date('F', mktime(0, 0, 0, $_SESSION['month'])); + $thisYear = date('Y', mktime(0, 0, 0, 1, 1, $_SESSION['year'])); + $nextMonth = sprintf('%02d', (($_SESSION['month'] % 12) + 1)) . (($_SESSION['month'] == 12) ? $thisYear + 1 : $thisYear); + $prevMonth = sprintf('%02d', ((($_SESSION['month'] + 10) % 12) + 1)) . (($_SESSION['month'] == 1) ? $thisYear - 1 : $thisYear); + $showTips = ( isset($_POST['show_tips']) && ($_POST['show_tips'] == 1) ) ? 1 : 0; + $showStats = ( isset($_POST['show_stats']) && ($_POST['show_stats'] == 1) ) ? 1 : 0; + $navMonth = $_POST['nav_month']; + $navMonth = ( isset($navMonth) && $navMonth >= 0 && $navMonth < 5 ) ? $navMonth : 3; + +?> + + + + <?php echo $APP_TITLE; ?> + + + + + + + + + + + +
+ + + + + + +
+ + $thisMonth, $thisYear + +
+ + + + + + +
+ + + +EOE +); +?> +
+ + Edit Tips >>> + +
+ <<< Hide Tips +
+EOE + . calendar($_SESSION['month'], $_SESSION['year'], $tips, $showStats) . <<< EOE +
+
+
+ Show Stats >>> +
+
+ <<< Hide Stats +
+EOE + . stats($_SESSION['month'], $_SESSION['year'], $tips) . <<< EOE +
+
+EOE + . '
' . + '' . + '' . $thisMonth . ' 1 - 15
' . + '
Hours: ' . + '' . + '   Check Amount: ' . + '' . + '   Tips: $' . $tip1_total . + '

' . $thisMonth . ' 16 - ' . + date('t', mktime(1, 1, 1, $_SESSION['month'], 1, $_SESSION['year'])) . '
' . + '
Hours: ' . + '' . + '   Check Amount: ' . + '' . + '   Tips: $' . $tip2_total . + '

  ' . + '' . + '' . + '' . + '
' . + '
' . + '
' . + "$thisMonth Total: $" . ($tip1_total + $tip2_total + $checks['amount1'] + $checks['amount2']) . + '  
' + , + 0); + echo '
'; + echo footer(); +?> + + + + + diff --git a/objects.css b/objects.css new file mode 100644 index 0000000..5caaf65 --- /dev/null +++ b/objects.css @@ -0,0 +1,21 @@ + +form { margin: 0px; } + +table.round +{ + background-color: #ACF; + width: 100%; + margin: 0px; + padding: 0px; +} + +td.corner { width: 5px; padding: 0; margin: 0; } +td.button_top { border-top-style: solid; border-top-width: 1px; } +td.button_left { border-left-style: solid; border-left-width: 1px; } +td.button_right { border-right-style: solid; border-right-width: 1px; } +td.button_bottom { border-bottom-style: solid; border-bottom-width: 1px; } + +img.blank { border-style: none; margin: 0px; padding: 0px; } + +.smaller { font-size: smaller; } +.really-small { font-size: 0.75em; } diff --git a/vars.inc b/vars.inc new file mode 100644 index 0000000..2454056 --- /dev/null +++ b/vars.inc @@ -0,0 +1,12 @@ +