"); function BuildReportValue ($rptType, $eventid=NULL) { // // Given the report type and, if the type requires, an eventid, // this returns a STRING to be used as the option value in the // drop down list. global $valdivider; return (($eventid==NULL) ? $rptType : implode($valdivider, array($rptType, $eventid))); } function GetPageHeader ($rptType, $eventid, $eventlist) { if (($rptType==C_STD_INDEXED_REPORT) || ($rptType==C_STD_BYCLASS_REPORT)) { // // Generate 'Standings' title $retstr = "STANDINGS"; } else if ($rptType==C_MYSEASON_REPORT) { // // Generate 'My Season' title $retstr = "MY SEASON"; } else { // // Generate a title for a specific event $eventnum = array_search($eventid, $eventlist); if ($eventnum===false) return ""; list($isvalid, $year, $month, $day, $season, $num) = EventId::SplitEventId($eventid); if ($isvalid!==TRUE) return ""; $retstr = "Event #" . (intval($eventnum)+1) . "     " . date("F j, Y", mktime(0, 0, 0, $month, $day, $year)); } return $retstr; } function ResolveDisplayFormat ($rptType, $rptFormat_requested, $seasonid, $eventlist, $eventcount, $eventid=NULL, $mbrid=NULL) { // // Given information that defines what should be displayed on this // page, return with the values needed to display the page set. This // function is responsible for setting most of the page variables // required to display this page. // // The input required is: // rptType - a specifier of what type of report to display; this is // equivalent to page variable 'pg_rptType' // rptFormat_requested - a value corresponding to the ID in the report // format drop-down that specifies the format for the report // seasonid, eventlist, eventcount, eventid and mbrid - // These variables are used (where applicable) as parameters to // the various display functions. Depending upon the display // request, the required parameter values will be returned in // pg_rptParams. // // The values returned are equivalent to these page variables: // pg_rptFormat_options: an array of format options for this report type // pg_rptFormat_id: the value of the selected option in the pg_rptFormat_options list // pg_rptFunction & pg_rptParams: function to call and values to pass // // Initialize the return values $ret_rptFormat_options = array(); $ret_rptFormat_selected = ""; $ret_rptFunction = NULL; $ret_rptParams = array(); switch ($rptType) { case C_EVENT_FULL_REPORT: // requires $eventid { global $myresults; $displayclass = 0; // parameter initialized to not limit the display // Pick up classes for the specified event to use as display options list($isvalid, $ret_rptFormat_options) = $myresults->_getClassesForEvent($eventid); if (($isvalid==FALSE) || empty($ret_rptFormat_options)) { $ret_rptFormat_options = array('ALL'); } else { // // If the report format requested is in this display list... if ((!empty($rptFormat_requested)) && (in_array($rptFormat_requested, $ret_rptFormat_options)==TRUE)) { $ret_rptFormat_selected = $rptFormat_requested; // mark the drop-down selected $displayclass = $rptFormat_requested; // limit display to selected class } // Add 'All' to the front of the selection array_unshift($ret_rptFormat_options, 'ALL'); } // Build the call information to display the right report $ret_rptFunction = 'DisplayFull'; // 'DisplayPointsLine1' $ret_rptParams = array($eventid, $displayclass, $mbrid, NULL); break; } case C_EVENT_INDEXED_REPORT: // novice-only option { $shownovice = false; // parameter initialized to not limit the display $ret_rptFormat_options = array( 'ALL', C_NOVICE_DESIGNATE); // Now that we have the options: // Determine if the requested format is available for this report type if (strcmp($rptFormat_requested,C_NOVICE_DESIGNATE)==0) { // // User's request to show novice is valid $ret_rptFormat_selected = $rptFormat_requested; // mark the novice selection $shownovice = TRUE; // set display limit } else { // $ret_rptFormat_selected = $ret_rptFormat_options[0]; $shownovice = FALSE; } $ret_rptFunction = 'DisplayIndexedResults'; $ret_rptParams = array($eventid, $shownovice, $mbrid, NULL); break; } case C_EVENT_RAW_REPORT: // just raw results - no novice option here { $ret_rptFunction = 'DisplayRawResults'; $ret_rptParams = array($eventid, $mbrid, NULL); break; } case C_STD_INDEXED_REPORT: // novice-only option { $shownovice = false; // parameter initialized to not limit the display $ret_rptFormat_options = array( 'ALL', C_NOVICE_DESIGNATE); // Now that we have the options: // Determine if the requested format is available for this report type if (strcmp($rptFormat_requested,C_NOVICE_DESIGNATE)==0) { // // User's request to show novice is valid $ret_rptFormat_selected = $rptFormat_requested; // mark the novice selection $shownovice = TRUE; $title = "Novice Standings"; } else { // $ret_rptFormat_selected = $ret_rptFormat_options[0]; $shownovice = FALSE; $title = "Top 100 Drivers"; } $ret_rptFunction = 'DisplayStandings'; $ret_rptParams = array($seasonid, $eventlist, $eventcount, $title, FALSE, NULL, $shownovice, $mbrid, FALSE, 100, FALSE); break; } case C_ALL_INDEXED_REPORT: // novice-only option { $shownovice = false; // parameter initialized to not limit the display $ret_rptFormat_options = array( 'ALL' ); $ret_rptFormat_selected = $ret_rptFormat_options[0]; $shownovice = FALSE; $title = "All Indexed Drivers"; $ret_rptFunction = 'DisplayStandings'; $ret_rptParams = array($seasonid, $eventlist, $eventcount, $title, FALSE, NULL, $shownovice, $mbrid, FALSE, 0, FALSE); break; } case C_STD_BYCLASS_REPORT: { global $myresults; $displayclass = 0; // parameter initialized to not limit the display // Pick up classes for the specified event to use as display options list($isvalid, $ret_rptFormat_options) = $myresults->_getClassesForSeason($seasonid); if (($isvalid==FALSE) || empty($ret_rptFormat_options)) { $ret_rptFormat_options = array('ALL'); } else { // // If the report format requested is in this display list... if ((!empty($rptFormat_requested)) && (in_array($rptFormat_requested, $ret_rptFormat_options)==TRUE)) { $ret_rptFormat_selected = $rptFormat_requested; // mark the drop-down selected $displayclass = $rptFormat_requested; // limit display to selected class } // Add 'All' to the front of the selection array_unshift($ret_rptFormat_options, 'ALL'); } $ret_rptFunction = 'DisplayStandings'; $ret_rptParams = array($seasonid, $eventlist, $eventcount, NULL, TRUE, $displayclass, FALSE, $mbrid, FALSE, 0, FALSE); break; } case C_MYSEASON_REPORT: // no options { $ret_rptFunction = 'DisplayMySeason'; $ret_rptParams = array($seasonid, $eventlist, $eventcount, $mbrid); break; } } // end switch return (array($ret_rptFormat_options, $ret_rptFormat_selected, $ret_rptFunction, $ret_rptParams)); } // *** BEGIN MAIN *** // // The display is driven by a small set of page variables. // These are: // // Support for the page label: // pg_html_eventheader: top of page header // // Support for the report type and format options at the top of the page: // pg_rptType: a specifier of what type of report to display // pg_rptType_value: the value of the requested report option in the option list // pg_rptFormat_options: specifies the list of format options for the given report // pg_rptFormat_value: the value of the selected option in the pg_rptFormat_options list // // Support to actually display the requested report type and format // pg_rptFunction, pg_rptParams: function to call and values to pass // $myresults = CreateResultSet(); // class for calling result functions // *Most* of the page variables are set in the 'ResolveDisplayFormat' // function. So initialize the variables we need to call that function // $pg_rptType = C_STD_INDEXED_REPORT; // default display: indexed standings $rptFormat_requested = 0; // choose the default format option $eventid = ''; // no eventid required for this display type $pg_rptType_value = BuildReportValue($pg_rptType); // build the value that loads this report /format combo $this_member = ($MyAuth->_isUserLoggedOn()==true) ? $_SESSION['ua_id'] : NULL; // if this user is logged on, get their id // Set the list of what reports are allowed $pg_rptType_options = array ( C_EVENT_FULL_REPORT, C_EVENT_INDEXED_REPORT, C_EVENT_RAW_REPORT, C_STD_INDEXED_REPORT, C_STD_BYCLASS_REPORT, C_ALL_INDEXED_REPORT ); if (!empty($this_member) && ($myresults->_isMemberInSeason($pg_seasonid, $this_member)==TRUE)) $pg_rptType_options[] = C_MYSEASON_REPORT; // Now look at any incoming values to see if the user requested a // specific display. // if (!empty(${"_$_SERVER[REQUEST_METHOD]"}['rep'])) { // // found specifier for report list ($tmp_rptType, $tmp_eventid) = SplitReportValue(${"_$_SERVER[REQUEST_METHOD]"}['rep']); if (in_array($tmp_rptType, $pg_rptType_options)) { // // Verified report specifier is valid $pg_rptType = $tmp_rptType; if (!empty($tmp_eventid)) $eventid = $tmp_eventid; $pg_rptType_value = ${"_$_SERVER[REQUEST_METHOD]"}['rep']; } } $rptFormat_requested = (!empty(${"_$_SERVER[REQUEST_METHOD]"}['dsp'])) ? ${"_$_SERVER[REQUEST_METHOD]"}['dsp'] : 0; // Magic! // Transform what we know into our display parameters. list ($pg_rptFormat_options, $pg_rptFormat_value, $pg_rptFunction, $pg_rptParams) = ResolveDisplayFormat ($pg_rptType, $rptFormat_requested, $pg_seasonid, $pg_eventlist, $pg_eventcount, $eventid, $this_member); $pg_html_eventheader = GetPageHeader ($pg_rptType, $eventid, $pg_eventlist); // ********************************************** // All page variables defined above are now set! // ********************************************** ?> $display"); } function AddSwitcheroo ($rptType_options, $rptType_selected, $eventlist, $format_options, $format_selected){ global $myresults; // must already be set // Create the HTML for the report type selection box $returnstr = "\n        "; // if there are no formatting options, return if (empty($format_options)) return ($returnstr); // Allow the user to select a format for this report type $returnstr .= "\n"; return ($returnstr); } function DisplayStandings($seasonid, $eventlist, $eventcount, $eventtitle=NULL, $byClass=FALSE, $displayclass=NULL, $shownovice=FALSE, $mbrid=NULL, $mbrdisplay=FALSE, $limitlist=0, $suppressNullOutput=FALSE) { // // This function generates standings for the specified events within // the specified season. The "basic" report is all users, ordered // by standing position. This forms the "Top 100" list. The other // input parameters // // INPUT: // seasonid - Results for all events within this season // eventlist - list of events whose results should be displayed // eventcount - number of events in the season // eventtitle - OPTIONAL: force a single, top-of-page title (overrides byclass) // byclass - OPTIONAL: break results into a 'by class' listing // displayclass - OPTIONAL: limit to results for this specified class // shownovice - OPTIONAL: limit results to novice members only // mbrid - OPTIONAL: member to hilight OR, for single display, limit display // mbrdisplay - OPTIONAL: display ONLY results for the member in mbrid // limitlist - OPTIONAL: display no more than this number (ignore if empty or zero) // suppressNullOutput // - OPTIONAL: if TRUE, will only output results, not bad // or empty data messages. // Initialization global $myresults; // result function object: must already be set $htmlstr = ""; // output html - displayed at end of routine if (($mbrdisplay==TRUE) && empty($mbrid)) { $mbrdisplay=FALSE; // validate: mbrdisplay is only true if mbrid is provided } // Get specified result set $resultset = array(); // array of results, returned by _getStandings // HACK ALERT...manually set qualcount to 6 for 2011SS //if ($seasonid == "2011SS") { if ($seasonid == '2011SS' || $seasonid == '2013SS') { $qualcount = 6; } else { $qualcount = intval(floor($eventcount/2))+1; } // number of events a user must be in to // qualify for a trophy. if ($myresults->_getStandings($resultset, $seasonid, $qualcount, $displayclass, $byClass, $shownovice)==false) { $err = $myresults->_getErrors($sqlerrno, $sqlerr); if ($err == E_RES_OTHER_MYSQL_ERROR) { // Report SQL error while retrieving standards $htmlstr = "

