Author: jfthomps Date: Tue Aug 31 20:41:32 2010 New Revision: 991322 URL: http://svn.apache.org/viewvc?rev=991322&view=rev Log: VCL-274 check for SQL injection/XSS
found some places where $_POST was being used in schedules.php with the possiblity of poor validation; I didn't fully trace it out because I was already wanting to change the way schedule times were modified to use ajax instead of a series of page loads utils.php: modified getDojoHTML - added stuff for editSchedule and submitAddSchedule states.php: removed submitScheduleTime; added AJgetScheduleTimesData and AJsaveScheduleTimes schedules.php: -modified editOrAddSchedule - changed form to have a dojox DataGrid to manage the schedule times -added AJgetScheduleTimesData - sends JSON data of schedule times to initially populate the datagrid -modified processScheduleInput - removed code that dealt with schedule times -removed printStartEndTimeForm -removed printStartEndTimeForm2 -added AJsaveScheduleTimes - updates schedule times in database -removed submitScheduleTime css/vcl.css: added #savestatus Added: incubator/vcl/trunk/web/js/schedules.js Modified: incubator/vcl/trunk/web/.ht-inc/schedules.php incubator/vcl/trunk/web/.ht-inc/states.php incubator/vcl/trunk/web/.ht-inc/utils.php incubator/vcl/trunk/web/css/vcl.css Modified: incubator/vcl/trunk/web/.ht-inc/schedules.php URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/schedules.php?rev=991322&r1=991321&r2=991322&view=diff ============================================================================== --- incubator/vcl/trunk/web/.ht-inc/schedules.php (original) +++ incubator/vcl/trunk/web/.ht-inc/schedules.php Tue Aug 31 20:41:32 2010 @@ -170,14 +170,12 @@ function viewSchedules() { /// //////////////////////////////////////////////////////////////////////////////// function editOrAddSchedule($state) { - global $submitErr, $mode, $submitErrMsg; + global $submitErr, $mode, $submitErrMsg, $days; $schedules = getSchedules(); - $days = array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", - "Friday", "Saturday"); $newcont = 0; - if($submitErr || $mode == "submitScheduleTime" || $mode == "submitAddSchedule") { + if($submitErr || $mode == "submitAddSchedule") { $data = processScheduleInput(0); $newcont = 1; # continuation to get here was deleted; so, we'll need to set # deletefromself true this time @@ -187,9 +185,7 @@ function editOrAddSchedule($state) { $id = $data["scheduleid"]; $data["name"] = $schedules[$id]["name"]; $data["owner"] = $schedules[$id]["owner"]; - $data["submode"] = processInputVar("submode", ARG_STRING); } - $schedules = getSchedules(); print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; print "<DIV align=center>\n"; if($state) { @@ -250,121 +246,56 @@ function editOrAddSchedule($state) { print " </TD>\n"; print " </TR>\n"; print "</TABLE>\n"; + print "</div>\n"; if($state) return; print "The start and end day/times are based on a week's time period with "; print "the start/end point being 'Sunday 12:00 am'. i.e. The earliest "; print "start day/time is 'Sunday 12:00 am' and the latest end day/"; print "time is 'Sunday 12:00 am'<br><br>\n"; - if(! $submitErr && $mode == "submitScheduleTime" && $data["submode"] == "Save changes") { - print "<font color=green>Changes saved</font><br>\n"; - } - printSubmitErr(OVERLAPERR); - print "<FORM action=\"" . BASEURL . SCRIPT . "\" method=post>\n"; - print "<TABLE>\n"; - print " <TR>\n"; - print " <TD></TD>\n"; - print " <TH>Start</TH>\n"; - print " <TD></TD>\n"; - print " <TH>End</TH>\n"; - print " <TD></TD>\n"; - print " </TR>\n"; - $addrow = 0; - if($mode == "submitScheduleTime") { - $addrow = 1; - } - print "<TR><TD colspan=5>"; - print "</TD></TR>\n"; - $doaddrow = 0; - if($mode == "submitScheduleTime") { - if($data["selrow"] == "") - $end = $data["count"]; - elseif($data["submode"] == "Insert before selected row") { - $doaddrow = 1; - $addrow = $data["selrow"]; - $end = $data["count"] + 1; - } - elseif($data["submode"] == "Insert after selected row") { - $doaddrow = 1; - $addrow = $data["selrow"] + 1; - $end = $data["count"] + 1; - } - else - $end = $data["count"]; - } - else - $end = count($schedules[$data["scheduleid"]]["times"]); - if($end == 0) { - $doaddrow = 1; - $addrow = 0; - $end = 1; - } - reset($schedules[$data["scheduleid"]]["times"]); - $index = 0; - for($count = 0; $count < $end; $count++) { - // if mode == submitScheduleTime, print submitted times - if($mode == "submitScheduleTime") { - if($doaddrow && $count == $addrow) { - $startday = ""; - $starttime = ""; - $endday = ""; - $endtime = ""; - $doaddrow = 0; - $index--; - } - else { - $startday = $data["startDay"][$index]; - $starttime = $data["startTime"][$index]; - $endday = $data["endDay"][$index]; - $endtime = $data["endTime"][$index]; - } - print " <TR>\n"; - print " <TD align=right><INPUT type=radio name=selrow value=$count></TD>\n"; - printStartEndTimeForm2($startday, $starttime, $count, "start"); - print " <TD> </TD>\n"; - printStartEndTimeForm2($endday, $endtime, $count, "end"); - } - // otherwise, print times from database - else { - $time = current($schedules[$data["scheduleid"]]["times"]); - print " <TR>\n"; - print " <TD align=right><INPUT type=radio name=selrow value=$count></TD>\n"; - printStartEndTimeForm($time["start"], $count, "start"); - print " <TD> </TD>\n"; - printStartEndTimeForm($time["end"], $count, "end"); - next($schedules[$data["scheduleid"]]["times"]); - } - print " <TD width=70>"; - if($data["submode"] == "Save changes") - printSubmitErr(1 << $count); - print "</TD>"; - print " </TR>\n"; - $index++; - } - $colspan = 5; - print " <TR>\n"; - print " <TD align=center colspan=$colspan><INPUT type=submit name=submode value=\"Delete selected row\"></TD>\n"; - print " <TR>\n"; - print " </TR>\n"; - print " <TD align=center colspan=$colspan><INPUT type=submit name=submode value=\"Insert before selected row\"></TD>\n"; - print " <TR>\n"; - print " </TR>\n"; - print " <TD align=center colspan=$colspan><INPUT type=submit name=submode value=\"Insert after selected row\"></TD>\n"; - print " <TR>\n"; - print " </TR>\n"; - print " <TD align=center colspan=$colspan><INPUT type=submit name=submode value=\"Save changes\"></TD>\n"; - print " </TR>\n"; - print "</TABLE>\n"; - $cdata = array('scheduleid' => $data['scheduleid'], - 'count' => $count, - 'name' => $data['name'], - 'owner' => $data['owner']); - if($newcont) - $cont = addContinuationsEntry('submitScheduleTime', $cdata, SECINDAY, 1, 0); - else - $cont = addContinuationsEntry('submitScheduleTime', $cdata, SECINDAY, 0, 0); - print "<INPUT type=hidden name=continuation value=\"$cont\">\n"; - print "</FORM>\n"; + + + print "Start:"; + printSelectInput('startday', $days, -1, 0, 0, 'startday'); + print "<input type=\"text\" id=\"starttime\" dojoType=\"dijit.form.TimeTextBox\" "; + print "required=\"true\" />\n"; + print "End:"; + printSelectInput('endday', $days, -1, 0, 0, 'endday'); + print "<input type=\"text\" id=\"endtime\" dojoType=\"dijit.form.TimeTextBox\" "; + print "required=\"true\" />\n"; + print "<button dojoType=\"dijit.form.Button\" type=\"button\" "; + print "id=\"addTimeBtn\">\n"; + print " Add\n"; + print " <script type=\"dojo/method\" event=\"onClick\">\n"; + print " addTime();\n"; + print " </script>\n"; + print "</button>\n"; + print "<div dojoType=\"dojo.data.ItemFileWriteStore\" jsId=\"scheduleStore\" "; + print "data=\"scheduleTimeData\"></div>\n"; + print "<table dojoType=\"dojox.grid.DataGrid\" jsId=\"scheduleGrid\" sortInfo=1 "; + print "store=\"scheduleStore\" style=\"width: 524px; height: 165px;\">\n"; + print "<thead>\n"; + print "<tr>\n"; + print "<th field=\"startday\" width=\"94px\" formatter=\"formatDay\">Start Day</th>\n"; + print "<th field=\"startday\" width=\"94px\" formatter=\"formatTime\">Start Time</th>\n"; + print "<th field=\"endday\" width=\"94px\" formatter=\"formatDay\">End Day</th>\n"; + print "<th field=\"endday\" width=\"94px\" formatter=\"formatTime\">End Time</th>\n"; + print "<th field=\"remove\" width=\"80px\">Remove</th>\n"; + print "</tr>\n"; + print "</thead>\n"; + print "</table>\n"; + + print "<div align=\"center\">\n"; + print "<div id=\"savestatus\"></div>\n"; + print "<button dojoType=\"dijit.form.Button\" type=\"button\" id=\"saveTimesBtn\">\n"; + print " Save Schedule Times\n"; + print " <script type=\"dojo/method\" event=\"onClick\">\n"; + $cdata = array('id' => $data['scheduleid']); + $cont = addContinuationsEntry('AJsaveScheduleTimes', $cdata); + print " saveTimes('$cont');\n"; + print " </script>\n"; + print "</button>\n"; + print "</div>\n"; } //////////////////////////////////////////////////////////////////////////////// @@ -470,6 +401,39 @@ function submitAddSchedule() { //////////////////////////////////////////////////////////////////////////////// /// +/// \fn AJgetScheduleTimesData() +/// +/// \brief gets start/end times for a schedule and sends in JSON format +/// +//////////////////////////////////////////////////////////////////////////////// +function AJgetScheduleTimesData() { + $id = getContinuationVar('id'); + $query = "SELECT start, " + . "end " + . "FROM scheduletimes " + . "WHERE scheduleid = $id " + . "ORDER BY start"; + $qh = doQuery($query, 101); + $times = array(); + while($row = mysql_fetch_assoc($qh)) { + $smin = $row['start'] % 1440; + $sday = (int)($row['start'] / 1440); + if($sday > 6) + $sday = 0; + $emin = $row['end'] % 1440; + $eday = (int)($row['end'] / 1440); + if($eday > 6) + $eday = 0; + $times[] = array('smin' => $smin, + 'sday' => $sday, + 'emin' => $emin, + 'eday' => $eday); + } + sendJSON($times); +} + +//////////////////////////////////////////////////////////////////////////////// +/// /// \fn confirmDeleteSchedule() /// /// \brief prints a form to confirm the deletion of a schedule @@ -659,8 +623,7 @@ function submitScheduleGroups() { /// \param $checks - (optional) 1 to perform validation, 0 not to /// /// \return an array with the following indexes:\n -/// scheduleid, name, owner, submode, selrow, count, startDay, startTime, -/// endDay, endTime +/// scheduleid, name, owner /// /// \brief validates input from the previous form; if anything was improperly /// submitted, sets submitErr and submitErrMsg @@ -669,23 +632,12 @@ function submitScheduleGroups() { function processScheduleInput($checks=1) { global $submitErr, $submitErrMsg; $return = array(); - $return["start"] = array(); - $return["end"] = array(); - $return["scheduleid"] = getContinuationVar("scheduleid", processInputVar("scheduleid" , ARG_NUMERIC)); $return["name"] = getContinuationVar("name", processInputVar("name", ARG_STRING)); $return["owner"] = getContinuationVar("owner", processInputVar("owner", ARG_STRING)); - $return["submode"] = processInputVar("submode", ARG_STRING); - $return["selrow"] = processInputVar("selrow", ARG_NUMERIC); - $return["count"] = getContinuationVar("count", processInputVar("count", ARG_NUMERIC, 0)); - $return["startDay"] = processInputVar("startDay", ARG_MULTINUMERIC); - $return["startTime"] = processInputVar("startTime", ARG_MULTISTRING); - $return["endDay"] = processInputVar("endDay", ARG_MULTINUMERIC); - $return["endTime"] = processInputVar("endTime", ARG_MULTISTRING); - if(! $checks) { + if(! $checks) return $return; - } if(strlen($return["name"]) > 25 || strlen($return["name"]) < 2) { $submitErr |= SCHNAMEERR; @@ -700,30 +652,6 @@ function processScheduleInput($checks=1) $submitErr |= SCHOWNERERR; $submitErrMsg[SCHOWNERERR] = "The submitted unity ID is invalid."; } - for($i = 0; $i < $return["count"]; $i++) { - if((! preg_match('/^((0?[1-9])|(1[0-2])):([0-5][0-9]) (am|pm)$/', $return["startTime"][$i])) || - (! preg_match('/^((0?[1-9])|(1[0-2])):([0-5][0-9]) (am|pm)$/', $return["endTime"][$i]))) { - $submitErr |= (1 << $i); - $submitErrMsg[1 << $i] = "Time must be of the form [H]H:MM am/pm"; - } - elseif(daytimeToMin($return["startDay"][$i], $return["startTime"][$i], "start") >= - daytimeToMin($return["endDay"][$i], $return["endTime"][$i], "end")) { - $submitErr |= (1 << $i); - $submitErrMsg[1 << $i] = "The start day/time must be before the end day/time"; - } - } - for($i = 0; $i < $return["count"] - 1; $i++) { - for($j = $i + 1; $j < $return["count"]; $j++) { - if(daytimeToMin($return["startDay"][$i], $return["startTime"][$i], "start") < - daytimeToMin($return["endDay"][$j], $return["endTime"][$j], "end") && - daytimeToMin($return["endDay"][$i], $return["endTime"][$i], "end") > - daytimeToMin($return["startDay"][$j], $return["startTime"][$j], "start")) { - $submitErr |= OVERLAPERR; - $submitErrMsg[OVERLAPERR] = "At least 2 of the time periods overlap. Please combine them into a single entry."; - break(2); - } - } - } return $return; } @@ -810,157 +738,42 @@ function addSchedule($data) { //////////////////////////////////////////////////////////////////////////////// /// -/// \fn printStartEndTimeForm($min, $count, $startend) +/// \fn AJsaveScheduleTimes() /// -/// \param $min - minute in the week, pass empty string to get an empty text -/// entry field -/// \param $count - counter value - used to keep track of which row this is -/// \param $startend - "start" or "end" -/// -/// \brief prints a select input for the day of week and a text entry field -/// for the time to be entered +/// \brief saves the submitted time for the schedule and notifies the user /// //////////////////////////////////////////////////////////////////////////////// -function printStartEndTimeForm($min, $count, $startend) { - $days = array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", - "Friday", "Saturday"); - if($min == "") { - print " <TD>\n"; - printSelectInput("$startend" . "Day[$count]", $days); - $name = $startend . "Time[$count]"; - print " <INPUT type=text name=$name size=8 mazlength=8>\n"; - print " </TD>\n"; +function AJsaveScheduleTimes() { + $id = getContinuationVar('id'); + $tmp = processInputVar('times', ARG_STRING); + if(! preg_match('/^([0-9]+:[0-9]+,)*([0-9]+:[0-9]+){1}$/', $tmp)) { + print "alert('invalid data submitted');"; return; } - $time = minuteToTime($min % 1440); - if((int)($min / 1440) == 0) { - $day = 0; - } - elseif((int)($min / 1440) == 1) { - $day = 1; - } - elseif((int)($min / 1440) == 2) { - $day = 2; - } - elseif((int)($min / 1440) == 3) { - $day = 3; - } - elseif((int)($min / 1440) == 4) { - $day = 4; - } - elseif((int)($min / 1440) == 5) { - $day = 5; - } - elseif((int)($min / 1440) == 6) { - $day = 6; - } - elseif((int)($min / 1440) > 6) { - $day = 0; - } - print " <TD>\n"; - printSelectInput("$startend" . "Day[$count]", $days, $day); - $name = $startend . "Time[$count]"; - print " <INPUT type=text name=$name value=\"$time\" size=8 maxlength=8>\n"; - print " </TD>\n"; -} - -//////////////////////////////////////////////////////////////////////////////// -/// -/// \fn printStartEndTimeForm2($day, $time, $count, $startend) -/// -/// \param $day - numeric day of week with Sunday being 0 -/// \param $time - time of day in string format HH:MM am/pm -/// \param $count - counter value - used to keep track of which row this is -/// \param $startend - "start" or "end" -/// -/// \brief prints a select input for the day of week and a text entry field -/// for the time to be entered -/// -//////////////////////////////////////////////////////////////////////////////// -function printStartEndTimeForm2($day, $time, $count, $startend) { - $days = array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", - "Friday", "Saturday"); - print " <TD>\n"; - printSelectInput("$startend" . "Day[$count]", $days, $day); - $name = $startend . "Time[$count]"; - print " <INPUT type=text name=$name value=\"$time\" size=8 maxlength=8>\n"; - print " </TD>\n"; -} - -//////////////////////////////////////////////////////////////////////////////// -/// -/// \fn submitScheduleTime() -/// -/// \brief handles submitting date/time form for schedule times and calls -/// editOrAddSchedule(0) again -/// -//////////////////////////////////////////////////////////////////////////////// -function submitScheduleTime() { - global $submitErr, $contdata; - - if($_POST["submode"] == "Save changes") { - $data = processScheduleInput(1); - if($submitErr) { - editOrAddSchedule(0); - return; - } - } - else { - $data = processScheduleInput(0); - if($data["selrow"] == "") { - editOrAddSchedule(0); - return; - } - } - - if($data["submode"] == "Delete selected row") { - // delete entry from db - $start = daytimeToMin($data["startDay"][$data["selrow"]], $data["startTime"][$data["selrow"]], "start"); - $end = daytimeToMin($data["endDay"][$data["selrow"]], $data["endTime"][$data["selrow"]], "end"); - $query = "DELETE FROM scheduletimes " - . "WHERE scheduleid = {$data["scheduleid"]} AND " - . "start = $start AND " - . "end = $end"; - doQuery($query, 101); - // decrease all values by 1 that are > deleted row - for($i = 0; $i < $data["count"] - 1; $i++) { - if($i >= $data["selrow"]) { - $_POST["startDay"][$i] = $_POST["startDay"][$i + 1]; - $_POST["startTime"][$i] = $_POST["startTime"][$i + 1]; - $_POST["endDay"][$i] = $_POST["endDay"][$i + 1]; - $_POST["endTime"][$i] = $_POST["endTime"][$i + 1]; + $times = explode(',', $tmp); + $newtimes = array(); + $qvals = array(); + foreach($times as $pair) { + list($start, $end) = explode(':', $pair); + foreach($newtimes as $check) { + if($start < $check['end'] && $end > $check['start']) { + print "alert('Two sets of times are overlapping;\nplease correct and save again.');"; + return; } } - unset($_POST["startDay"][$i]); - unset($_POST["startTime"][$i]); - unset($_POST["endDay"][$i]); - unset($_POST["endTime"][$i]); - $contdata["count"]--; - editOrAddSchedule(0); - } - elseif($data["submode"] == "Insert before selected row") { - editOrAddSchedule(0); - } - elseif($data["submode"] == "Insert after selected row") { - editOrAddSchedule(0); - } - elseif($data["submode"] == "Save changes") { - $query = "DELETE FROM scheduletimes WHERE scheduleid = {$data["scheduleid"]}"; - doQuery($query, 101); - for($i = 0; $i < $data["count"]; $i++) { - $start = daytimeToMin($data["startDay"][$i], $data["startTime"][$i], "start"); - $end = daytimeToMin($data["endDay"][$i], $data["endTime"][$i], "end"); - $query = "INSERT INTO scheduletimes " - . "(scheduleid, " - . "start, " - . "end) " - . "VALUES ({$data["scheduleid"]}, " - . "$start, " - . "$end)"; - doQuery($query, 101); - } - editOrAddSchedule(0); + $newtimes[] = array('start' => $start, 'end' => $end); + $qvals[] = "($id, $start, $end)"; } + $query = "DELETE FROM scheduletimes WHERE scheduleid = $id"; + doQuery($query, 101); + $allvals = implode(',', $qvals); + $query = "INSERT INTO scheduletimes " + . "(scheduleid, start, end) " + . "VALUES $allvals"; + doQuery($query, 101); + print "dijit.byId('saveTimesBtn').attr('disabled', false);"; + print "dojo.byId('savestatus').innerHTML = 'Schedule times successfully saved';"; + print "setTimeout(function() {dojo.byId('savestatus').innerHTML = '';}, 8000);"; } //////////////////////////////////////////////////////////////////////////////// Modified: incubator/vcl/trunk/web/.ht-inc/states.php URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/states.php?rev=991322&r1=991321&r2=991322&view=diff ============================================================================== --- incubator/vcl/trunk/web/.ht-inc/states.php (original) +++ incubator/vcl/trunk/web/.ht-inc/states.php Tue Aug 31 20:41:32 2010 @@ -139,6 +139,8 @@ $noHTMLwrappers = array('sendRDPfile', 'AJgetDelSiteMaintenanceData', 'AJeditSiteMaintenance', 'AJdeleteSiteMaintenance', + 'AJgetScheduleTimesData', + 'AJsaveScheduleTimes', ); # main @@ -356,7 +358,8 @@ $actions['mode']['submitAddSchedule'] = $actions['mode']['confirmDeleteSchedule'] = "confirmDeleteSchedule"; $actions['mode']['submitDeleteSchedule'] = "submitDeleteSchedule"; $actions['mode']['submitScheduleGroups'] = "submitScheduleGroups"; -$actions['mode']['submitScheduleTime'] = "submitScheduleTime"; +$actions['mode']['AJgetScheduleTimesData'] = "AJgetScheduleTimesData"; +$actions['mode']['AJsaveScheduleTimes'] = "AJsaveScheduleTimes"; $actions['pages']['viewSchedules'] = "manageSchedules"; $actions['pages']['editSchedule'] = "manageSchedules"; $actions['pages']['confirmEditSchedule'] = "manageSchedules"; @@ -366,7 +369,8 @@ $actions['pages']['submitAddSchedule'] = $actions['pages']['confirmDeleteSchedule'] = "manageSchedules"; $actions['pages']['submitDeleteSchedule'] = "manageSchedules"; $actions['pages']['submitScheduleGroups'] = "manageSchedules"; -$actions['pages']['submitScheduleTime'] = "manageSchedules"; +$actions['pages']['AJgetScheduleTimesData'] = "manageSchedules"; +$actions['pages']['AJsaveScheduleTimes'] = "manageSchedules"; # manage computers $actions['mode']['selectComputers'] = "selectComputers"; # entry Modified: incubator/vcl/trunk/web/.ht-inc/utils.php URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/.ht-inc/utils.php?rev=991322&r1=991321&r2=991322&view=diff ============================================================================== --- incubator/vcl/trunk/web/.ht-inc/utils.php (original) +++ incubator/vcl/trunk/web/.ht-inc/utils.php Tue Aug 31 20:41:32 2010 @@ -9051,6 +9051,17 @@ function getDojoHTML($refresh) { case 'viewBlockStatus': $dojoRequires = array('dojo.parser'); break; + case 'editSchedule': + case 'submitAddSchedule': + // TODO remove any unneeded items + $dojoRequires = array('dojo.parser', + 'dijit.form.TimeTextBox', + 'dojox.grid.DataGrid', + 'dojox.string.sprintf', + #'dijit.form.FilteringSelect', + #'dijit.Tooltip', + 'dijit.form.Button', + 'dojo.data.ItemFileWriteStore'); case 'viewImages': /*$dojoRequires = array('dojo.data.ItemFileWriteStore', 'dojox.grid.Grid', @@ -9237,6 +9248,29 @@ function getDojoHTML($refresh) { $rt .= "</script>\n"; return $rt; + case "editSchedule": + case "submitAddSchedule": + $rt .= "<style type=\"text/css\">\n"; + $rt .= " @import \"themes/$skin/css/dojo/$skin.css\";\n"; + $rt .= " @import \"dojo/dojox/grid/resources/Grid.css\";\n"; + $rt .= "</style>\n"; + $rt .= "<script type=\"text/javascript\" src=\"js/schedules.js\"></script>\n"; + $rt .= "<script type=\"text/javascript\" src=\"dojo/dojo/dojo.js\"\n"; + $rt .= " djConfig=\"parseOnLoad: true\">\n"; + $rt .= "</script>\n"; + $rt .= "<script type=\"text/javascript\">\n"; + $rt .= " dojo.addOnLoad(function() {\n"; + foreach($dojoRequires as $req) { + $rt .= " dojo.require(\"$req\");\n"; + } + $id = getContinuationVar("scheduleid"); + $cont = addContinuationsEntry('AJgetScheduleTimesData', array('id' => $id), SECINDAY, 1, 0); + $rt .= " populateTimeStore('$cont');\n"; + #$rt .= " setTimeout(function() {populateTimeStore('$cont');}, 1000);\n"; + $rt .= " });\n"; + $rt .= "</script>\n"; + return $rt; + case "viewImageGrouping": case "submitImageGroups": case "viewImageMapping": Modified: incubator/vcl/trunk/web/css/vcl.css URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/css/vcl.css?rev=991322&r1=991321&r2=991322&view=diff ============================================================================== --- incubator/vcl/trunk/web/css/vcl.css (original) +++ incubator/vcl/trunk/web/css/vcl.css Tue Aug 31 20:41:32 2010 @@ -256,3 +256,7 @@ border: 1px solid; background-color: #f3f3f3; } + +#savestatus { + color: #008000; +} Added: incubator/vcl/trunk/web/js/schedules.js URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/web/js/schedules.js?rev=991322&view=auto ============================================================================== --- incubator/vcl/trunk/web/js/schedules.js (added) +++ incubator/vcl/trunk/web/js/schedules.js Tue Aug 31 20:41:32 2010 @@ -0,0 +1,193 @@ +var scheduleTimeData = { + identifier: 'id', + items: [] +} + +function RPCwrapper(data, CB, dojson) { + if(dojson) { + dojo.xhrPost({ + url: 'index.php', + load: CB, + handleAs: "json", + error: errorHandler, + content: data, + timeout: 15000 + }); + } + else { + dojo.xhrPost({ + url: 'index.php', + load: CB, + error: errorHandler, + content: data, + timeout: 15000 + }); + } +} + +function generalReqCB(data, ioArgs) { + eval(data); + document.body.style.cursor = 'default'; +} + +function populateTimeStore(cont) { + RPCwrapper({continuation: cont}, populateTimeStoreCB, 1); +} + +function populateTimeStoreCB(data, ioArgs) { + if(data.items.error) { + alert(data.items.error); + return; + } + var store = scheduleStore; + if(! store.nextid) + store.nextid = 0; + for(var i = 0; i < data.items.length; i++) { + var id = store.nextid + 1; + store.nextid = id; + var sday = new Date(0); + sday.setFullYear(2000); + sday.setMonth(9); + sday.setDate(data.items[i].sday + 1); + sday.setHours(Math.floor(data.items[i].smin / 60)); + sday.setMinutes(data.items[i].smin % 60); + var eday = new Date(0); + eday.setFullYear(2000); + eday.setMonth(9); + if(data.items[i].eday == 0 && + data.items[i].emin == 0) { + eday.setDate(data.items[i].eday + 8); + eday.setHours(Math.floor(data.items[i].emin / 60)); + eday.setMinutes(data.items[i].emin % 60); + } + else { + eday.setDate(data.items[i].eday + 1); + eday.setHours(Math.floor(data.items[i].emin / 60)); + eday.setMinutes(data.items[i].emin % 60); + } + var btn = new dijit.form.Button({ + label: "Remove", + onClick: createRemoveFunc(removeTime, id) + }); + store.newItem({id: id, startday: sday, endday: eday, remove: btn}); + } + scheduleGrid.sort(); +} + +function createRemoveFunc(func, id) { + return function() {func(id);} +} + +function removeTime(id) { + scheduleStore.fetch({ + query: {id: id}, + onItem: function(item) { + scheduleStore.deleteItem(item); + } + }); +} + +function addTime() { + var endday = parseInt(dojo.byId('endday').value); + var endtimeobj = dijit.byId('endtime').value; + if(dojo.byId('startday').value != 0 && + endday == 0 && + (endtimeobj.getHours() != 0 || + endtimeobj.getMinutes() != 0)) { + alert("If the start day is not Sunday, the end day cannot\nbe Sunday with a time later than 12:00 AM."); + return; + } + var sday = new Date(0); + sday.setFullYear(2000); + sday.setMonth(9); + sday.setDate(parseInt(dojo.byId('startday').value) + 1); + sday.setHours(dijit.byId('starttime').value.getHours()); + sday.setMinutes(dijit.byId('starttime').value.getMinutes()); + var eday = new Date(0); + eday.setFullYear(2000); + eday.setMonth(9); + if(endday == 0 && + endtimeobj.getHours() == 0 && + endtimeobj.getMinutes() == 0) { + eday.setDate(endday + 8); + eday.setHours(endtimeobj.getHours()); + eday.setMinutes(endtimeobj.getMinutes()); + } + else { + eday.setDate(endday + 1); + eday.setHours(endtimeobj.getHours()); + eday.setMinutes(endtimeobj.getMinutes()); + } + + if(eday < sday) { + alert('The ending day/time cannot be earlier than the starting day/time'); + return; + } + + var items = scheduleStore._arrayOfAllItems; + for(var i = 0; i < items.length; i++) { + if(items[i] == null) + continue; + if(sday < items[i].endday[0] && eday > items[i].startday[0]) { + alert("The submitted days/times overlap with\nan existing set of days/times."); + return; + } + } + + id = ++scheduleStore.nextid; + var btn = new dijit.form.Button({ + label: "Remove", + onClick: createRemoveFunc(removeTime, id) + }); + scheduleStore.newItem({id: id, startday: sday, endday: eday, remove: btn}); + scheduleGrid.sort(); +} + +function formatDay(val) { + return getDay(val.getDay()); +} + +function formatTime(val) { + return getTime(val); +} + +function getDay(day) { + var days = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'); + return days[day]; +} + +function getTime(obj) { + var hour = obj.getHours(); + var min = obj.getMinutes(); + if(hour == 12) + return dojox.string.sprintf('12:%02d PM', min); + if(hour == 0) + return dojox.string.sprintf('12:%02d AM', min); + if(parseInt(hour / 12)) + return dojox.string.sprintf('%d:%02d PM', hour % 12, min); + return dojox.string.sprintf('%d:%02d AM', hour, min); +} + +function saveTimes(cont) { + var times = new Array(); + var items = scheduleStore._arrayOfAllItems; + for(var i = 0; i < items.length; i++) { + if(items[i] == null) + continue; + var start = minuteInWeek(items[i].startday[0]); + var end = minuteInWeek(items[i].endday[0]); + times.push(dojox.string.sprintf('%d:%d', start, end)); + } + var data = {continuation: cont, + times: times.join(',')}; + dijit.byId('saveTimesBtn').attr('disabled', true); + document.body.style.cursor = 'wait'; + RPCwrapper(data, generalReqCB); +} + +function minuteInWeek(val) { + var min = val.getMinutes(); + min += val.getHours() * 60; + min += (val.getDate() - 1) * 1440; + return min; +}