You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by jf...@apache.org on 2008/12/12 19:20:18 UTC

svn commit: r726079 [28/32] - in /incubator/vcl/tags/import: ./ managementnode/ managementnode/bin/ managementnode/etc/ managementnode/etc/vcl/ managementnode/legacy_vcl_vbs_scripts/ managementnode/lib/ managementnode/lib/VCL/ managementnode/lib/VCL/Mo...

Added: incubator/vcl/tags/import/web/.ht-inc/statistics.php
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/web/.ht-inc/statistics.php?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/web/.ht-inc/statistics.php (added)
+++ incubator/vcl/tags/import/web/.ht-inc/statistics.php Fri Dec 12 10:20:10 2008
@@ -0,0 +1,1015 @@
+<?php
+/*
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+*/
+
+if($phpVer == 5) {
+require_once(".ht-inc/jpgraph/jpgraph.php");
+require_once(".ht-inc/jpgraph/jpgraph_bar.php");
+require_once(".ht-inc/jpgraph/jpgraph_line.php");
+}
+else {
+require_once(".ht-inc/jpgraph.old/jpgraph.php");
+require_once(".ht-inc/jpgraph.old/jpgraph_bar.php");
+require_once(".ht-inc/jpgraph.old/jpgraph_line.php");
+}
+
+/**
+ * \file
+ */
+
+/// global array for x axis labels
+$xaxislabels = array();
+/// signifies an error with the submitted start date
+define("STARTERR", 1);
+/// signifies an error with the submitted end date
+define("ENDERR", 1 << 1);
+/// signifies an error with the start date being after the end date
+define("ORDERERR", 1 << 2);
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn selectStatistics()
+///
+/// \brief prints a form for getting statistics
+///
+////////////////////////////////////////////////////////////////////////////////
+function selectStatistics() {
+	global $submitErr, $viewmode, $user;
+	list($month1, $day1, $year1) = explode(',', date('F,j,Y', time() - 
+	                                    (SECINDAY * 6)));
+	list($month2, $day2, $year2) = explode(',', date('F,j,Y', time()));
+	print "<H2>Statistic Information</H2>\n";
+	if($submitErr) {
+		printSubmitErr(STARTERR);
+		printSubmitErr(ENDERR);
+		printSubmitErr(ORDERERR);
+		$monthkey1 = processInputVar("month1", ARG_NUMERIC);
+		$daykey1 = processInputVar("day1", ARG_NUMERIC);
+		$yearkey1 = processInputVar("year1", ARG_NUMERIC);
+		$monthkey2 = processInputVar("month2", ARG_NUMERIC);
+		$daykey2 = processInputVar("day2", ARG_NUMERIC);
+		$yearkey2 = processInputVar("year2", ARG_NUMERIC);
+		$affilid = processInputVar("affilid", ARG_NUMERIC);
+	}
+	else
+		$affilid = $user['affiliationid'];
+	print "Select a starting date:<br>\n";
+	$months = array("",
+	                "January",
+	                "February",
+	                "March",
+	                "April",
+	                "May",
+	                "June",
+	                "July",
+	                "August",
+	                "September",
+	                "October",
+	                "November",
+	                "December");
+	unset($months[0]);
+	$days = array();
+	for($i = 0; $i < 32; $i++) {
+		array_push($days, $i);
+	}
+	unset($days[0]);
+	$years = array();
+	for($i = 2004; $i <= $year2; $i++) {
+		$years[$i] = $i;
+	}
+	if(! $submitErr) {
+		$monthkey1 = array_search($month1, $months);
+		$daykey1 = array_search($day1, $days);
+		$yearkey1 = array_search($year1, $years);
+	}
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	printSelectInput("month1", $months, $monthkey1);
+	printSelectInput("day1", $days, $daykey1);
+	printSelectInput("year1", $years, $yearkey1);
+	print "<br>\n";
+	print "Select a ending date:<br>\n";
+	if(! $submitErr) {
+		$monthkey2 = array_search($month2, $months);
+		$daykey2 = array_search($day2, $days);
+		$yearkey2 = array_search($year2, $years);
+	}
+	print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	printSelectInput("month2", $months, $monthkey2);
+	printSelectInput("day2", $days, $daykey2);
+	printSelectInput("year2", $years, $yearkey2);
+	print "<br>\n";
+	if($viewmode >= ADMIN_FULL) {
+		print "Select an affiliation:<br>\n";
+		$affils = getAffiliations();
+		if(! array_key_exists($affilid, $affils))
+			$affilid = $user['affiliationid'];
+		$affils = array_reverse($affils, TRUE);
+		$affils[0] = "All";
+		$affils = array_reverse($affils, TRUE);
+		printSelectInput("affilid", $affils, $affilid);
+		print "<br>\n";
+	}
+	$cont = addContinuationsEntry('viewstats');
+	print "<INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "<INPUT type=submit value=Submit>\n";
+	print "</FORM>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn viewStatistics
+///
+/// \brief prints statistic information
+///
+////////////////////////////////////////////////////////////////////////////////
+function viewStatistics() {
+	global $submitErr, $submitErrMsg, $user, $viewmode;
+	define("30MIN", 1800);
+	define("1HOUR", 3600);
+	define("2HOURS", 7200);
+	define("4HOURS", 14400);
+	$month1 = processInputVar("month1", ARG_NUMERIC);
+	$day1 = processInputVar("day1", ARG_NUMERIC);
+	$year1 = processInputVar("year1", ARG_NUMERIC);
+	$month2 = processInputVar("month2", ARG_NUMERIC);
+	$day2 = processInputVar("day2", ARG_NUMERIC);
+	$year2 = processInputVar("year2", ARG_NUMERIC);
+	$affilid = processInputVar("affilid", ARG_NUMERIC, $user['affiliationid']);
+
+	$affils = getAffiliations();
+	if($viewmode < ADMIN_FULL ||
+	   ($affilid != 0 && ! array_key_exists($affilid, $affils)))
+		$affilid = $user['affiliationid'];
+
+	$start = "$year1-$month1-$day1 00:00:00";
+	$end = "$year2-$month2-$day2 23:59:59";
+	if(! checkdate($month1, $day1, $year1)) {
+		$submitErr |= STARTERR;
+		$submitErrMsg[STARTERR] = "The selected start date is not valid. Please "
+		                        . "select a valid date.<br>\n";
+	}
+	if(! checkdate($month2, $day2, $year2)) {
+		$submitErr |= ENDERR;
+		$submitErrMsg[ENDERR] = "The selected end date is not valid. Please "
+		                      . "select a valid date.<br>\n";
+	}
+	if(datetimeToUnix($start) > datetimeToUnix($end)) {
+		$submitErr |= ORDERERR;
+		$submitErrMsg[ORDERERR] = "The selected end date is before the selected "
+		                        . "start date.  Please select an end date equal "
+		                        . "to or greater than the start date.<br>\n";
+	}
+	if($submitErr) {
+		selectStatistics();
+		return;
+	}
+
+	$timestart = microtime(1);
+	print "<H2>Statistic Information</H2>\n";
+	print "<H3>Reservation information between $month1/$day1/$year1 and ";
+	print "$month2/$day2/$year2:\n";
+	print "</H3>\n";
+	$reloadid = getUserlistID('vclreload');
+	$query = "SELECT l.userid, "
+	       .        "l.nowfuture, "
+	       .        "UNIX_TIMESTAMP(l.start) AS start, "
+	       .        "(UNIX_TIMESTAMP(l.loaded) - UNIX_TIMESTAMP(l.start)) AS loadtime, "
+	       .        "UNIX_TIMESTAMP(l.finalend) AS finalend, "
+	       .        "l.wasavailable, "
+	       .        "l.ending, "
+	       .        "i.prettyname, "
+	       .        "o.prettyname AS OS "
+	       . "FROM log l, "
+	       .      "image i, "
+	       .      "user u, "
+	       .      "OS o "
+	       . "WHERE l.start >= '$start' AND "
+	       .       "l.finalend <= '$end' AND "
+	       .       "i.id = l.imageid AND "
+	       .       "i.OSid = o.id AND "
+	       .       "l.userid != $reloadid AND ";
+	if($affilid != 0)
+		$query .=   "u.affiliationid = $affilid AND ";
+	$query .=      "l.userid = u.id "
+	       . "ORDER BY i.prettyname";
+	$qh = doQuery($query, 275);
+
+	$totalreservations = 0;
+	$users = array();
+	$nows = 0;
+	$futures = 0;
+	$notavailable = 0;
+	$loadtimes = array("2less" => 0, "2more" => 0);
+	$ending = array("deleted" => 0,
+	                "released" => 0,
+	                "failed" => 0,
+	                "noack" => 0,
+	                "nologin" => 0,
+	                "timeout" => 0,
+	                "EOR" => 0,
+	                "none" => 0);
+	$imagecount = array();
+	$imageusers = array();
+	$imagehours = array();
+	$imageload2less = array();
+	$imageload2more = array();
+	$lengths = array("30min" => 0,
+	                 "1hour" => 0,
+	                 "2hours" => 0,
+	                 "4hours" => 0,
+	                 "4hrsplus" => 0);
+	$totalhours = 0;
+	$osusers = array();
+	while($row = mysql_fetch_assoc($qh)) {
+		if(! array_key_exists($row["prettyname"], $imageload2less))
+			$imageload2less[$row["prettyname"]] = 0;
+		if(! array_key_exists($row["prettyname"], $imageload2more))
+			$imageload2more[$row["prettyname"]] = 0;
+
+		# notavailable
+		if($row["wasavailable"] == 0) {
+			$notavailable++;
+		}
+		else {
+			$totalreservations++;
+
+			# load times
+			if($row['loadtime'] < 120) {
+				$loadtimes['2less']++;
+				# imageload2less
+				$imageload2less[$row['prettyname']]++;
+			}
+			else {
+				$loadtimes['2more']++;
+				# imageload2more
+				$imageload2more[$row['prettyname']]++;
+			}
+		}
+
+		# users
+		$users[$row['userid']] = 1;
+
+		# nowfuture
+		if($row["nowfuture"] == "now")
+			$nows++;
+		else
+			$futures++;
+
+		# ending
+		$ending[$row["ending"]]++;
+
+		# imagecount
+		if(! array_key_exists($row["prettyname"], $imagecount))
+			$imagecount[$row["prettyname"]] = 0;
+		$imagecount[$row["prettyname"]]++;
+
+		# imageusers
+		if(! array_key_exists($row["prettyname"], $imageusers))
+			$imageusers[$row["prettyname"]] = array();
+		$imageusers[$row['prettyname']][$row['userid']] = 1;
+
+		# lengths
+		$length = $row["finalend"] - $row["start"];
+		if($length <= 1800)
+			$lengths["30min"]++;
+		elseif($length <= 3600)
+			$lengths["1hour"]++;
+		elseif($length <= 7200)
+			$lengths["2hours"]++;
+		elseif($length <= 14400)
+			$lengths["4hours"]++;
+		else
+			$lengths["4hrsplus"]++;
+
+		# imagehours
+		if(! array_key_exists($row["prettyname"], $imagehours))
+			$imagehours[$row["prettyname"]] = 0;
+		$imagehours[$row["prettyname"]] += ($length / 3600);
+
+		# total hours
+		$totalhours += ($length / 3600);
+
+		# osusers
+		if(! array_key_exists($row["OS"], $osusers))
+			$osusers[$row["OS"]] = array();
+		$osusers[$row['OS']][$row['userid']] = 1;
+	}
+	print "<DIV align=center>\n";
+	print "<TABLE>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Total Reservations:</TH>\n";
+	print "    <TD>$totalreservations</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Total Hours Used:</TH>\n";
+	print "    <TD>" . (int)$totalhours . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>\"Now\" Reservations:</TH>\n";
+	print "    <TD>$nows</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>\"Later\" Reservations:</TH>\n";
+	print "    <TD>$futures</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Unavailable:</TH>\n";
+	print "    <TD>$notavailable</TD>\n";
+	print "  </TR>\n";
+	if($viewmode >= ADMIN_FULL) {
+		print "  <TR>\n";
+		print "    <TH align=right>Load times &lt; 2 minutes:</TH>\n";
+		print "    <TD>{$loadtimes['2less']}</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>Load times &gt;= 2 minutes:</TH>\n";
+		print "    <TD>{$loadtimes['2more']}</TD>\n";
+		print "  </TR>\n";
+	}
+	print "  <TR>\n";
+	print "    <TH align=right>Total Unique Users:</TH>\n";
+	print "    <TD>" . count($users) . "</TD>\n";
+	print "  </TR>\n";
+	foreach(array_keys($osusers) as $key) {
+		print "  <TR>\n";
+		print "    <TH align=right>Unique Users of $key:</TH>\n";
+		print "    <TD>" . count($osusers[$key]) . "</TD>\n";
+		print "  </TR>\n";
+	}
+	print "</TABLE>\n";
+
+	print "<TABLE>\n";
+	print "  <TR>\n";
+	print "    <TD></TD>\n";
+	print "    <TH>Reservations</TH>\n";
+	print "    <TH>Unique Users</TH>\n";
+	print "    <TH>Hours Used</TH>\n";
+	if($viewmode >= ADMIN_FULL) {
+		print "    <TH>&lt; 2 min load time</TH>\n";
+		print "    <TH>&gt;= 2 min load time</TH>\n";
+	}
+	print "  </TR>\n";
+	foreach($imagecount as $key => $value) {
+		print "  <TR>\n";
+		print "    <TH align=right>$key:</TH>\n";
+		print "    <TD align=center>$value</TD>\n";
+		print "    <TD align=center>" . count($imageusers[$key]) . "</TD>\n";
+		if(((int)$imagehours[$key]) == 0)
+			print "    <TD align=center>1</TD>\n";
+		else
+			print "    <TD align=center>" . (int)$imagehours[$key] . "</TD>\n";
+		if($viewmode >= ADMIN_FULL) {
+			print "    <TD align=center>{$imageload2less[$key]}</TD>\n";
+			print "    <TD align=center>{$imageload2more[$key]}</TD>\n";
+		}
+		print "  </TR>\n";
+	}
+	print "</TABLE>\n";
+
+	print "<H3>Durations:</H3>\n";
+	print "<TABLE>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>0 - 30 Min:</TH>\n";
+	print "    <TD>" . $lengths["30min"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>30 Min - 1 Hour:</TH>\n";
+	print "    <TD>" . $lengths["1hour"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>1 Hour - 2 Hours:</TH>\n";
+	print "    <TD>" . $lengths["2hours"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>2 Hours - 4 Hours:</TH>\n";
+	print "    <TD>" . $lengths["4hours"] . "</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>&gt; 4 Hours:</TH>\n";
+	print "    <TD>" . $lengths["4hrsplus"] . "</TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+
+	print "<H3>Ending information:</H3>\n";
+	print "<TABLE>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Deleted:</TH>\n";
+	print "    <TD>" . $ending["deleted"] . "</TD>\n";
+	print "    <TD rowspan=7><img src=\"images/blank.gif\" width=5></TD>\n";
+	print "    <TD>(Future reservation deleted before start time reached)</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Released:</TH>\n";
+	print "    <TD>" . $ending["released"] . "</TD>\n";
+	print "    <TD>(Reservation released before end time reached)</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Not Acknowledged:</TH>\n";
+	print "    <TD>" . $ending["noack"] . "</TD>\n";
+	print "    <TD>(\"Connect!\" button never clicked)</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>No Login:</TH>\n";
+	print "    <TD>" . $ending["nologin"] . "</TD>\n";
+	print "    <TD>(User never logged in)</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>End of Reservation:</TH>\n";
+	print "    <TD>" . $ending["EOR"] . "</TD>\n";
+	print "    <TD>(End of reservation reached)</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Timed Out:</TH>\n";
+	print "    <TD>" . $ending["timeout"] . "</TD>\n";
+	print "    <TD>(Disconnect and no reconnection within 15 minutes)</TD>\n";
+	print "  </TR>\n";
+	print "  <TR>\n";
+	print "    <TH align=right>Failed:</TH>\n";
+	print "    <TD>" . $ending["failed"] . "</TD>\n";
+	print "    <TD>(Reserved computer failed to get prepared for user)</TD>\n";
+	print "  </TR>\n";
+	print "</TABLE>\n";
+	print "<br>\n";
+
+	$unixstart = datetimeToUnix($start);
+	$unixend = datetimeToUnix($end);
+	$start = date('Y-m-d', $unixstart);
+	$end = date('Y-m-d', $unixend);
+	$cdata = array('start' => $start,
+	               'end' => $end,
+	               'affilid' => $affilid);
+	print "<H2>Reservations by Day</H2>\n";
+	$cont = addContinuationsEntry('statgraphday', $cdata);
+	print "<img src=" . BASEURL . SCRIPT . "?continuation=$cont>";
+
+	print "<H2>Max Concurrent Reservations By Day</H2>\n";
+	if($unixend - $unixstart > SECINMONTH)
+		print "(this graph only available for up to a month of data)<br>\n";
+	else {
+		$cont = addContinuationsEntry('statgraphdayconcuruser', $cdata);
+		print "<img src=" . BASEURL . SCRIPT . "?continuation=$cont>";
+	}
+
+	print "<H2>Max Concurrent Blade Reservations By Day</H2>\n";
+	if($unixend - $unixstart > SECINMONTH)
+		print "(this graph only available for up to a month of data)<br>\n";
+	else {
+		$cont = addContinuationsEntry('statgraphdayconcurblade', $cdata);
+		print "<img src=" . BASEURL . SCRIPT . "?continuation=$cont>";
+	}
+
+	print "<H2>Reservations by Hour</H2>\n";
+	print "(Averaged over the time period)<br><br>\n";
+	$cont = addContinuationsEntry('statgraphhour', $cdata);
+	print "<img src=" . BASEURL . SCRIPT . "?continuation=$cont>";
+	print "</div>\n";
+
+	$endtime = microtime(1);
+	$end = $endtime - $timestart;
+	#print "running time: $endtime - $timestart = $end<br>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn sendStatGraphDay()
+///
+/// \brief sends a graph image
+///
+////////////////////////////////////////////////////////////////////////////////
+function sendStatGraphDay() {
+	global $xaxislabels, $inContinuation;
+	if(! $inContinuation)
+		return;
+	$start = getContinuationVar("start");
+	$end = getContinuationVar("end");
+	$affilid = getContinuationVar("affilid");
+	$graphdata = getStatGraphDayData($start, $end, $affilid);
+	$count = count($graphdata["labels"]);
+	if($count < 8)
+		$labelinterval = 1;
+	else
+		$labelinterval = $count / 7;
+	$xaxislabels = $graphdata["labels"];
+	$graph = new Graph(300, 300, "auto");
+	$graph->SetScale("textlin");
+	$plot = new BarPlot($graphdata["points"]);
+	$graph->Add($plot);
+	$graph->xaxis->SetLabelFormatCallback('statXaxisDayCallback');
+	$graph->xaxis->SetLabelAngle(90);
+	$graph->xaxis->SetTextLabelInterval($labelinterval);
+	$graph->yaxis->SetTitle('Reservations with start time on given day', 
+	                        'high');
+	$graph->SetMargin(40,40,20,80);
+	$graph->Stroke();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getStatGraphDayData($start, $end, $affilid)
+///
+/// \param $start - starting day in YYYY-MM-DD format
+/// \param $end - ending day in YYYY-MM-DD format
+/// \param $affilid - affiliationid of data to gather
+///
+/// \return an array whose keys are the days (in YYYY-MM-DD format) between
+/// $start and $end, inclusive, and whose values are the number of reservations
+/// on each day
+///
+/// \brief queries the log table to get reservations between $start and $end
+/// and creates an array with the number of reservations on each day
+///
+////////////////////////////////////////////////////////////////////////////////
+function getStatGraphDayData($start, $end, $affilid) {
+	$startunix = datetimeToUnix($start . " 00:00:00");
+	$endunix = datetimeToUnix($end . " 23:59:59");
+
+	$data = array();
+	$data["points"] = array();
+	$data["labels"] = array();
+	$reloadid = getUserlistID('vclreload');
+	for($i = $startunix; $i < $endunix; $i += SECINDAY) {
+		array_push($data["labels"], date('Y-m-d', $i));
+		$startdt = unixToDatetime($i);
+		$enddt = unixToDatetime($i + SECINDAY);
+		if($affilid != 0) {
+			$query = "SELECT count(l.id) "
+			       . "FROM log l, "
+			       .      "user u "
+			       . "WHERE l.start >= '$startdt' AND "
+			       .       "l.start < '$enddt' AND "
+			       .       "l.userid != $reloadid AND "
+			       .       "l.wasavailable = 1 AND "
+			       .       "l.userid = u.id AND "
+			       .       "u.affiliationid = $affilid";
+		}
+		else {
+			$query = "SELECT count(l.id) "
+			       . "FROM log l "
+			       . "WHERE l.start >= '$startdt' AND "
+			       .       "l.start < '$enddt' AND "
+			       .       "l.userid != $reloadid AND "
+			       .       "l.wasavailable = 1";
+		}
+		$qh = doQuery($query, 295);
+		if($row = mysql_fetch_row($qh))
+			array_push($data["points"], $row[0]);
+		else
+			array_push($data["points"], 0);
+	}
+	return($data);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn statXaxisDayCallback($val)
+///
+/// \param $val - value passed in by SetLabelFormatCallback
+///
+/// \return day of week
+///
+/// \brief formats $val into day of week
+///
+////////////////////////////////////////////////////////////////////////////////
+function statXaxisDayCallback($val) {
+	global $xaxislabels;
+	if(array_key_exists((int)$val, $xaxislabels)) {
+		return date('n/d/Y', datetimeToUnix($xaxislabels[$val] . " 00:00:00")) . " ";
+	}
+	else {
+		return $val;
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn sendStatGraphHour()
+///
+/// \brief sends a graph image
+///
+////////////////////////////////////////////////////////////////////////////////
+function sendStatGraphHour() {
+	global $xaxislabels, $inContinuation;
+	if(! $inContinuation)
+		return;
+	$start = getContinuationVar("start");
+	$end = getContinuationVar("end");
+	$affilid = getContinuationVar("affilid");
+	$graphdata = getStatGraphHourData($start, $end, $affilid);
+	$graph = new Graph(300, 300, "auto");
+	$graph->SetScale("textlin");
+	$plot = new LinePlot($graphdata["points"]);
+	$graph->Add($plot);
+	$graph->xaxis->SetLabelFormatCallback('statXaxisHourCallback');
+	$graph->xaxis->SetLabelAngle(90);
+	$graph->xaxis->SetTextLabelInterval(2);
+	$graph->yaxis->SetTitle('Active reservations during given hour', 'high');
+	$graph->SetMargin(40,40,20,80);
+	$graph->Stroke();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getStatGraphHourData($start, $end, $affilid)
+///
+/// \param $start - starting day in YYYY-MM-DD format
+/// \param $end - ending day in YYYY-MM-DD format
+/// \param $affilid - affiliationid of data to gather
+///
+/// \return an array whose keys are the days (in YYYY-MM-DD format) between
+/// $start and $end, inclusive, and whose values are the number of reservations
+/// on each day
+///
+/// \brief queries the log table to get reservations between $start and $end
+/// and creates an array with the number of reservations on each day
+///
+////////////////////////////////////////////////////////////////////////////////
+function getStatGraphHourData($start, $end, $affilid) {
+	$startdt = $start . " 00:00:00";
+	$enddt = $end . " 23:59:59";
+	$startunix = datetimeToUnix($startdt);
+	$endunix = datetimeToUnix($enddt) + 1;
+	$enddt = unixToDatetime($endunix);
+	$days = ($endunix - $startunix) / SECINDAY;
+
+	$data = array();
+	$data["points"] = array();
+	for($i = 0; $i < 24; $i++) {
+		$data["points"][$i] = 0;
+	}
+
+	$reloadid = getUserlistID('vclreload');
+	if($affilid != 0) {
+		$query = "SELECT DATE_FORMAT(l.start, '%k') AS shour, "
+		       .        "DATE_FORMAT(l.start, '%i') AS smin, "
+		       .        "DATE_FORMAT(l.finalend, '%k') AS ehour, "
+		       .        "DATE_FORMAT(l.finalend, '%i') AS emin "
+		       . "FROM log l, "
+		       .      "user u "
+		       . "WHERE l.start < '$enddt' AND "
+		       .       "l.finalend > '$startdt' AND "
+		       .       "l.userid != $reloadid AND "
+		       .       "l.userid = u.id AND "
+		       .       "l.wasavailable = 1 AND "
+		       .       "u.affiliationid = $affilid";
+	}
+	else {
+		$query = "SELECT DATE_FORMAT(l.start, '%k') AS shour, "
+		       .        "DATE_FORMAT(l.start, '%i') AS smin, "
+		       .        "DATE_FORMAT(l.finalend, '%k') AS ehour, "
+		       .        "DATE_FORMAT(l.finalend, '%i') AS emin "
+		       . "FROM log l "
+		       . "WHERE l.start < '$enddt' AND "
+		       .       "l.finalend > '$startdt' AND "
+		       .       "l.userid != $reloadid AND "
+		       .       "l.wasavailable = 1";
+	}
+	$qh = doQuery($query, 296);
+	$count = 0;
+	while($row = mysql_fetch_assoc($qh)) {
+		$startmin = ($row['shour'] * 60) + $row['smin'];
+		$endmin = ($row['ehour'] * 60) + $row['emin'];
+
+		for($binstart = 0, $binend = 60, $binindex = 0; 
+		   $binend <= 1440;
+		   $binstart += 60, $binend += 60, $binindex++) {
+			if($binend <= $startmin)
+				continue;
+			elseif($startmin < $binend &&
+				$endmin > $binstart) {
+				$data["points"][$binindex]++;
+			}
+			elseif($binstart >= $endmin)
+				break;
+		}
+	}
+
+	# comment this to change graph to be aggregate instead of average
+	foreach($data["points"] as $key => $val)
+		$data["points"][$key] = $val / $days;
+
+	return($data);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn statXaxisHourCallback($val)
+///
+/// \param $val - value passed in by SetLabelFormatCallback
+///
+/// \return day of week
+///
+/// \brief formats $val into day of week
+///
+////////////////////////////////////////////////////////////////////////////////
+function statXaxisHourCallback($val) {
+	if($val == 0) {
+		return "12 am ";
+	}
+	elseif($val < 12) {
+		return "$val am ";
+	}
+	elseif($val == 12) {
+		return "$val pm ";
+	}
+	else {
+		return $val - 12 . " pm ";
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn sendStatGraphDayConUsers()
+///
+/// \brief sends a graph image
+///
+////////////////////////////////////////////////////////////////////////////////
+function sendStatGraphDayConUsers() {
+	global $xaxislabels, $inContinuation;
+	if(! $inContinuation)
+		return;
+	$start = getContinuationVar("start");
+	$end = getContinuationVar("end");
+	$affilid = getContinuationVar("affilid");
+	$graphdata = getStatGraphDayConUsersData($start, $end, $affilid);
+	$count = count($graphdata["labels"]);
+	if($count < 8)
+		$labelinterval = 1;
+	else
+		$labelinterval = $count / 7;
+	$xaxislabels = $graphdata["labels"];
+	$graph = new Graph(300, 300, "auto");
+	$graph->SetScale("textlin");
+	$plot = new BarPlot($graphdata["points"]);
+	$graph->Add($plot);
+	$graph->xaxis->SetLabelFormatCallback('statXaxisDayConUsersCallback');
+	$graph->xaxis->SetLabelAngle(90);
+	$graph->xaxis->SetTextLabelInterval($labelinterval);
+	$graph->yaxis->SetTitle('Maximum concurrent reservations per day', 
+	                        'high');
+	$graph->SetMargin(40,40,20,80);
+	$graph->Stroke();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getStatGraphDayConUsersData($start, $end, $affilid)
+///
+/// \param $start - starting day in YYYY-MM-DD format
+/// \param $end - ending day in YYYY-MM-DD format
+/// \param $affilid - affiliationid of data to gather
+///
+/// \return an array whose keys are the days (in YYYY-MM-DD format) between
+/// $start and $end, inclusive, and whose values are the max concurrent users
+/// on each day
+///
+/// \brief queries the log table to get reservations between $start and $end
+/// and creates an array with the max concurrent users per day
+///
+////////////////////////////////////////////////////////////////////////////////
+function getStatGraphDayConUsersData($start, $end, $affilid) {
+	$startdt = $start . " 00:00:00";
+	$enddt = $end . " 23:59:59";
+	$startunix = datetimeToUnix($startdt);
+	$endunix = datetimeToUnix($enddt) + 1;
+	$days = ($endunix - $startunix) / SECINDAY;
+
+	$data = array();
+	$data["points"] = array();
+	$data["labels"] = array();
+
+	$reloadid = getUserlistID('vclreload');
+	for($daystart = $startunix; $daystart < $endunix; $daystart += SECINDAY) {
+		array_push($data["labels"], date('Y-m-d', $daystart));
+		$count = array();
+		for($j = 0; $j < 24; $j++) {
+			$count[$j] = 0;
+		}
+
+		$startdt = unixToDatetime($daystart);
+		$enddt = unixToDatetime($daystart + SECINDAY);
+		if($affilid != 0) {
+			$query = "SELECT UNIX_TIMESTAMP(l.start) AS start, "
+			       .        "UNIX_TIMESTAMP(l.finalend) AS end "
+			       . "FROM log l, "
+			       .      "user u "
+			       . "WHERE l.start < '$enddt' AND "
+			       .       "l.finalend > '$startdt' AND "
+			       .       "l.userid != $reloadid AND "
+			       .       "l.userid = u.id AND "
+				    .       "u.affiliationid = $affilid";
+		}
+		else {
+			$query = "SELECT UNIX_TIMESTAMP(l.start) AS start, "
+			       .        "UNIX_TIMESTAMP(l.finalend) AS end "
+			       . "FROM log l "
+			       . "WHERE l.start < '$enddt' AND "
+			       .       "l.finalend > '$startdt' AND "
+			       .       "l.userid != $reloadid";
+		}
+		$qh = doQuery($query, 101);
+		while($row = mysql_fetch_assoc($qh)) {
+			$unixstart = $row["start"];
+			$unixend = $row["end"];
+			for($binstart = $daystart, $binend = $daystart + 3600, $binindex = 0;
+			   $binstart <= $unixend && $binend <= ($daystart + SECINDAY);
+			   $binstart += 3600, $binend += 3600, $binindex++) {
+				if($binend <= $unixstart) {
+					continue;
+				}
+				elseif($unixstart < $binend &&
+					$unixend > $binstart) {
+					$count[$binindex]++;
+				}
+				elseif($binstart >= $unixend) {
+					break;
+				}
+			}
+		}
+		rsort($count);
+		array_push($data["points"], $count[0]);
+	}
+	return($data);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn statXaxisDayConUsersCallback($val)
+///
+/// \param $val - value passed in by SetLabelFormatCallback
+///
+/// \return day of week
+///
+/// \brief formats $val into day of week
+///
+////////////////////////////////////////////////////////////////////////////////
+function statXaxisDayConUsersCallback($val) {
+	global $xaxislabels;
+	if(array_key_exists((int)$val, $xaxislabels)) {
+		return date('n/d/Y', datetimeToUnix($xaxislabels[$val] . " 00:00:00")) . " ";
+	}
+	else {
+		return $val;
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn sendStatGraphConBladeUser()
+///
+/// \brief sends a graph image of max concurrent users of blades per day
+///
+////////////////////////////////////////////////////////////////////////////////
+function sendStatGraphConBladeUser() {
+	global $xaxislabels, $inContinuation;
+	if(! $inContinuation)
+		return;
+	$start = getContinuationVar("start");
+	$end = getContinuationVar("end");
+	$affilid = getContinuationVar("affilid");
+	$graphdata = getStatGraphConBladeUserData($start, $end, $affilid);
+	$count = count($graphdata["labels"]);
+	if($count < 8)
+		$labelinterval = 1;
+	else
+		$labelinterval = $count / 7;
+	$xaxislabels = $graphdata["labels"];
+	$graph = new Graph(300, 300, "auto");
+	$graph->SetScale("textlin");
+	$plot = new BarPlot($graphdata["points"]);
+	$graph->Add($plot);
+	$graph->xaxis->SetLabelFormatCallback('statXaxisDayConUsersCallback');
+	$graph->xaxis->SetLabelAngle(90);
+	$graph->xaxis->SetTextLabelInterval($labelinterval);
+	$graph->yaxis->SetTitle('Maximum concurrent reservations per day', 
+	                        'high');
+	$graph->SetMargin(40,40,20,80);
+	$graph->Stroke();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn getStatGraphConBladeUserData($start, $end, $affilid)
+///
+/// \param $start - starting day in YYYY-MM-DD format
+/// \param $end - ending day in YYYY-MM-DD format
+/// \param $affilid - affiliationid of data to gather
+///
+/// \return an array whose keys are the days (in YYYY-MM-DD format) between
+/// $start and $end, inclusive, and whose values are the max concurrent users
+/// of blades on each day
+///
+/// \brief queries the log table to get reservations between $start and $end
+/// and creates an array with the max concurrent users of blades per day
+///
+////////////////////////////////////////////////////////////////////////////////
+function getStatGraphConBladeUserData($start, $end, $affilid) {
+	$startdt = $start . " 00:00:00";
+	$enddt = $end . " 23:59:59";
+	$startunix = datetimeToUnix($startdt);
+	$endunix = datetimeToUnix($enddt) + 1;
+	$days = ($endunix - $startunix) / SECINDAY;
+
+	$data = array();
+	$data["points"] = array();
+	$data["labels"] = array();
+
+	$reloadid = getUserlistID('vclreload');
+	for($daystart = $startunix; $daystart < $endunix; $daystart += SECINDAY) {
+		array_push($data["labels"], date('Y-m-d', $daystart));
+		$count = array();
+		for($j = 0; $j < 24; $j++) {
+			$count[$j] = 0;
+		}
+		$startdt = unixToDatetime($daystart);
+		$enddt = unixToDatetime($daystart + SECINDAY);
+		if($affilid != 0) {
+			$query = "SELECT l.start AS start, "
+			       .        "l.finalend AS end "
+			       . "FROM log l, "
+			       .      "sublog s, "
+			       .      "computer c, "
+			       .      "user u "
+			       . "WHERE l.userid = u.id AND "
+			       .       "l.start < '$enddt' AND "
+			       .       "l.finalend > '$startdt' AND "
+			       .       "s.logid = l.id AND "
+			       .       "s.computerid = c.id AND "
+			       .       "l.wasavailable = 1 AND "
+			       .       "c.type = 'blade' AND "
+			       .       "l.userid != $reloadid AND "
+			       .       "u.affiliationid = $affilid";
+		}
+		else {
+			$query = "SELECT l.start AS start, "
+			       .        "l.finalend AS end "
+			       . "FROM log l, "
+			       .      "sublog s, "
+			       .      "computer c "
+			       . "WHERE l.start < '$enddt' AND "
+			       .       "l.finalend > '$startdt' AND "
+			       .       "s.logid = l.id AND "
+			       .       "s.computerid = c.id AND "
+			       .       "l.wasavailable = 1 AND "
+			       .       "c.type = 'blade' AND "
+			       .       "l.userid != $reloadid";
+		}
+		$qh = doQuery($query, 101);
+		while($row = mysql_fetch_assoc($qh)) {
+			$unixstart = datetimeToUnix($row["start"]);
+			$unixend = datetimeToUnix($row["end"]);
+			for($binstart = $daystart, $binend = $daystart + 3600, $binindex = 0;
+			   $binstart <= $unixend && $binend <= ($daystart + SECINDAY);
+			   $binstart += 3600, $binend += 3600, $binindex++) {
+				if($binend <= $unixstart) {
+					continue;
+				}
+				elseif($unixstart < $binend &&
+					$unixend > $binstart) {
+					$count[$binindex]++;
+				}
+				elseif($binstart >= $unixend) {
+					break;
+				}
+			}
+		}
+		rsort($count);
+		array_push($data["points"], $count[0]);
+	}
+	return($data);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn statXaxisConBladeUserCallback($val)
+///
+/// \param $val - value passed in by SetLabelFormatCallback
+///
+/// \return day of week
+///
+/// \brief formats $val into day of week
+///
+////////////////////////////////////////////////////////////////////////////////
+function statXaxisConBladeUserCallback($val) {
+	global $xaxislabels;
+	if(array_key_exists((int)$val, $xaxislabels)) {
+		return date('n/d/Y', datetimeToUnix($xaxislabels[$val] . " 00:00:00")) . " ";
+	}
+	else {
+		return $val;
+	}
+}
+?>

Added: incubator/vcl/tags/import/web/.ht-inc/userpreferences.php
URL: http://svn.apache.org/viewvc/incubator/vcl/tags/import/web/.ht-inc/userpreferences.php?rev=726079&view=auto
==============================================================================
--- incubator/vcl/tags/import/web/.ht-inc/userpreferences.php (added)
+++ incubator/vcl/tags/import/web/.ht-inc/userpreferences.php Fri Dec 12 10:20:10 2008
@@ -0,0 +1,564 @@
+<?php
+/*
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+*/
+
+/**
+ * \file
+ */
+
+/// signifies an error with submitted preferred name
+define("PREFNAMEERR", 1);
+/// signifies an error with submitted width
+define("WIDTHERR", 1 << 1);
+/// signifies an error with submitted height
+define("HEIGHTERR", 1 << 2);
+/// signifies an error with submitted viewasuser id
+define("VIEWASUSERERR", 1 << 3);
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn userpreferences()
+///
+/// \brief prints a page for a user to edit his preferences
+///
+////////////////////////////////////////////////////////////////////////////////
+function userpreferences() {
+	global $user, $submitErr, $viewmode, $mode;
+	if($submitErr) {
+		$data = processUserPrefsInput(0);
+		$data['affiliation'] = $user['affiliation'];
+	}
+	else {
+		$data = $user;
+		if($data["width"] == 0)
+			$data["resolution"] = "Full Screen";
+		else
+			$data["resolution"] = $user["width"] . "x" . $user["height"];
+	}
+
+	$adminleveldeveloper = 0;
+	if(array_key_exists('WRAP_USERID', $_SERVER)) {
+		$testid = getAffiliationID("NCSU");
+		if(! empty($testid)) {
+			$testuser = getUserInfo("{$_SERVER['WRAP_USERID']}@NCSU");
+			if($testuser['adminlevelid'] == ADMIN_DEVELOPER)
+				$adminleveldeveloper = 1;
+		}
+	}
+
+
+	print "<H2 align=center>User Preferences</H2>\n";
+	print "<div align=center id=status class=visible>\n";
+	if($mode == "submituserprefs") {
+		print "<font color=green>User preferences successfully updated</font><br>\n";
+	}
+	print "</div>\n";
+	print "<table id=layouttable summary=\"\">\n";
+	print "  <TR>\n";
+	print "    <TD>\n";
+	print "      <div id=preflinks class=hidden>\n";
+	print "      <ul class=preferenceslist>\n";
+	print "      <li><a href=#personal onclick=\"";
+	print "show('personal'); return false;\">Personal&nbsp;Information</a>";
+	print "</li>\n";
+	print "      <li><a href=#rdpfile onclick=\"";
+	print "show('rdpfile'); return false;\">RDP&nbsp;File&nbsp;Preferences</a>";
+	print "</li>\n";
+	print "      <li><a href=#uiprefs onclick=\"javascript:show('uiprefs'); ";
+	print "return false\">General&nbsp;Preferences</a></li>\n";
+	if($adminleveldeveloper) {
+		print "      <li><a href=#viewmode onclick=\"javascript:";
+		print "show('viewmode'); return false\">View&nbsp;Mode</a></li>\n";
+	}
+	print "      </ul>\n";
+	print "      </div>\n";
+	print "    </TD>\n";
+	print "    <TD rowspan=2 width=50px></TD>\n";
+	print "    <TD rowspan=2>\n";
+	print "      <fieldset id=personal class=shown>\n";
+	print "      <legend>Personal</legend>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "      <table summary=\"displays your personal information\">\n";
+	print "        <TR>\n";
+	print "          <TH align=right>First Name<a href=#updateinfo>*</a>:</TH>\n";
+	print "          <TD>" . $user["firstname"] . "</TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Middle Name<a href=#updateinfo>*</a>:</TH>\n";
+	print "          <TD>" . $user["middlename"] . "</TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Last Name<a href=#updateinfo>*</a>:</TH>\n";
+	print "          <TD>" . $user["lastname"] . "</TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Preferred Name:</TH>\n";
+	print "          <TD><label class=hidden for=preferredname>Preferred Name</label>\n";
+	print "              <INPUT type=text name=preferredname maxlength=100 ";
+	print "size=15 value=\"" . $data["preferredname"] . "\"></TD>\n";
+	print "          <TD>";
+	printSubmitErr(PREFNAMEERR);
+	print "</TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Email Address<a href=#updateinfo>*</a>:</TH>\n";
+	print "          <TD>" . $user["email"] . "</TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "      </table>\n";
+	$updateText = getAffiliationDataUpdateText($user['affiliationid']);
+	print "<a name=updateinfo></a>{$updateText[$user['affiliationid']]}";
+	print "<br><br>\n";
+	$cont = addContinuationsEntry('confirmpersonalprefs', array(), SECINDAY, 1, 1, 1);
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <div align=center>\n";
+	print "      <INPUT type=submit value=\"Submit Changes\">\n";
+	print "      </div>\n";
+	print "      </FORM>\n";
+	print "      </fieldset>\n";
+
+	print "      <fieldset id=rdpfile class=visible>\n";
+	print "      <legend>RDP</legend>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	print "      <table summary=\"lists adjustable preferences for the RDP ";
+	print "file that is sent when you click the Get RDP File button on the ";
+	print "Connect! page\">\n";
+	print "        <TR>\n";
+	print "          <TD colspan=3><small>Try decreasing <em>Resolution</em> or <em>";
+	print "Color Depth</em> to<br>speed up your connection if things seem ";
+	print "slow<br>when connected to a remote computer.</small></TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Resolution:</TH>\n";
+	$resolutionArray = array("Full Screen" => "Full Screen",
+	                         "1920x1440" => "1920x1440",
+	                         "1600x1200" => "1600x1200",
+	                         "1280x1024" => "1280x1024",
+	                         "1152x864" => "1152x864",
+	                         "1024x768" => "1024x768",
+	                         "800x600" => "800x600",
+	                         "640x480" => "640x480",
+	                         "1680x1050" => "1680x1050",
+	                         "1600x1024" => "1600x1024",
+	                         "1440x900" => "1440x900",
+	                         "1280x854" => "1280x854",
+	                         "1280x768" => "1280x768",
+	                         "1024x576" => "1024x576");
+	print "          <TD>\n";
+	printSelectInput("resolution", $resolutionArray, $data["resolution"]);
+	print "          </TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Color Depth:</TH>\n";
+	print "          <TD>\n";
+	#$colordepth = array("8" => "8", "16" => "16", "24" => "24");
+	$colordepth = array("8" => "8", "16" => "16", "24" => "24", "32" => "32 (Vista only)");
+	printSelectInput("bpp", $colordepth, $data["bpp"]);
+	print "          </TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Audio:</TH>\n";
+	print "          <TD>\n";
+	$audio = array("none" => "None", "local" => "Use my speakers");
+	printSelectInput("audiomode", $audio, $data["audiomode"]);
+	print "          </TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Map Local Drives:</TH>\n";
+	print "          <TD>\n";
+	$yesno = array(1 => "Yes", 0 => "No");
+	printSelectInput("mapdrives", $yesno, $data["mapdrives"]);
+	print "          </TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Map Local Printers:</TH>\n";
+	print "          <TD>\n";
+	printSelectInput("mapprinters", $yesno, $data["mapprinters"]);
+	print "          </TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "        <TR>\n";
+	print "          <TH align=right>Map Local Serial Ports:</TH>\n";
+	print "          <TD>\n";
+	printSelectInput("mapserial", $yesno, $data["mapserial"]);
+	print "          </TD>\n";
+	print "          <TD></TD>\n";
+	print "        </TR>\n";
+	print "      </table>\n";
+	$cont = addContinuationsEntry('confirmrdpprefs', array(), SECINDAY, 1, 1, 1);
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <div align=center>\n";
+	print "      <INPUT type=submit value=\"Submit Changes\">\n";
+	print "      </div>\n";
+	print "      </FORM>\n";
+	print "      </fieldset>\n";
+
+	print "      <div id=uiprefs class=visible>\n";
+	print "      <fieldset>\n";
+	print "      <legend>General Preferences</legend>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cdata = array();
+	if(in_array("userGrant", $user["privileges"])) {
+		if($user['showallgroups']) {
+			$selected['affiliation'] = '';
+			$selected['allgroups'] = 'checked';
+		}
+		else {
+			$selected['affiliation'] = 'checked';
+			$selected['allgroups'] = '';
+		}
+		print "      <p>View User Groups:<br>\n";
+		print "      <INPUT type=radio id=r1 name=groupview value=affiliation ";
+		print "{$selected['affiliation']}><label for=r1>matching my affiliation";
+		print "</label><br>\n";
+		print "      <INPUT type=radio id=r2 name=groupview value=allgroups ";
+		print "{$selected['allgroups']}><label for=r2>from all affiliations";
+		print "</label></p>\n";
+	}
+	else
+		$cdata['groupview'] = 'affiliation';
+	if($user['emailnotices']) {
+		$selected['enabled'] = 'checked';
+		$selected['disabled'] = '';
+	}
+	else {
+		$selected['enabled'] = '';
+		$selected['disabled'] = 'checked';
+	}
+	print "      <p>Send email notifications about reservations:<br>\n";
+	print "      <INPUT type=radio id=r3 name=emailnotify value=2 ";
+	print "{$selected['enabled']}><label for=r3>Enabled";
+	print "</label><br>\n";
+	print "      <INPUT type=radio id=r4 name=emailnotify value=1 ";
+	print "{$selected['disabled']}><label for=r4>Disabled";
+	print "</label></p>\n";
+	$cont = addContinuationsEntry('submitgeneralprefs', $cdata, SECINDAY, 1, 0);
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=\"Submit General Preferences\">\n";
+	print "      </FORM>\n";
+	print "      </fieldset>\n";
+	print "      </div>\n";
+	print "      <div id=viewmode class=visible>\n";
+	if($adminleveldeveloper) {
+		print "      <fieldset>\n";
+		print "      <legend>View Mode</legend>\n";
+		print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+		if($viewmode == ADMIN_FULL) {
+			$selected[ADMIN_NONE] = "";
+			$selected[ADMIN_FULL] = "checked";
+			$selected[ADMIN_DEVELOPER] = "";
+		}
+		elseif($viewmode == ADMIN_DEVELOPER) {
+			$selected[ADMIN_NONE] = "";
+			$selected[ADMIN_FULL] = "";
+			$selected[ADMIN_DEVELOPER] = "checked";
+		}
+		else {
+			$selected[ADMIN_NONE] = "checked";
+			$selected[ADMIN_FULL] = "";
+			$selected[ADMIN_DEVELOPER] = "";
+		}
+		if($user["adminlevelid"] != ADMIN_NONE) {
+			print "      <p>View site as:<br>\n";
+			print "      <INPUT type=radio name=viewmode value=" . ADMIN_NONE . " ";
+			print $selected[ADMIN_NONE] . ">Normal User<br>\n";
+			if($user["adminlevel"] == "full" || $user["adminlevel"] == "developer") {
+				print "      <INPUT type=radio name=viewmode value=" . ADMIN_FULL . " ";
+				print $selected[ADMIN_FULL] . ">Admin Level<br>\n";
+			}
+			if($user["adminlevel"] == "developer") {
+				print "      <INPUT type=radio name=viewmode value=" . ADMIN_DEVELOPER . " ";
+				print $selected[ADMIN_DEVELOPER] . ">Developer Level<br>\n";
+			}
+			print "      </p>\n";
+		}
+		print "      View As User: <INPUT type=text name=viewasuser  ";
+		if(! array_key_exists('unityid', $data))
+			print "size=20 value=\"{$user["unityid"]}@{$user['affiliation']}\">\n";
+		else
+			print "size=20 value=\"{$data["unityid"]}@{$data['affiliation']}\">\n";
+		printSubmitErr(VIEWASUSERERR);
+		print "<br>\n";
+		$cont = addContinuationsEntry('submitviewmode', array(), SECINDAY, 1, 0);
+		print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+		print "      <INPUT type=submit value=\"Submit View Mode\">\n";
+		print "      </FORM>\n";
+		print "      </fieldset>\n";
+	}
+	print "      </div>\n";
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</table>\n";
+	printUserprefJavascript();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn confirmUserPrefs($type)
+///
+/// \param $type - 0 for personal prefs, 1 for rdp prefs
+///
+/// \brief prints a page for user to confirm changes to preferences
+///
+////////////////////////////////////////////////////////////////////////////////
+function confirmUserPrefs($type) {
+	global $submitErr;
+
+	$data = processUserPrefsInput(1);
+
+	if($submitErr) {
+		userpreferences();
+		return;
+	}
+
+	if($data["audiomode"] == "none")
+		$audio = "None";
+	else
+		$audio = "Use my speakers";
+	if($data["mapdrives"] == 0)
+		$drives = "No";
+	else
+		$drives = "Yes";
+	if($data["mapprinters"] == 0)
+		$printers = "No";
+	else
+		$printers = "Yes";
+	if($data["mapserial"] == 0)
+		$serial = "No";
+	else
+		$serial = "Yes";
+
+	print "<DIV align=center>\n";
+	if($type == 0) {
+		print "<H2>Personal Information</H2>\n";
+		print "<H3>Submit the following changes?</H3>\n";
+		print "<table>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>Preferred Name:</TH>\n";
+		print "    <TD>" . $data["preferredname"] . "</TD>\n";
+		print "  </TR>\n";
+		print "</table>\n";
+	}
+	elseif($type == 1) {
+		print "<H2>RDP File Preferences</H2>\n";
+		print "<H3>Submit the following changes?</H3>\n";
+		print "<table>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>Resolution:</TH>\n";
+		print "    <TD>" . $data["resolution"] . "</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>Color Depth:</TH>\n";
+		$colordepth = array("8" => "8", "16" => "16", "24" => "24", "32" => "32 (Vista only)");
+		print "    <TD>" . $colordepth[$data["bpp"]] . "</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>Audio:</TH>\n";
+		print "    <TD>$audio</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>Map Local Drives:</TH>\n";
+		print "    <TD>$drives</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>Map Local Printers:</TH>\n";
+		print "    <TD>$printers</TD>\n";
+		print "  </TR>\n";
+		print "  <TR>\n";
+		print "    <TH align=right>Map Local Serial Ports:</TH>\n";
+		print "    <TD>$serial</TD>\n";
+		print "  </TR>\n";
+		print "</table>\n";
+	}
+	print "<table>\n";
+	print "  <TR>\n";
+	print "    <TD>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cont = addContinuationsEntry('submituserprefs', $data, SECINWEEK, 0, 0);
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=Submit>\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "    <TD>\n";
+	print "      <FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n";
+	$cont = addContinuationsEntry('userpreferences');
+	print "      <INPUT type=hidden name=continuation value=\"$cont\">\n";
+	print "      <INPUT type=submit value=Cancel>\n";
+	print "      </FORM>\n";
+	print "    </TD>\n";
+	print "  </TR>\n";
+	print "</table>\n";
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitUserPrefs()
+///
+/// \brief updates user prefs and prints a page informing the user of success
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitUserPrefs() {
+	global $user;
+	$data = getContinuationVar();
+	if($data["resolution"] == "Full Screen") {
+		$width = 0;
+		$height = 0;
+	}
+	else
+		list($width, $height) = explode('x', $data["resolution"]);
+	if(updateUserPrefs($user['id'], $data["preferredname"], $width, $height, 
+	                   $data["bpp"], $data["audiomode"], $data["mapdrives"],
+	                   $data["mapprinters"], $data["mapserial"])) {
+	}
+	$user = getUserInfo($user["id"]);
+	$_SESSION['user'] = $user;
+	userpreferences();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn submitGeneralPreferences()
+///
+/// \brief updates user general preferences and calls userpreferences
+///
+////////////////////////////////////////////////////////////////////////////////
+function submitGeneralPreferences() {
+	global $user, $HTMLheader, $printedHTMLheader, $mode, $viewmode;
+	$groupview = getContinuationVar('groupview', processInputVar('groupview', ARG_STRING));
+	$emailnotify = processInputVar('emailnotify', ARG_NUMERIC);
+	if($groupview != 'affiliation' && $groupview != 'allgroups') {
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		userpreferences();
+		return;
+	}
+	if($emailnotify != 1 && $emailnotify != 2) {
+		$printedHTMLheader = 1;
+		print $HTMLheader;
+		userpreferences();
+		return;
+	}
+	if(($groupview == 'allgroups' && $user['showallgroups'] == 0) ||
+	   ($groupview == 'affiliation' && $user['showallgroups'] == 1)) {
+		if($groupview == 'allgroups')
+			$value = 1;
+		else
+			$value = 0;
+		$query = "UPDATE user SET showallgroups = $value WHERE id = {$user['id']}";
+		doQuery($query, 101);
+		$_SESSION['user']['showallgroups'] = $value;
+		$user['showallgroups'] = $value;
+	}
+	if(($user['emailnotices'] == 1 && $emailnotify == 1) ||
+	   ($user['emailnotices'] == 0 && $emailnotify == 2)) {
+		$newval = $emailnotify - 1;
+		$query = "UPDATE user SET emailnotices = $newval WHERE id = {$user['id']}";
+		doQuery($query, 101);
+		$_SESSION['user']['emailnotices'] = $newval;
+		$user['emailnotices'] = $newval;
+	}
+	print $HTMLheader;
+	$printedHTMLheader = 1;
+	$mode = 'submituserprefs';
+	# FIXME might need to clear some cache items for cached lists of groups
+	userpreferences();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn processUserPrefsInput($checks)
+///
+/// \param $checks - (optional) 1 to perform validation, 0 not to
+///
+/// \return an array with the following indexes:\n
+/// preferredname, resolution, bpp, audiomode, mapdrives, mapprinters,
+/// mapserial, unityid
+///
+/// \brief validates input from the previous form; if anything was improperly
+/// submitted, sets submitErr and submitErrMsg
+///
+////////////////////////////////////////////////////////////////////////////////
+function processUserPrefsInput($checks=1) {
+	global $submitErr, $submitErrMsg, $user;
+	$return = array();
+
+	$defaultres = $user["width"] . 'x' . $user["height"];
+	$return["preferredname"] = processInputVar("preferredname" , ARG_STRING, $user["preferredname"]);
+	$return["resolution"] = processInputVar("resolution" , ARG_STRING, $defaultres);
+	$return["bpp"] = processInputVar("bpp" , ARG_NUMERIC, $user["bpp"]);
+	$return["audiomode"] = processInputVar("audiomode" , ARG_STRING, $user["audiomode"]);
+	$return["mapdrives"] = processInputVar("mapdrives" , ARG_NUMERIC, $user["mapdrives"]);
+	$return["mapprinters"] = processInputVar("mapprinters" , ARG_NUMERIC, $user["mapprinters"]);
+	$return["mapserial"] = processInputVar("mapserial" , ARG_NUMERIC, $user["mapserial"]);
+	if(array_key_exists('WRAP_USERID', $_SERVER) && ($user['unityid'] != $_SERVER["WRAP_USERID"]))
+		$return["unityid"] = processInputVar("viewasuser" , ARG_STRING, "{$user["unityid"]}@{$user['affiliation']}");
+	else
+		$return['unityid'] = "{$user['unityid']}@{$user['affiliation']}";
+
+	if(! $checks) {
+		return $return;
+	}
+
+	if(strlen($return["preferredname"]) > 25) {
+	   $submitErr |= PREFNAMEERR;
+	   $submitErrMsg[PREFNAMEERR] = "Preferred name can only be up to 25 characters";
+	}
+	if(! ereg('^[a-zA-Z ]*$', $return["preferredname"])) {
+	   $submitErr |= PREFNAMEERR;
+	   $submitErrMsg[PREFNAMEERR] = "Preferred name can only contain letters and spaces";
+	}
+	if(array_key_exists('unityid', $return) &&
+	   ! validateUserid($return['unityid'])) {
+	   $submitErr |= VIEWASUSERERR;
+	   $submitErrMsg[VIEWASUSERERR] = "Invalid user id";
+	}
+	return $return;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// \fn printUserprefJavascript()
+///
+/// \brief prints javascript used in user preferences page
+///
+////////////////////////////////////////////////////////////////////////////////
+function printUserprefJavascript() {
+	print <<<HTMLdone
+<script type="text/javascript">
+function show(id) {
+	document.getElementById("personal").className = "hidden";
+	document.getElementById("rdpfile").className = "hidden";
+	document.getElementById("uiprefs").className = "hidden";
+	document.getElementById("viewmode").className = "hidden";
+	document.getElementById("status").className = "hidden";
+	document.getElementById(id).className = "shown";
+}
+show("personal");
+document.getElementById("preflinks").className = "shown";
+document.getElementById("status").className = "visible";
+</script>
+
+HTMLdone;
+}
+?>