There are no results available at this time (SQL ERR).

"; } else { // Report other error while retrieving standards $htmlstr = "

There are no results available at this time (OTHER ERR).

"; } if ($suppressNullOutput==FALSE) { echo $htmlstr; // display } return; } elseif (empty($resultset) || empty($eventlist)) { // Report successful return from query but no results found $htmlstr = "

There are no results available at this time.

"; if ($suppressNullOutput==FALSE) { echo $htmlstr; // display } return; } // At this point, we know we have results. // Begin the start of the table display // Design the table layout: // // Given the 3-line layout, here is an APPROXIMATE characters-per // column mapping that we can use to get the space we need in // each column. // 1st line: 3, 4, (8+8+8), 8, 8, (8+8+8+8(+8)*), 8, 6 // 2nd line: 3, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, (8)*, 8, 6 // // All event-related points are on the second line and it can // be expanded as needed--though there MUST be a minimum of // 10 event instances for the display to look pretty. // // The colchars table is only used to put in a space-filled line // so that the layout of the table doesn't change drastically // if fields end-up blank. $showevents = ($eventcount<10) ? 10 : $eventcount; // # of event slots to show $spacecols = $showevents -10; // number of columns to throw in to make the math work $columnchars = array_merge ( array(3), // first field array(4), // second field array_pad(array (), $showevents, 8), // number of events to show array(6) // last field ); $columncount = count($columnchars); // number of columns in a table row $layout = array ( array ( // 1st line array( 'name'=>'T', 'width'=>3, ), // Trophy (T) - left just array( 'name'=>'Pos', 'width'=>4 ), // Position(###.) - right just array( 'name'=>'Driver', 'width'=>24, 'cols'=>3 ), // Driver +/- 'N' array( 'name'=>'', 'width'=>8 ), // empty array( 'name'=>'Class', 'width'=>8 ), // Class(/Subclass) array( 'name'=>'Vehicle', 'width'=>($spacecols+4)*8, 'cols'=>$spacecols+4 ), // YY Make Model + extra space array( 'name'=>'', 'width'=>8 ), // empty array( 'name'=>'Total', 'width'=>6 ) // Total points, right justified ) // 2nd line: 1st column and last column are blank, middle columns // are an event total or empty. ); // Open table // To make a good-looking, fixed-width table, create a blank row that has the // correct column information. This is the only direct use of the colchars table. $htmlstr = "\n\n"; foreach($columnchars as $width) { $htmlstr .= '\n"; } $htmlstr .= ""; // initialize common table elements $barrier = sprintf(C_BARRIER, $columncount); $drivercnt = 0; $lastclass_id = NULL; // used to signal the start of a new class $scratchReportVals = array(); // array that keeps the 'rep' anchor values. foreach ($eventlist as $eventid) { // Anchor labels for each available event $scratchReportVals[$eventid] = BuildReportValue(C_EVENT_FULL_REPORT,$eventid); } // Walk through the results and collect each result row into the display foreach ($resultset as $order => $driverset) { foreach ($driverset as $thisdriver) { // If the user wants to limit list to a specific number of drivers if ((!empty($limitlist)) && ($drivernum>=$limitlist)) break; // Detect the start of a new section--either (1) the top of the page or, // if we are breaking the data up by class, (2) the start of a new class. if ( ($lastclass_id==NULL) || (($byClass===TRUE)&& ($lastclass_id != $thisdriver['class_nickname']))) { // Display the heading for a new class or top of page // (skip showing the heading other than the top for // a single heading page. if ( !( (!empty($eventtitle)) && ($lastclass_id!=NULL)) ) { // // 1st line: // KLUDGE: we are just going to display the column titles // from 'Vehicle' onward because the first fields contain // the class name. $fieldstart = 4; $lineheight = $lastclass_id==NULL ? 30 : 45; // more spacing for top of page if (!empty($eventtitle)) { // user provided a top-of-page title $title = $eventtitle; } else if ($byClass===TRUE) { // byclass display: put classname in title $title = (empty($thisdriver['class_name'])) ? $thisdriver['class_nickname'] : $thisdriver['class_name']; } else if (!empty($limitlist)) { // title for a limited list $title = "Top {$limitlist} Drivers"; } else { // default $title = "Driver List"; } $fieldcount = count($layout[0]); $collectcols = 0; for ($ii=0; $ii<$fieldcount; $ii++) { $cols = (empty($layout[0][$ii]['cols'])) ? 1 : $layout[0][$ii]['cols']; if ($ii<$fieldstart) { $collectcols += $cols; if ($ii==($fieldstart-1)) { // We've collected the count of columns prior to the first // important heading: span the class identifier across these columns $remaincols = $columncount-$collectcols; $htmlstr .= "\n" . $barrier . "\n" . "\n\n"; } continue; } $htmlstr .= "\n"; } // // Place column headers for second line $htmlstr .= "\n"; // first two columns are empty for ($ii=1; $ii<($showevents+1); $ii++) { $htmlstr .= ""; } //$htmlstr .= "" . $barrier; $htmlstr .= "". $barrier; } // end display of heading // Initialize at the start of every break: $lastclass_id = $thisdriver['class_nickname']; // used to detect next break $drivernum = 0; // restart numbering at zero for every break } $drivernum++; // Report formatting control: // // If the request is for a single-member report... if (($mbrdisplay==TRUE) && ($mbrid!=$thisdriver['mbr_id'])) { // // ... skip this driver if it isn't the driver of interest continue; } // // For a multiple-member report with a specified driver .... if (($mbrdisplay==FALSE) && !empty($mbrid) && ($mbrid==$thisdriver['mbr_id'])) { // // ... set font/background to hilight the user-of-interest $fonttag = ""; // hilight data $bgcolor = " bgcolor=\"".C_HILIGHT_BG."\""; } else { // // ... set default font/background for a regular user $fonttag = ""; // no hilight $bgcolor = ""; } // *** LINE 2 ************************************************** // YOU MUST BUILD LINE TWO FIRST! // As we build line two we collect information across // multiple events that is used to build the line 1 display. // // Empty columns for columns 1 and 2 $line2 = "\n\n"; // // Now walk through the event fields and put in what we know. $acrossevents = array(); for ($ii=0; $ii<$showevents; $ii++) { $eventid = $eventlist[$ii]; if (empty($eventid) || empty($thisdriver['eventinfo'][$eventid])) { // Empty event $line2 .= ""; } else { // Show event result $eventdata = $thisdriver['eventinfo'][$eventid]; if (!empty($scratchReportVals[$eventid])) { // anchor exists: show with anchor $line2 .= ""; } else { // show without anchor $line2 .= ""; } // Collate the data that is collected for multiple events: // // Events the user drove as a novice if (!empty($eventdata['isnovice'])) { $acrossevents['novice_events'][] = $eventid; } // Classes this driver drove in $acrossevents['class_nickname'][] = $eventdata['class_nickname']; // // Subclasses this driver drove in $acrossevents['subclass_nickname'][] = $eventdata['subclass_nickname']; // // Vehicles used in events ("number - year make model" indexed by makemodel) $bld = array(); if (strlen($eventdata['num']>0)) { $bld[] = $eventdata['num']; $bld[] = '-'; } if (!empty($eventdata['year'])) $bld[] = substr($eventdata['year'], 2, 2); if (!empty($eventdata['make'])) $bld[] = $eventdata['make']; if (!empty($eventdata['model'])) $bld[] = $eventdata['model']; $mykey = strtolower($eventdata['make'].$eventdata['model']); $acrossevents['makemodel'][$mykey][] = implode(' ', $bld); } } // Empty single column // $line2 .= ""; $line2 .= ""; // Spacer row - add after line two $line2 .= "\n"; // // *** LINE 1 ********************************************** // // Trophy / layout[0] $cntevents = 0; if (!empty($acrossevents['class_nickname']) && is_array($acrossevents['class_nickname'])) { // // get frequency count of each class $cntevents = count($acrossevents['class_nickname']); } $htmlstr .= "\n\n" : "Q \n"); // // Pos / layout[1] $htmlstr .= "\n"; // // Driver / layout[2] $thisfield = $layout[0][2]; $novicestr = ((empty($acrossevents['novice_events'])) ? '' : ' (N)'); $bname = doLazyCaps($thisdriver['firstname']).' '.doLazyCaps($thisdriver['lastname']).$novicestr; if (strlen($bname)>(($thisfield['width'])+strlen($novicestr))) { $bname = substr($thisdriver['firstname'],0,1) .'. '.doLazyCaps(substr($thisdriver['lastname'], 0, ($thisfield['width'])-(3+strlen($novicestr)))) . $novicestr; } // this is the character string cut to length $bname = htmlspecialchars($bname); // protect any special characters $htmlstr .= "\n"; // // Empty / layout[3] $thisfield = $layout[0][3]; $htmlstr .= "\n"; // // Class/Subclass / layout[4] $thisfield = $layout[0][4]; $showclass = "Unknown"; // Display string for class [default] if (!empty($acrossevents['class_nickname']) && is_array($acrossevents['class_nickname'])) { // // get frequency count of each class $numarr = array_count_values($acrossevents['class_nickname']); if (count($numarr)!=1) { // Class is not unique: use term 'Various' $showclass="Various"; } else { // Driver ran events in only one class: use class name $showarr = array_keys($numarr); $showclass = $showarr[0]; // Now check for subclass name if (!empty($acrossevents['subclass_nickname']) && is_array($acrossevents['subclass_nickname'])) { // // get frequency count of each subclass $numarr = array_count_values($acrossevents['subclass_nickname']); if (count($numarr)==1) { // Driver used only one subclass: append it $showarr = array_keys($numarr); $showclass .= '/' . $showarr[0]; } } } } $htmlstr .= "\n" : "{$showclass}  \n"); // // Vehicle (Num - YY Make Model) / layout[5] $thisfield = $layout[0][5]; $showit = ""; if (!empty($acrossevents['makemodel']) && is_array($acrossevents['makemodel'])) { // // get frequency count of each makemodel if (count($acrossevents['makemodel']) == 1) { // We only put out vehicle info if the user has driven a // car with the same make'n'model information for all events $numarr = array_values($acrossevents['makemodel']); // flatten array $numarr = array_count_values($numarr[0]); // get freq count of each value arsort($numarr); // arrange with highest freq first $numarr = array_keys($numarr); $showit = $numarr[0]; } else { $showit = "Various"; } } $htmlstr .= ""; // // Empty / layout[6] $thisfield = $layout[0][6]; $htmlstr .= "\n"; // // Total Points / layout[7] $htmlstr .= ""; $htmlstr .= $line2; // End of line 1: now show line 2 $drivercnt++; // full count of drivers } if ((!empty($limitlist)) && ($drivernum>=$limitlist)) break; } // End the table cleanly $htmlstr .= <<< ENDTABLE
' . str_repeat(' ', $width) . "
" . " 
  $title
1) ? " colspan=$cols" : "") . ">  {$layout[0][$ii]['name']}
$ii  
(Avg.)
$fonttag--  $fonttag{$eventdata['points']}  $fonttag{$eventdata['points']}  
$fonttag{$thisdriver['averagepts']}
$fonttag" . (($cntevents<$qualcount) ? "  $fonttag" . (($drivernum<10) ? "  $drivernum." : ( ($drivernum<100) ? " $drivernum." : "$drivernum.")) . " 1) ? " colspan={$thisfield['cols']}" : "") . ">$fonttag$bname  1) ? " colspan={$thisfield['cols']}" : "") . ">1) ? " colspan={$thisfield['cols']}" : "") . ">$fonttag" . (($thisdriver['class_nickname']==$showsubclass) ? "{$thisdriver['class_nickname']}  1) ? " colspan={$thisfield['cols']}" : "") . ">$fonttag" . htmlspecialchars($showit) . "1) ? " colspan={$thisfield['cols']}" : "") . ">$fonttag{$thisdriver['totalpts']}
ENDTABLE; if (!(($drivercnt==0) && ($suppressNullOutput==TRUE))) { echo $htmlstr; // display } return; } function DisplayMySeason ($seasonid, $eventlist, $eventcount, $mbrid) { global $myresults; // Superficial note on display layout: // // To get the multiple tables we display here to layout in // all (most?) browsers, we have to include them in a table. The // page itself is already using an external
tab AND we are // already inside a table within that
. If we use
to // separate these tables, IE (and other) browsers don't display // correctly because mixing
and layouts causes // problems. 'Nuff said. // Display standings from 'ALL' rmsolo display echo "\n
"; DisplayStandings($seasonid, $eventlist, $eventcount, "Standings By Class", TRUE, NULL, FALSE, $mbrid, TRUE, 0, FALSE); echo "\n
"; // Display standings from 'NOVICE' rmsolo display IFF they exist DisplayStandings($seasonid, $eventlist, $eventcount, "Novice Standing", FALSE, NULL, TRUE, $mbrid, TRUE, 0, TRUE); echo "\n
"; $eventcnt = 0; foreach ($eventlist as $eventid) { $mbrclass = $myresults->_isMemberInEvent($eventid, $mbrid); if (empty($mbrclass)) continue; $mbrtitle = GetPageHeader (C_EVENT_FULL_REPORT, $eventid, $eventlist); DisplayFull($eventid, $mbrclass, $mbrid, $mbrtitle, ($eventcnt==0)? C_TBL_STARTMULTIPLE : C_TBL_CONTINUE ); $eventcnt++; } if ($eventcnt>0) echo "\n
"; echo "\n"; return; } // Values for DisplayFull 'tablectrl' parameter // define("C_TBL_SINGLE", "0"); // Opens and closes a table define("C_TBL_STARTMULTIPLE", "1"); // opens but does not close define("C_TBL_CONTINUE", "2"); // does not open or close (continues) function DisplayFull($eventid, $classname=NULL, $mbrid=NULL, $mbrtitle=NULL, $tablectrl=C_TBL_SINGLE) { // // This function generates HTML to display 'full' results for // a given eventid. The results are sorted by primary class and // the full results view, which contains all classes, can be // limited to display full results for a given class or for a // given user. // // INPUT: // eventid - Results for an individual event // classname - OPTIONAL: limit to an individual class within the event // mbrid - OPTIONAL: member to hilight OR for single display // mbrtitle - OPTIONAL: limit to a single member using this title // (if mbrid is set) // tablectrl - OPTIONAL: only used if building multiple calls together // // Initialization global $myresults; // must lready be set $htmlstr = ""; // output building string $resultset = array(); // array of results, returned by _getResults // Additional information returned by _getResults: $res_drivers = 0; // - total number of drivers in resultset $res_rundata = NULL; // - array of runs used in resultset $res_driversinclass = NULL; // - array of drivers per class in resultset // Get specified result set (all or limited to an individual class) $returnset = $myresults->_getFullResults($resultset, $eventid, $classname, FALSE); list($res_status, $res_rundata, $res_driversinclass) = $returnset; $res_drivers = count($resultset); if ($res_status!=TRUE) { // // Error return when fetching results: make the best report we can $err = $myresults->_getErrors($sqlerrno, $sqlerr); if ($err == E_RES_OTHER_MYSQL_ERROR) { // // SQL message error $htmlstr = "

There are no results available at this time.

"; } else { // // Default error message $htmlstr = "

There are no results available at this time.

"; } if (!empty($tablectrl)) echo $htmlstr; // display return; } elseif (empty($res_drivers) || empty($res_rundata)) { // // Successful return from query but no results found $htmlstr = "

There are no results available at this time.

"; if (!empty($tablectrl)) echo $htmlstr; // display return; } // At this point, we know we have results. // Begin the start of the table display // Design the table layout: // // Given the 3-line layout, here is an APPROXIMATE characters-per // column mapping that we can use to get the space we need in // each column. // $columnchars = array (2, 4, 9, 9, 18, 5, 13, 9, 9, 9, 4); $columncount = count($columnchars); $columnpct = array (3, 4, 10, 9, 19, 6, 14, 10, 10, 10, 5); // = 100 // // // The 'columnpct' table is only used in the first "blank-space" // line to set rough column sizes by percentages. $layout = array ( // // Map visible columns into the 'columnchars' column definitons: // 1st line: 2, 4, 9, (9+18+5), (13+9), 9, 9, 4 // 2nd line: (2+4), (9+9+18), (5+13+9+9+9+4) // 3rd line: (2+4), (9+9), (18), (5+13), (9+9), (9+4) // array ( // 1st line array( 'name'=>'T', 'width'=>3, 'align'=>'left' ), // Trophy (T) array( 'name'=>'Pos', 'width'=>4, 'align'=>'right' ), // Position(###.) - right just array( 'name'=>'Num/Cls', 'width'=>7, 'align'=>'right' ), // CarNum (###/class) array( 'name'=>'Driver', 'width'=>30, 'cols'=>3, 'align'=>'left' ), // Driver +/- 'N' array( 'name'=>'  Hometown', 'width'=>20, 'cols'=>2, 'align'=>'left'), // Town, ST array( 'name'=>'(Index)  ', 'width'=>7, 'align'=>'right' ), // Index ( (#.###) ) - right just array( 'name'=>'Best', 'width'=>7, 'align'=>'center'), // Besttime, Indexed ( ###.### ) - right just array( 'name'=>'Pts', 'width'=>4, 'align'=>'center') // Pts (max 1000) - right just ), array ( // 2nd line array( 'name'=>'', 'width'=>7, 'cols'=>2 ), // empty array( 'name'=>'Vehicle', 'width'=>37, 'cols'=>3 ), // YY Make Model / Tires array( 'name'=>'Sponsor', 'width'=>40, 'cols'=>6 ) // Sponsor ), array ( // 3rd line array( 'name'=>'', 'width'=>7, 'cols'=>2 ), // empty array( 'name'=>'', 'width'=>12, 'cols'=>2 ), // 1st run array( 'name'=>'', 'width'=>12 ), // 2nd run array( 'name'=>'', 'width'=>12, 'cols'=>2 ), // 3rd run array( 'name'=>'', 'width'=>12, 'cols'=>2 ), // 4th run array( 'name'=>'', 'width'=>12, 'cols'=>2 ) // empty ) ); // Open table // To make a good-looking, fixed-width table, create a blank row that has the // correct column information. This is the only direct reference to the // 'columnchars' and 'columnpct' variables. if ($tablectrl != C_TBL_CONTINUE) { $htmlstr = "\n\n"; } else { $htmlstr = "\n\n"; } for($ii=0 ; $ii < $columncount ; $ii++) { $htmlstr .= "\n"; } $htmlstr .= ""; // initialize common elements $barrier = sprintf(C_BARRIER, $columncount); // Walk through the results and collect each result row into the display $myclass_id = NULL; foreach ($resultset as $thisdriver) { // If this record starts a new class .... if (($myclass_id==NULL) || ($myclass_id != $thisdriver['class_nickname'])) { // // Display the header for this class // // KLUDGE: we are just going to display the column titles // for the first line from field 4 ('Home Town') onward. $fieldstart = 4; $lineheight = $myclass_id==NULL ? 30 : 45; // was 15:30 $myclass_id = $thisdriver['class_nickname']; $title = (!empty($mbrid) && !empty($mbrtitle)) ? $mbrtitle."  -  " : ""; $title .= (empty($thisdriver['class_name'])) ? $thisdriver['class_nickname'] : $thisdriver['class_name']; $fieldcount = count($layout[0]); $collectcols = 0; for ($ii=0; $ii<$fieldcount; $ii++) { $cols = (empty($layout[0][$ii]['cols'])) ? 1 : $layout[0][$ii]['cols']; if ($ii<$fieldstart) { $collectcols += $cols; if ($ii==($fieldstart-1)) { $remaincols = $columncount-$collectcols; $htmlstr .= "\n" . $barrier . "\n" . "\n\n"; } continue; } $myalign = (empty($layout[0][$ii]['align'])) ? 'left' : $layout[0][$ii]['align']; $htmlstr .= "\n"; } // // Place column headers for second line $htmlstr .= "\n"; $fieldcount = count($layout[1]); for ($ii=0; $ii<$fieldcount; $ii++) { $htmlstr .= "\n"; } $htmlstr .= "" . $barrier; // Init class-related variables $drivernum = 0; $trophycnt = intval(ceil($res_driversinclass[$thisdriver['class_nickname']]/3)); } $drivernum++; if (!empty($mbrid) && !empty($mbrtitle) && ($mbrid!=$thisdriver['mbr_id'])) { // For single-member report: skip this driver if it isn't the driver of interest continue; } // if this is the user of interest in a not-single-user display.... if (!empty($mbrid) && empty($mbrtitle) && ($mbrid==$thisdriver['mbr_id'])) { $fonttag = ""; // hilight data $bgcolor = " bgcolor=\"".C_HILIGHT_BG."\""; } else { $fonttag = ""; // no hilight $bgcolor = ""; } // // *** LINE 1 ********************************************** // // Trophy / layout[0] $htmlstr .= "\n\n" : "T \n"); // // Pos / layout[1] $htmlstr .= "\n"; // // Num/Cls / layout[2] $htmlstr .= "\n"; // // Driver / layout[3] $thisfield = $layout[0][3]; $novicestr = ($thisdriver['isnovice']==0) ? '' : ' (N)'; $bname = doLazyCaps($thisdriver['firstname']).' '.doLazyCaps($thisdriver['lastname']).$novicestr; if (strlen($bname)>(($thisfield['width'])+strlen($novicestr))) { $bname = substr($thisdriver['firstname'],0,1) .'. '.doLazyCaps(substr($thisdriver['lastname'], 0, ($thisfield['width'])-(3+strlen($novicestr)))) . $novicestr; } // this is the character string cut to length $bname = htmlspecialchars($bname); // protect any special characters $htmlstr .= "\n"; // // Hometown / layout[4] $thisfield = $layout[0][4]; $htmlstr .= "\n"; // // (Index) / layout[5] $indextouse =($thisdriver['isIndexClass']==1) ? $thisdriver['paxrtp_index'] : 0; $htmlstr .= "\n"; // Best / layout[6] // NOTE: for indexed classes, the best time displayed is the indexed best time; // for regular classes it is just the straight best time. I don't know why. $timetouse =($thisdriver['isIndexClass']==1) ? 'besttime_index' : 'besttime'; $htmlstr .= "\n"; // // Pts / layout[7] $htmlstr .= "\n"; // // *** LINE 2 ********************************************** // // Empty / layout[0] $thisfield = $layout[1][0]; $htmlstr .= "\n"; // // Vehicle (YY Make Model / Tire) / layout[1] $thisfield = $layout[1][1]; $bld = array(); $bld[] = (empty($thisdriver['year'])) ? "" : substr($thisdriver['year'], 2, 2); $bld[] = $thisdriver['make']; $bld[] = $thisdriver['model']; $bldstr = implode(' ', $bld); $tires = (empty($thisdriver['tires'])) ? "" : ' / '.$thisdriver['tires']; $bldstr = htmlspecialchars(substr($bldstr, 0, ($thisfield['width'])-strlen($tires)).$tires); $htmlstr .= ""; // // Sponsor / layout[2] $thisfield = $layout[1][2]; $htmlstr .= "\n"; // // *** LINE 3 (and event more) ***************************** // // There are 6 scores on a line: walk through the rundata // and display which ones we have, generating new lines as needed $thisfieldset = $layout[2]; $runnums = array_keys($res_rundata); $runcount = count($runnums); $run = 0; while ($run < $runcount) { // empty 1st column $htmlstr .= "\n"; // Add up to maxperline run instances $maxperline = 7; for ($countbat=0; $countbat < $maxperline; $countbat++) { $fieldid = $countbat+1; if ($run < $runcount) { // enter run information if we aren't out $runid = $runnums[$run]; $htmlstr .= "\n"; $run++; } else { // enter empty column $htmlstr .= "\n"; } } // empty last column $htmlstr .= "\n"; $countbat = 0; } // Spacer $htmlstr .= ""; } // End the table cleanly if ($tablectrl == C_TBL_SINGLE) { $htmlstr .= "
" . str_repeat(' ', $columnchars[$ii]) . "
" . " 
$title
1) ? " colspan=$cols" : "") . ">{$layout[0][$ii]['name']}
  {$layout[1][$ii]['name']}
$fonttag" . (($drivernum>$trophycnt) ? "  $fonttag" . (($drivernum<10) ? "  $drivernum." : ( ($drivernum<100) ? " $drivernum." : "$drivernum.")) . " $fonttag{$thisdriver['car_number']}/{$thisdriver['subclass_nickname']}  1) ? " colspan={$thisfield['cols']}" : "") . ">$fonttag$bname  1) ? " colspan={$thisfield['cols']}" : "") . ">$fonttag" . htmlspecialchars(doLazyCaps(substr($thisdriver['city'], 0, $thisfield['width']-4))) . ", {$thisdriver['state']}" . "  $fonttag" . ((!empty($indextouse)) ? '('.sprintf('%01.3f', $indextouse).')' : ' ') . "  $fonttag" . ((!empty($thisdriver[$timetouse])) ? sprintf('%01.3f', $thisdriver[$timetouse]) : '--') . "  $fonttag" . ((!empty($thisdriver['points'])) ? $thisdriver['points'] : '--') . "
1) ? " colspan={$thisfield['cols']}" : "") . ">1) ? " colspan={$thisfield['cols']}" : "") . ">$fonttag$bldstr1) ? " colspan={$thisfield['cols']}" : "") . ">$fonttag" . htmlspecialchars($thisdriver['sponsor']) . "
1) ? " colspan={$thisfieldset[0]['cols']}" : "") . ">1) ? " colspan={$thisfieldset[$fieldid]['cols']}" : "") . ">$fonttag$runid) " // . (!empty($thisdriver['pen'.$runid]) ? // $thisdriver['pen'.$runid] // : (!empty($thisdriver['runtime'.$runid]) ? // $thisdriver['runtime'.$runid]. (!empty($thisdriver['pyl'.$runid]) ? // " + {$thisdriver['pyl'.$runid]}" : "") // : '--')) . (!empty($thisdriver['runtime'.$runid]) ? $thisdriver['runtime'.$runid]. (!empty($thisdriver['pen'.$runid]) ? " {$thisdriver['pen'.$runid]}" : (!empty($thisdriver['pyl'.$runid]) ? " + {$thisdriver['pyl'.$runid]}" : "")) : '--') . "  1) ? " colspan={$thisfieldset[$fieldid+1]['cols']}" : "") . ">1) ? " colspan={$thisfieldset[$countbat+1]['cols']}" : "") . ">
"; } echo $htmlstr; // display return; } function DisplayIndexedResults($eventid, $shownovice=NULL, $mbrid=NULL) { // // This function collects the reserved numbers for the given class // (or all classes if the class_id is unspecified), generates // the appropriate HTML and displays it // Initialization global $myresults; $htmlstr = ""; // output building string $resultset = array(); // array of results, returned by _getResults // Additional information returned by _getResults: $res_drivercount = 0; // - total number of drivers in resultset // Get specified result set $returnset = $myresults->_getIndexedResults($resultset, $eventid, $classname, $shownovice); list($res_status, $res_drivercount) = $returnset; if ($res_status!=TRUE) { // // Error return when fetching results: make the best report we can $err = $myresults->_getErrors($sqlerrno, $sqlerr); if ($err == E_RES_OTHER_MYSQL_ERROR) { // // SQL message error $htmlstr = <<< BADSQL_CASE

There are no results available at this time.

BADSQL_CASE; } else { // // Default error message $htmlstr = <<< BADRESULTS_CASE

There are no results available at this time.

BADRESULTS_CASE; } echo $htmlstr; // display return; } elseif (empty($res_drivercount)) { // // Successful return from query but no results found $htmlstr = <<< NORESULTS_CASE

There are no results available at this time.

NORESULTS_CASE; echo $htmlstr; // display return; } // At this point, we know we have results. // Begin the start of the table display // Design the table layout: // To make a good-looking, set-up the titles and the widths in chars // for each column NOTE: If you want to change the table width later, // change the layout here! $layout = array( // Arrays of column name, width in chars and justification array( 'name'=>'', 'width'=>4 ), // Position(###.) array( 'name'=>'Num ', 'width'=>3, 'just'=>'left' ), // Car Num (###) array( 'name'=>' Cls', 'width'=>4, 'just'=>'left' ), // Car Class (CLASS) array( 'name'=>'  Driver', 'width'=>30, 'just'=>'left' ), // Driver +/- 'N' array( 'name'=>'', 'width'=>3 ), // Vehicle Year 'YY ' array( 'name'=>'  Vehicle', 'width'=>17, 'just'=>'left' ), // Vehicle Make/Model array( 'name'=>'(Index)  ', 'width'=>7, 'just'=>'right' ), // Index ( (#.###) ) array( 'name'=>'Ind. Time', 'width'=>7, 'just'=>'center'), // Besttime, Indexed ( ###.### ) array( 'name'=>'Pts', 'width'=>4, 'just'=>'center') // Pts (max 1000) ); $layout_all_columns = count($layout); // Open table // // To make a good-looking, fixed-width table, create a blank row that // fills all columns to set their widths (+2 for spacing). $htmlstr = "\n\n"; // // Build column header $title = ($shownovice==TRUE) ? 'Novice Drivers' : 'All Drivers'; $barrier = sprintf(C_BARRIER, $layout_all_columns); $htmlstr .= "\n" . $barrier . "\n\n"; for ($ii=0; $ii<$layout_all_columns; $ii++) { $myalign = (empty($layout[$ii]['just'])) ? 'left' : $layout[$ii]['just']; $htmlstr .= "\n"; } $htmlstr .= "\n" . $barrier; // Init class-related variables $drivernum = 0; // Walk through the results and collect each result row into the display foreach ($resultset as $thisdriver) { // if this is the user of interest in a not-single-user display.... if (!empty($mbrid) && empty($mbrtitle) && ($mbrid==$thisdriver['mbr_id'])) { $fonttag = ""; // hilight data $bgcolor = " bgcolor=\"".C_HILIGHT_BG."\""; } else { $fonttag = ""; // no hilight $bgcolor = ""; } // Display the driver information // // -- Pos / layout[0] $drivernum++; $htmlstr .= "\n"; // // -- Num / layout[1] $htmlstr .= "\n"; // // -- Class / layout[2] $htmlstr .= "\n" : "{$thisdriver['class_nickname']}/{$thisdriver['subclass_nickname']}  \n"); // // Driver / layout[3] $novicestr = ($thisdriver['isnovice']==0) ? '' : ' (N)'; $bname = doLazyCaps($thisdriver['firstname']).' '.doLazyCaps($thisdriver['lastname']).$novicestr; if (strlen($bname)>($layout[3]['width'])) { $bname = substr($thisdriver['firstname'],0,1) .'. '.doLazyCaps(substr($thisdriver['lastname'], 0, ($layout[3]['width'])-(3+strlen($novicestr)))) . $novicestr; } // this is the character string cut to length $bname = htmlspecialchars($bname); // protect any special characters $htmlstr .= "\n"; // // Vehicle YY / layout[4] $year = (empty($thisdriver['year'])) ? " " : substr($thisdriver['year'], 2, 2); $year = str_replace(" ", " ", $year); // year, sized and displayable $htmlstr .= ""; // // Vehicle (Make Model) / layout[5] $makemodel = htmlspecialchars(substr (" {$thisdriver['make']} {$thisdriver['model']}", 0, ($layout[5]['width'])-strlen($year))); // makemodel sized and displayable $htmlstr .= ""; // // (Index) / layout[6] $htmlstr .= "\n"; // // Index Time / layout[7] $htmlstr .= "\n"; // // Pts / layout[8] $htmlstr .= ""; } // End the table cleanly $htmlstr .= <<< ENDTABLE
 
  $title
 {$layout[$ii]['name']}
$fonttag" . (($drivernum<10) ? "  $drivernum." : ( ($drivernum<100) ? " $drivernum." : "$drivernum.")) . "  $fonttag{$thisdriver['car_number']}  $fonttag" . (($thisdriver['class_nickname']==$thisdriver['subclass_nickname']) ? "{$thisdriver['class_nickname']}  $fonttag$bname  $fonttag$year $fonttag$makemodel  $fonttag(" . ((!empty($thisdriver['paxrtp_index'])) ? sprintf('%01.3f', $thisdriver['paxrtp_index']) : '0.000') . ")  $fonttag" . ((!empty($thisdriver['besttime_index'])) ? sprintf('%01.3f', $thisdriver['besttime_index']) : '--') . "  $fonttag" . ((!empty($thisdriver['points'])) ? $thisdriver['points'] : '--') . "
ENDTABLE; echo $htmlstr; // display return; } function DisplayRawResults($eventid, $mbrid=NULL) { // // This function collects the reserved numbers for the given class // (or all classes if the class_id is unspecified), generates // the appropriate HTML and displays it // Initialization global $myresults; $htmlstr = ""; // output building string $resultset = array(); // array of results, returned by _getResults // Additional information returned by _getResults: $res_drivercount = 0; // - total number of drivers in resultset // Get specified result set $returnset = $myresults->_getRawResults($resultset, $eventid, $classname); list($res_status, $res_drivercount) = $returnset; if ($res_status!=TRUE) { // // Error return when fetching results: make the best report we can $err = $myresults->_getErrors($sqlerrno, $sqlerr); if ($err == E_RES_OTHER_MYSQL_ERROR) { // // SQL message error $htmlstr = <<< BADSQL_CASE

There are no results available at this time. (BADSQL)

BADSQL_CASE; } else { // // Default error message $htmlstr = <<< BADRESULTS_CASE

There are no results available at this time. (BADRES) $err

BADRESULTS_CASE; } echo $htmlstr; // display return; } elseif (empty($res_drivercount)) { // // Successful return from query but no results found $htmlstr = <<< NORESULTS_CASE

There are no results available at this time. (NORES)

NORESULTS_CASE; echo $htmlstr; // display return; } // At this point, we know we have results. // Begin the start of the table display // Design the table layout: // To make a good-looking, set-up the titles and the widths in chars // for each column NOTE: If you want to change the table width later, // change the layout here! $layout = array( // Arrays of column name, width in chars and justification array( 'name'=>'', 'width'=>4 ), // Position(###.) array( 'name'=>'Num ', 'width'=>3, 'just'=>'left' ), // Car Num (###) array( 'name'=>' Cls', 'width'=>4, 'just'=>'left' ), // Car Class (CLASS) array( 'name'=>'  Driver', 'width'=>30, 'just'=>'left' ), // Driver +/- 'N' array( 'name'=>'', 'width'=>3 ), // Vehicle Year 'YY ' array( 'name'=>'  Vehicle', 'width'=>17, 'just'=>'left' ), // Vehicle Make/Model // array( 'name'=>'(Index)  ', 'width'=>7, 'just'=>'right' ), // Index ( (#.###) ) array( 'name'=>'Time', 'width'=>7, 'just'=>'center'), // Besttime ( ###.### ) // array( 'name'=>'Pts', 'width'=>4, 'just'=>'center') // Pts (max 1000) ); $layout_all_columns = count($layout); // Open table // // To make a good-looking, fixed-width table, create a blank row that // fills all columns to set their widths (+2 for spacing). $htmlstr = "\n\n"; // // Build column header $title = ($shownovice==TRUE) ? 'Novice Drivers' : 'All Drivers'; $barrier = sprintf(C_BARRIER, $layout_all_columns); $htmlstr .= "\n" . $barrier . "\n\n"; for ($ii=0; $ii<$layout_all_columns; $ii++) { $myalign = (empty($layout[$ii]['just'])) ? 'left' : $layout[$ii]['just']; $htmlstr .= "\n"; } $htmlstr .= "\n" . $barrier; // Init class-related variables $drivernum = 0; // Walk through the results and collect each result row into the display foreach ($resultset as $thisdriver) { // if this is the user of interest in a not-single-user display.... if (!empty($mbrid) && empty($mbrtitle) && ($mbrid==$thisdriver['mbr_id'])) { $fonttag = ""; // hilight data $bgcolor = " bgcolor=\"".C_HILIGHT_BG."\""; } else { $fonttag = ""; // no hilight $bgcolor = ""; } // Display the driver information // // -- Pos / layout[0] $drivernum++; $htmlstr .= "\n"; // // -- Num / layout[1] $htmlstr .= "\n"; // // -- Class / layout[2] $htmlstr .= "\n" : "{$thisdriver['class_nickname']}/{$thisdriver['subclass_nickname']}  \n"); // // Driver / layout[3] $novicestr = ($thisdriver['isnovice']==0) ? '' : ' (N)'; $bname = doLazyCaps($thisdriver['firstname']).' '.doLazyCaps($thisdriver['lastname']).$novicestr; if (strlen($bname)>($layout[3]['width'])) { $bname = substr($thisdriver['firstname'],0,1) .'. '.doLazyCaps(substr($thisdriver['lastname'], 0, ($layout[3]['width'])-(3+strlen($novicestr)))) . $novicestr; } // this is the character string cut to length $bname = htmlspecialchars($bname); // protect any special characters $htmlstr .= "\n"; // // Vehicle YY / layout[4] $year = (empty($thisdriver['year'])) ? " " : substr($thisdriver['year'], 2, 2); $year = str_replace(" ", " ", $year); // year, sized and displayable $htmlstr .= ""; // // Vehicle (Make Model) / layout[5] $makemodel = htmlspecialchars(substr (" {$thisdriver['make']} {$thisdriver['model']}", 0, ($layout[5]['width'])-strlen($year))); // makemodel sized and displayable $htmlstr .= ""; // // Best Raw Time / layout[6] $htmlstr .= "\n"; } // End the table cleanly $htmlstr .= <<< ENDTABLE
 
  $title
 {$layout[$ii]['name']}
$fonttag" . (($drivernum<10) ? "  $drivernum." : ( ($drivernum<100) ? " $drivernum." : "$drivernum.")) . "  $fonttag{$thisdriver['car_number']}  $fonttag" . (($thisdriver['class_nickname']==$thisdriver['subclass_nickname']) ? "{$thisdriver['class_nickname']}  $fonttag$bname  $fonttag$year $fonttag$makemodel  $fonttag" . ((!empty($thisdriver['besttime'])) ? sprintf('%01.3f', $thisdriver['besttime']) : '--') . "  
ENDTABLE; echo $htmlstr; // display return; } ?> Rocky Mountain Solo Series
Rocky Mountain Solo Logo
Join Now! Colorado Region Continental Divide Region SCCA Home Thanks to Riptide Hosting, Inc. for the Windows® Dedicated Server hosting AutoHaus of Boulder

RMSolo Summer Series 2005

RMSolo Summer Series 2006

RMSolo Summer Series 2007

RMSolo Summer Series 2008

RMSolo Summer Series 2009

RMSolo Summer Series 2010

RMSolo Summer Series 2011

RMSolo Summer Series 2012

RMSolo Summer Series 2013