D:\host\scoreman.in\upstate2025closed\functions best working 14.php
<?php
require_once 'PHPMailer/PHPMailer.php';
require_once 'PHPMailer/SMTP.php';
require_once 'PHPMailer/Exception.php';
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
function buildSpeedEventSummary(mysqli $con, $repdistrict = '')
{
// ---- header info (championships) ----
$eventtitle = $eventdate = '';
if ($repdistrict !== '') {
$sqlC = 'SELECT championshiptitle, dates FROM championships WHERE district = ? ORDER BY id DESC LIMIT 1';
if ($st = mysqli_prepare($con, $sqlC)) {
mysqli_stmt_bind_param($st, 's', $repdistrict);
mysqli_stmt_execute($st);
if (function_exists('mysqli_stmt_get_result')) {
$rs = mysqli_stmt_get_result($st);
if ($row = mysqli_fetch_assoc($rs)) {
$eventtitle = trim($row['championshiptitle']);
$eventdate = trim($row['dates']);
}
if ($rs) mysqli_free_result($rs);
}
mysqli_stmt_close($st);
}
}
// ---- speed events order (quad first, then inline) ----
$events = array(
'rink1' => 'rink1', 'rink2' => 'rink2', 'rink3' => 'rink3',
'road1' => 'road1', 'road2' => 'road2',
'rink4' => 'rink4', 'rink5' => 'rink5', 'rink6' => 'rink6', 'rink7' => 'rink7',
'p2p' => 'p2p', 'elim' => 'elim',
'road3' => 'road3', 'road4' => 'road4', 'road5' => 'road5',
'p2prd' => 'p2prd', 'elimrd'=> 'elimrd',
'relay' => 'relay', 'mixedrelay' => 'mixedrelay'
// 'marathon' // omit if not required
);
// ---- fetch all needed data ----
$cols = array_merge(array('agegroup','agorder','gender'), array_keys($events));
$select = '`' . implode('`,`', $cols) . '`';
$where = 'order_status="Success"';
$types = '';
$params = array();
if ($repdistrict !== '') {
$where .= ' AND repdistrict = ?';
$types .= 's';
$params[] = $repdistrict;
}
// optional: ignore blank chno entries if you prefer
// $where .= ' AND chno <> ""';
$sql = "SELECT $select FROM applications WHERE $where";
$sql .= " ORDER BY agorder+0, gender DESC"; // Cadet.. Senior by agorder; Boys after Girls (DESC -> M,F depends on your data)
$rows = array();
if ($st = mysqli_prepare($con, $sql)) {
if ($types !== '') {
$bind = array($st, $types);
foreach ($params as $k => $v) { $bind[] = &$params[$k]; }
call_user_func_array('mysqli_stmt_bind_param', $bind);
}
mysqli_stmt_execute($st);
if (function_exists('mysqli_stmt_get_result')) {
$rs = mysqli_stmt_get_result($st);
while ($r = mysqli_fetch_assoc($rs)) $rows[] = $r;
if ($rs) mysqli_free_result($rs);
} else {
mysqli_stmt_store_result($st);
$meta = mysqli_stmt_result_metadata($st);
$fields = array(); $cur = array(); $bindRes = array();
while ($f = mysqli_fetch_field($meta)) { $fields[] = $f->name; $bindRes[] = &$cur[$f->name]; }
call_user_func_array('mysqli_stmt_bind_result', array_merge(array($st), $bindRes));
while (mysqli_stmt_fetch($st)) {
$rr = array();
foreach ($fields as $f) $rr[$f] = $cur[$f];
$rows[] = $rr;
}
}
mysqli_stmt_close($st);
}
// ---- accumulate counts: summary[agorder]['label'] + ['Female'|'Male'][event] ----
$summary = array(); // agorder => ['agegroup'=>..., 'Female'=>[], 'Male'=>[]]
$grand = array(); // event => total
foreach ($events as $ev => $lbl) { $grand[$ev] = 0; }
// helper to decide if a cell counts as an entry
$countsAsEntry = function($v) {
if ($v === null) return false;
$v = strtoupper(trim((string)$v));
// count entries that are participating or placed; ignore explicit Absent
return ($v === 'P' || $v === '1' || $v === '2' || $v === '3' || $v === 'G' || $v === 'S' || $v === 'B' || $v === 'A');
};
foreach ($rows as $r) {
$agorder = isset($r['agorder']) ? trim($r['agorder']) : '999';
if (!isset($summary[$agorder])) {
$summary[$agorder] = array(
'agegroup' => trim($r['agegroup']),
'Female' => array(),
'Male' => array(),
);
foreach (array('Female','Male') as $g) {
foreach ($events as $ev => $lbl) $summary[$agorder][$g][$ev] = 0;
}
}
$gender = strtolower(trim($r['gender']));
$gkey = (in_array($gender, array('f','female','girl','girls','women','woman'), true)) ? 'Female' : 'Male';
foreach ($events as $ev => $lbl) {
if ($countsAsEntry(isset($r[$ev]) ? $r[$ev] : null)) {
$summary[$agorder][$gkey][$ev] += 1;
$grand[$ev] += 1;
}
}
}
// ---- render HTML ----
ob_start();
?>
<style>
.evt-sum { width: 100%; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 12px; }
.evt-sum th, .evt-sum td { border: 1px solid #333; padding: 4px 6px; text-align: right; }
.evt-sum th:first-child, .evt-sum td:first-child { text-align: left; }
.evt-sum thead th { background: #f2f2f2; font-weight: bold; }
.evt-sum .ag { font-weight: bold; text-align: left; }
.evt-sum .sex { text-align: left; width: 80px; }
.evt-title { text-align:center; font-weight:bold; font-size:16px; margin:4px 0 10px; }
.evt-sub { text-align:center; font-size:12px; margin-top:-6px; margin-bottom:10px; }
.evt-sum tfoot td { font-weight: bold; background:#f7f7f7; }
/* optional: rotate headers */
.vhead { writing-mode: vertical-rl; transform: rotate(180deg); white-space:nowrap; padding:6px 2px; min-width:16px; }
@media print {
.evt-title { margin-top:0 }
}
</style>
<div class="evt-title"><?php echo htmlspecialchars($eventtitle !== '' ? $eventtitle : 'EVENT SUMMARY', ENT_QUOTES, 'UTF-8'); ?></div>
<div class="evt-sub">EVENT SUMMARY - SPEED<?php echo $eventdate ? ' | ' . htmlspecialchars($eventdate, ENT_QUOTES, 'UTF-8') : ''; ?></div>
<table class="evt-sum">
<thead>
<tr>
<th>Age Group</th>
<th class="sex">Gender</th>
<?php foreach ($events as $ev => $lbl): ?>
<th><span class="vhead"><?php echo htmlspecialchars($lbl, ENT_QUOTES, 'UTF-8'); ?></span></th>
<?php endforeach; ?>
</tr>
</thead>
<tbody>
<?php
ksort($summary, SORT_NATURAL);
foreach ($summary as $agorder => $blk):
$agegroup = $blk['agegroup'];
?>
<tr>
<td class="ag" rowspan="2"><?php echo htmlspecialchars($agegroup, ENT_QUOTES, 'UTF-8'); ?></td>
<td class="sex">Female</td>
<?php foreach ($events as $ev => $lbl): ?>
<td><?php echo (int)$blk['Female'][$ev]; ?></td>
<?php endforeach; ?>
</tr>
<tr>
<td class="sex">Male</td>
<?php foreach ($events as $ev => $lbl): ?>
<td><?php echo (int)$blk['Male'][$ev]; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot>
<tr>
<td colspan="2">Grand Total</td>
<?php foreach ($events as $ev => $lbl): ?>
<td><?php echo (int)$grand[$ev]; ?></td>
<?php endforeach; ?>
</tr>
</tfoot>
</table>
<?php
return ob_get_clean();
}
function buildCertificatesHTML(
mysqli $con,
$repdistrict = '',
array $onlyAppnos = null,
$certPrefix = 'TNDT2025/',
$bgPath = 'certbg.jpg'
) {
$eventTitle=''; $eventDate=''; $eventVenue=''; $president=''; $secretary=''; $districtSafe=$repdistrict;
// $fetchChamp = function(mysqli $con, $repdistrict){
// if ($st = mysqli_prepare($con, "SELECT * FROM championships WHERE district = ? ORDER BY id DESC LIMIT 1")) {
// mysqli_stmt_bind_param($st,"s",$repdistrict);
// mysqli_stmt_execute($st);
// if (function_exists('mysqli_stmt_get_result')) {
// $res = mysqli_stmt_get_result($st);
// if ($row = mysqli_fetch_assoc($res)) { mysqli_stmt_close($st); return $row; }
// if ($res) mysqli_free_result($res);
// }
// mysqli_stmt_close($st);
// }
// $row=null;
// return $row;
// };
// if ($champ = $fetchChamp($con,$repdistrict)) {
// $eventTitle = (string)($champ['championshiptitle'] ?? '');
// $eventDate = (string)($champ['dates'] ?? '');
// $eventVenue = (string)($champ['venue'] ?? '');
// $president = (string)($champ['president'] ?? '');
// $secretary = (string)($champ['secretary'] ?? '');
// $districtSafe = (string)($champ['district'] ?? $repdistrict);
// }
$databaseQuery = 'SELECT * FROM `championships` WHERE `district`="'.$con->real_escape_string($repdistrict).'"';
$result3 = mysqli_query($con,$databaseQuery) or die('Query failed: ' . mysqli_error());
while($row = mysqli_fetch_array($result3))
{
// $eventtitle=trim($row["championshiptitle"]);
// $eventdate=trim($row["dates"]);
$eventTitle = (string)($row['championshiptitle'] ?? '');
$eventDate = (string)($row['dates'] ?? '');
$eventVenue = (string)($row['venue'] ?? '');
$president = (string)($row['president'] ?? '');
$secretary = (string)($row['secretary'] ?? '');
$districtSafe = (string)($row['district'] ?? $repdistrict);
}
// Include ALL event columns now
$cols = [
'appno','sname','dob','agegroup','gender','club','clubname','photourl',
// Speed-Quad
'rink1','rink2','rink3','road1','road2',
// Speed-Inline
'rink4','rink5','rink6','rink7','p2p','elim','relay','mixedrelay','road3','road4','road5','p2prd','elimrd','marathon',
// Artistic
'figure','free','pair','solodance','pairdance','inlinefree','quartet','precisionskating','showgroup',
// Hockey
'quadhockey','mixedrollerhockey','inlinehockey',
// Freestyle
'speedslalom','classicslalom','pairslalom',
// Other Games
'alpine','downhill','rollerderby','rollerfreestyle','skateboarding','scooter'
];
$select = '`'.implode('`,`',$cols).'`';
$where = "order_status='Success'";
$types=''; $params=[];
if ($repdistrict!==''){ $where.=" AND repdistrict=?"; $types.='s'; $params[]=$repdistrict; }
if ($onlyAppnos && count($onlyAppnos)){
$where.=" AND appno IN (".implode(',',array_fill(0,count($onlyAppnos),'?')).")";
$types.=str_repeat('s',count($onlyAppnos));
foreach($onlyAppnos as $a){ $params[]=(string)$a; }
}
$sql = "SELECT $select FROM applications WHERE $where
ORDER BY agegroup, gender DESC, CAST(appno AS UNSIGNED)";
$rows=[];
if ($st = mysqli_prepare($con,$sql)) {
if ($types!==''){
$bind=[&$types]; foreach($params as $i=>$v){ $bind[]=&$params[$i]; }
call_user_func_array('mysqli_stmt_bind_param',array_merge([$st],$bind));
}
mysqli_stmt_execute($st);
if (function_exists('mysqli_stmt_get_result')) {
$res = mysqli_stmt_get_result($st);
while($r=mysqli_fetch_assoc($res)) $rows[]=$r;
if ($res) mysqli_free_result($res);
} else {
mysqli_stmt_store_result($st);
$meta = mysqli_stmt_result_metadata($st);
$fields=[]; $row=[]; $bindRes=[];
while($f=mysqli_fetch_field($meta)){ $fields[]=$f->name; $bindRes[]=&$row[$f->name]; }
call_user_func_array('mysqli_stmt_bind_result',array_merge([$st],$bindRes));
while(mysqli_stmt_fetch($st)){ $r=[]; foreach($fields as $f){ $r[$f]=$row[$f]; } $rows[]=$r; }
}
mysqli_stmt_close($st);
}
$resultLabel = function($v){
$v = strtoupper(trim((string)$v));
if ($v==='1' || $v==='G') return 'FIRST';
if ($v==='2') return 'SECOND'; // do NOT map 'S' to second anymore
if ($v==='3' || $v==='B') return 'THIRD';
if ($v==='S') return 'SELECTED'; // NEW
if ($v==='F') return 'FORWARD'; // optional: only if you store F
if ($v==='P') return 'PARTICIPATED';
// Hide Absent/empty by treating them as NIL (mkRows skips NIL)
return 'NIL';
};
$isMerit = function($lbl) { return in_array($lbl, array('FIRST','SECOND','THIRD'), true); };
$genderWord = function($g){
$g=strtolower(trim((string)$g));
if (in_array($g,['f','female','girl','girls','women','woman'],true)) return 'Girls';
if (in_array($g,['m','male','boy','boys','men','man'],true)) return 'Boys';
return ucfirst($g);
};
// Maps for all disciplines (labels per your spec)
$quadMap = [
'rink1'=>'RINK - I','rink2'=>'RINK - II','rink3'=>'RINK - III','road1'=>'ROAD - I','road2'=>'ROAD - II'
];
$inlineMap = [
'p2p'=>'POINTS (TRACK)','elim'=>'ELIMINATION (RINK)',
'rink4'=>'RINK - IV','rink5'=>'RINK - V','rink6'=>'RINK - VI','rink7'=>'RINK - VII (Dual TT)',
'road3'=>'ROAD - III','road4'=>'ROAD - IV','road5'=>'ROAD - V',
'p2prd'=>'POINT TO POINT (ROAD)','elimrd'=>'ELIMINATION (ROAD)','relay'=>'RELAY','mixedrelay'=>'MIXED RELAY','marathon'=>'MARATHON'
];
$artisticMap = [
'figure'=>'FIGURE','free'=>'FREE','pair'=>'PAIR','solodance'=>'SOLO DANCE','pairdance'=>'PAIR DANCE',
'inlinefree'=>'INLINE FREE','quartet'=>'QUARTET','precisionskating'=>'PRECISION SKATING','showgroup'=>'SHOW GROUP'
];
$rollerHockeyMap = [
'quadhockey'=>'ROLLER HOCKEY','mixedrollerhockey'=>'MIXED ROLLER HOCKEY'
];
$inlineHockeyMap = [
'inlinehockey'=>'INLINE HOCKEY'
];
$freestyleMap = [
'speedslalom'=>'SPEED SLALOM','classicslalom'=>'CLASSIC SLALOM','pairslalom'=>'PAIR SLALOM'
];
$otherGamesMap = [
'alpine'=>'ALPINE','downhill'=>'DOWNHILL','rollerderby'=>'ROLLER DERBY','rollerfreestyle'=>'ROLLER FREESTYLE',
'skateboarding'=>'SKATEBOARDING','scooter'=>'SCOOTER'
];
$districtSlug = preg_replace('/[^A-Za-z0-9_-]/','_',$districtSafe);
$bgAttr = htmlspecialchars($bgPath,ENT_QUOTES,'UTF-8');
$css = '<style>
:root{
--ink:#0b2a6f; --title:#12306e; --accent:#274b9a;
--line:#c3d2f2; --sig-bottom:68mm;
--hdr-top:10mm; --hdr-bottom:4mm; --logo-max-h:28mm;
--photo-size:34mm; --name-size:20pt; --title-size:19pt;
--ring:1mm; --corner:4mm; --grad-a:#7a2cff; --grad-b:#ff3aa6; --grad-c:#3a8dff;
}
*{box-sizing:border-box}
@page{ size:A4; margin:0 }
html,body{ height:100% }
body{ font-family:Arial,Helvetica,sans-serif; color:var(--ink); margin:0; -webkit-print-color-adjust:exact; print-color-adjust:exact; }
.certpage{ page-break-after:always } .certpage:last-child{ page-break-after:auto }
.sheet{ position:relative; width:210mm; height:297mm; overflow:hidden; display:grid; grid-template-rows:auto 1fr auto; }
.pagebg{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; z-index:-1; }
.hdr{ text-align:center; padding:var(--hdr-top) 16mm var(--hdr-bottom) }
.logoCenter{ display:block; margin:0 auto 4mm; width:85%; height:auto; max-height:var(--logo-max-h) }
.titleCert{ font-size:var(--title-size); font-weight:800; letter-spacing:.4px; margin:0; color:var(--title); text-transform:uppercase }
.certno{ font-size:10pt; margin:2px 0 5mm }
.content{ display:flex; flex-direction:column; align-items:center; padding:0 16mm; padding-bottom: calc(var(--sig-bottom) + 6mm); }
.content-inner{ max-width:138mm; text-align:center; width:100% }
.idrow{ display:flex; justify-content:center; margin:4mm 0 }
.photoFrame{ width:var(--photo-size); height:var(--photo-size); padding:var(--ring); border-radius:var(--corner);
background:linear-gradient(135deg,var(--grad-a) 0%,var(--grad-b) 45%,var(--grad-c) 100%); box-shadow:0 .8mm 2mm rgba(0,0,0,.12);}
.photo{ width:100%; height:100%; border-radius:var(--corner); object-fit:cover; background:#fff; display:block; }
.photo.ph{ display:flex; align-items:center; justify-content:center; background:#eef3ff; color:var(--ink); font-weight:700; border-radius:var(--corner) }
.name{ font-size:var(--name-size); font-weight:900; letter-spacing:.8px; margin:1.6mm 0 2.6mm; text-transform:uppercase }
.line{ margin:1.6mm 0 }
.events{ display:flex; gap:6mm; justify-content:center; margin-top:4mm; flex-wrap:wrap }
.blk{ width:70mm }
.blk h4{ margin:0 0 2mm; font-size:11.5pt; text-transform:uppercase; border-bottom:1px solid var(--accent); padding-bottom:2px; color:var(--accent) }
table.ev{ width:100%; border-collapse:collapse; font-size:10.5pt }
table.ev td{ border-bottom:0.8px dotted var(--line); padding:2.5px 2px }
table.ev td:first-child{ text-align:left; width:62% }
table.ev td:last-child{ text-align:right; width:38%; font-weight:800 }
.footer{ position:absolute; left:16mm; right:16mm; bottom:var(--sig-bottom); z-index:1; }
.signs{ display:flex; justify-content:space-between; gap:10mm }
.sigbox{ width:46%; text-align:center }
.signame{ font-weight:800; margin-top:0 }
.sigrole{ margin-top:1.2mm }
</style>';
$pages=[];
$mkRows = function($map,$row,&$hasMerit) use($resultLabel,$isMerit){
$h='';
foreach($map as $k=>$label){
$val = isset($row[$k]) ? $row[$k] : '';
$lbl = $resultLabel($val);
if ($lbl==='NIL') continue; // show only participating/non-NIL
if ($isMerit($lbl)) $hasMerit=true;
$h.='<tr><td>'.htmlspecialchars($label,ENT_QUOTES,'UTF-8').'</td><td>'.htmlspecialchars($lbl,ENT_QUOTES,'UTF-8').'</td></tr>';
}
return $h;
};
foreach($rows as $r){
$clubDisplay = ($r['clubname']!=='') ? $r['clubname'] : $r['club'];
$dobStr = ($ts=strtotime($r['dob'])) ? date('d-M-Y',$ts) : htmlspecialchars($r['dob'],ENT_QUOTES,'UTF-8');
$name = htmlspecialchars($r['sname'],ENT_QUOTES,'UTF-8');
$team = htmlspecialchars($clubDisplay,ENT_QUOTES,'UTF-8');
$ag = htmlspecialchars($r['agegroup'],ENT_QUOTES,'UTF-8');
$gender = htmlspecialchars($genderWord($r['gender']),ENT_QUOTES,'UTF-8');
$certNo = htmlspecialchars($certPrefix.$r['appno'],ENT_QUOTES,'UTF-8');
$photo = trim((string)$r['photourl']);
if ($photo!=='' && strpos($photo,'data:image/')!==0) $photo='data:image/png;base64,'.$photo;
$photoTag = ($photo!=='')
? '<div class="photoFrame"><img class="photo" src="'.htmlspecialchars($photo,ENT_QUOTES,'UTF-8').'" alt=""></div>'
: '<div class="photoFrame"><div class="photo ph">PHOTO</div></div>';
$hasMerit=false;
$quadRows = $mkRows($quadMap,$r,$hasMerit);
$inlineRows = $mkRows($inlineMap,$r,$hasMerit);
$artisticRows = $mkRows($artisticMap,$r,$hasMerit);
$rhRows = $mkRows($rollerHockeyMap,$r,$hasMerit);
$ihRows = $mkRows($inlineHockeyMap,$r,$hasMerit);
$freestyleRows = $mkRows($freestyleMap,$r,$hasMerit);
$otherRows = $mkRows($otherGamesMap,$r,$hasMerit);
$certTitle = $hasMerit ? 'CERTIFICATE OF MERIT' : 'CERTIFICATE OF PARTICIPATION';
$blocks = '';
if ($quadRows!=='') $blocks .= '<div class="blk"><h4>Speed-Quad</h4><table class="ev">'.$quadRows.'</table></div>';
if ($inlineRows!=='') $blocks .= '<div class="blk"><h4>Speed-Inline</h4><table class="ev">'.$inlineRows.'</table></div>';
if ($artisticRows!=='') $blocks .= '<div class="blk"><h4>Artistic</h4><table class="ev">'.$artisticRows.'</table></div>';
if ($rhRows!=='') $blocks .= '<div class="blk"><h4>Roller-Hockey</h4><table class="ev">'.$rhRows.'</table></div>';
if ($ihRows!=='') $blocks .= '<div class="blk"><h4>Inline-Hockey</h4><table class="ev">'.$ihRows.'</table></div>';
if ($freestyleRows!=='') $blocks .= '<div class="blk"><h4>Inline-Freestyle</h4><table class="ev">'.$freestyleRows.'</table></div>';
if ($otherRows!=='') $blocks .= '<div class="blk"><h4>Other-Games</h4><table class="ev">'.$otherRows.'</table></div>';
if ($blocks==='') $blocks = '<div class="blk"><h4>Events</h4><table class="ev"><tr><td>—</td><td>NIL</td></tr></table></div>';
$logo = $districtSlug!=='' ? '<img src="districtlogos/'.$districtSlug.'.png" class="logoCenter" alt="" onerror="this.style.display=\'none\'">' : '';
$titleLine = 'in the '.htmlspecialchars($eventTitle,ENT_QUOTES,'UTF-8');
$heldLine = ($eventVenue!=='')
? 'held at '.htmlspecialchars($eventVenue,ENT_QUOTES,'UTF-8').' on '.htmlspecialchars($eventDate,ENT_QUOTES,'UTF-8')
: 'Held on '.htmlspecialchars($eventDate,ENT_QUOTES,'UTF-8');
$pages[] =
'<div class="certpage"><div class="sheet">'.
'<img class="pagebg" src="'.$bgAttr.'" alt="" aria-hidden="true">'.
'<div class="hdr">'.$logo.'<div class="titleCert">'.$certTitle.'</div><div class="certno">Cert. No.: '.$certNo.'</div></div>'.
'<div class="content"><div class="content-inner">'.
'<div class="idrow">'.$photoTag.'</div>'.
'<div class="name">'.strtoupper($name).'</div>'.
'<div class="line">( born on '.$dobStr.' )</div>'.
'<div class="line">representing '.$team.'</div>'.
'<div class="line">in '.$ag.' '.$gender.' Age Group</div>'.
'<div class="line">'.$titleLine.'</div>'.
'<div class="line">'.$heldLine.'</div>'.
'<div class="line">has participated and attained the following ranking.</div>'.
'<div class="events">'.$blocks.'</div>'.
'</div></div>'.
'<div class="footer"><div class="signs">'.
'<div class="sigbox"><div class="signame">'.htmlspecialchars($president,ENT_QUOTES,'UTF-8').'</div><div class="sigrole">President</div></div>'.
'<div class="sigbox"><div class="signame">'.htmlspecialchars($secretary,ENT_QUOTES,'UTF-8').'</div><div class="sigrole">Secretary</div></div>'.
'</div></div>'.
'</div></div>';
}
if (empty($pages)) return '<p>No eligible records found.</p>';
return $css.implode("\n",$pages);
}
function buildCertificateData(mysqli $con, $appno, $repdistrict = null) {
// Championships (title, dates, district, president, secretary)
$sqlC = "SELECT championshiptitle, dates, district, venue, president, secretary
FROM championships
WHERE district = ?
ORDER BY id DESC LIMIT 1";
$stmtC = mysqli_prepare($con, $sqlC);
$dist = ($repdistrict !== null) ? $repdistrict : '';
mysqli_stmt_bind_param($stmtC, "s", $dist);
mysqli_stmt_execute($stmtC);
$evt = array('championshiptitle'=>'', 'dates'=>'', 'district'=>$dist, 'venue'=>'', 'president'=>'', 'secretary'=>'');
if (function_exists('mysqli_stmt_get_result')) {
$res = mysqli_stmt_get_result($stmtC);
if ($row = mysqli_fetch_assoc($res)) $evt = $row;
if ($res) mysqli_free_result($res);
} else {
mysqli_stmt_bind_result($stmtC, $evt['championshiptitle'], $evt['dates'], $evt['district'], $evt['venue'], $evt['president'], $evt['secretary']);
mysqli_stmt_fetch($stmtC);
}
mysqli_stmt_close($stmtC);
// Skater/application – include ALL event columns
$cols = array(
'appno','sname','dob','agegroup','gender','club','clubname','photourl',
// Speed-Quad
'rink1','rink2','rink3','road1','road2',
// Speed-Inline
'rink4','rink5','rink6','rink7','p2p','elim','relay','mixedrelay','road3','road4','road5','p2prd','elimrd','marathon',
// Artistic
'figure','free','pair','solodance','pairdance','inlinefree','quartet','precisionskating','showgroup',
// Hockey
'quadhockey','mixedrollerhockey','inlinehockey',
// Freestyle
'speedslalom','classicslalom','pairslalom',
// Other Games
'alpine','downhill','rollerderby','rollerfreestyle','skateboarding','scooter'
);
$select = '`'.implode('`,`',$cols).'`';
$sqlA = "SELECT $select FROM applications
WHERE appno = ? AND order_status='Success'".
(($repdistrict!==null && $repdistrict!=='') ? " AND repdistrict=?" : "").
" LIMIT 1";
$stmtA = mysqli_prepare($con, $sqlA);
if ($repdistrict!==null && $repdistrict!=='') {
mysqli_stmt_bind_param($stmtA, "ss", $appno, $repdistrict);
} else {
mysqli_stmt_bind_param($stmtA, "s", $appno);
}
mysqli_stmt_execute($stmtA);
$app = null;
if (function_exists('mysqli_stmt_get_result')) {
$res = mysqli_stmt_get_result($stmtA);
$app = mysqli_fetch_assoc($res);
if ($res) mysqli_free_result($res);
} else {
mysqli_stmt_store_result($stmtA);
$meta = mysqli_stmt_result_metadata($stmtA);
$fields = array(); $row = array(); $bindRes = array();
while ($f = mysqli_fetch_field($meta)) { $fields[] = $f->name; $bindRes[] = &$row[$f->name]; }
call_user_func_array('mysqli_stmt_bind_result', array_merge(array($stmtA), $bindRes));
if (mysqli_stmt_fetch($stmtA)) { $app = array(); foreach ($fields as $f) $app[$f] = $row[$f]; }
}
mysqli_stmt_close($stmtA);
if (!$app) { return null; }
// Helpers
// $gsb = function($v){
// $v = strtoupper(trim((string)$v));
// if ($v==='1') return 'G'; if ($v==='2') return 'S'; if ($v==='3') return 'B';
// if (in_array($v, array('G','S','B','P','A'), true)) return $v; // include P/A
// return 'NL';
// };
$gsb = function($v){
$v = strtoupper(trim((string)$v));
// Keep known raw codes as-is; avoid mapping 2 -> 'S'
if (in_array($v, array('1','2','3','P','A','S','F','G','B'), true)) return $v;
return 'NL';
};
$genderWord = function($g){
$g = strtolower(trim((string)$g));
if (in_array($g, array('f','female','girl','girls','women','woman'), true)) return 'Girls';
if (in_array($g, array('m','male','boy','boys','men','man'), true)) return 'Boys';
return ucfirst($g);
};
$clubDisplay = ($app['clubname']!=='') ? $app['clubname'] : $app['club'];
// Maps (matching HTML function)
$quadMap = array(
'rink1'=>'RINK - I', 'rink2'=>'RINK - II', 'rink3'=>'RINK - III',
'road1'=>'ROAD - I', 'road2'=>'ROAD - II'
);
$inlineMap = array(
'p2p'=>'POINTS (TRACK)',
'elim'=>'ELIMINATION (RINK)',
'rink4'=>'RINK - IV', 'rink5'=>'RINK - V', 'rink6'=>'RINK - VI', 'rink7'=>'RINK - VII (Dual TT)',
'road3'=>'ROAD - III', 'road4'=>'ROAD - IV', 'road5'=>'ROAD - V',
'p2prd'=>'POINT TO POINT (ROAD)', 'elimrd'=>'ELIMINATION (ROAD)',
'relay'=>'RELAY', 'mixedrelay'=>'MIXED RELAY', 'marathon'=>'MARATHON'
);
$artisticMap = array(
'figure'=>'FIGURE','free'=>'FREE','pair'=>'PAIR','solodance'=>'SOLO DANCE','pairdance'=>'PAIR DANCE',
'inlinefree'=>'INLINE FREE','quartet'=>'QUARTET','precisionskating'=>'PRECISION SKATING','showgroup'=>'SHOW GROUP'
);
$rollerHockeyMap = array(
'quadhockey'=>'ROLLER HOCKEY','mixedrollerhockey'=>'MIXED ROLLER HOCKEY'
);
$inlineHockeyMap = array(
'inlinehockey'=>'INLINE HOCKEY'
);
$freestyleMap = array(
'speedslalom'=>'SPEED SLALOM','classicslalom'=>'CLASSIC SLALOM','pairslalom'=>'PAIR SLALOM'
);
$otherGamesMap = array(
'alpine'=>'ALPINE','downhill'=>'DOWNHILL','rollerderby'=>'ROLLER DERBY','rollerfreestyle'=>'ROLLER FREESTYLE',
'skateboarding'=>'SKATEBOARDING','scooter'=>'SCOOTER'
);
// Build arrays (keep even P/A; drop only NL)
$mkArr = function($map) use ($app,$gsb){
$out = array();
foreach ($map as $k=>$label) {
$val = isset($app[$k]) ? $app[$k] : '';
$code = $gsb($val);
if ($code==='NL') continue;
$out[] = array('label'=>$label,'val'=>$code);
}
return $out;
};
return array(
'event' => $evt,
'skater' => array(
'appno'=>$app['appno'],
'name'=>$app['sname'],
'dob'=>$app['dob'],
'agegroup'=>$app['agegroup'],
'gender'=>$genderWord($app['gender']),
'team'=>$clubDisplay,
'photo'=>$app['photourl']
),
'quad' => $mkArr($quadMap),
'inline' => $mkArr($inlineMap),
'artistic' => $mkArr($artisticMap),
'rollerhockey' => $mkArr($rollerHockeyMap),
'inlinehockey' => $mkArr($inlineHockeyMap),
'freestyle' => $mkArr($freestyleMap),
'othergames' => $mkArr($otherGamesMap)
);
}
function renderPointsProbables(array $groups, $eventTitle, $discipline, $repdistrict = '') {
$genderLabel = function($g){
$gl = strtolower(trim((string)$g));
if (in_array($gl, array('f','female','girl','girls','women','woman'), true)) return 'Girls';
if (in_array($gl, array('m','male','boy','boys','men','man'), true)) return 'Boys';
return $g ?: '';
};
$initials = function($name){
$n = trim($name); if ($n==='') return '';
$parts = preg_split('/\s+/', $n);
$first = strtoupper(mb_substr($parts[0],0,1,'UTF-8'));
$last = isset($parts[count($parts)-1]) ? strtoupper(mb_substr($parts[count($parts)-1],0,1,'UTF-8')) : '';
return $first.$last;
};
$photoSrc = function($raw){
$raw = trim((string)$raw);
if ($raw==='') return '';
if (strpos($raw, 'data:image/') === 0) return $raw;
return 'data:image/png;base64,'.$raw;
};
date_default_timezone_set('Asia/Kolkata');
$printedOn = 'Printed On : ' . date('d-m-Y h:i:sa');
$logoSafe = preg_replace('/[^A-Za-z0-9_-]/', '_', (string)$repdistrict);
$logoHtml = $logoSafe!=='' ? "<div class='logo'><img src=\"districtlogos/".htmlspecialchars($logoSafe,ENT_QUOTES,'UTF-8').".png\" style=\"width:75%;height:auto;\" onerror=\"this.style.display='none'\" /></div>" : "";
$subtitle = strtoupper(str_replace('-', ' - ', $discipline)).' - POINTS & PROBABLES';
$css = <<<CSS
<style>
*{box-sizing:border-box}
body{font-family:Arial,sans-serif;font-size:12pt;margin:0.6cm}
table{border-collapse:collapse;width:100%;table-layout:fixed;margin:6px 0 12px}
th,td{border:1px solid #444;vertical-align:middle;overflow:hidden}
th{background:#e6e6e6}
.header{text-align:center;margin-bottom:6px}
.header .logo{display:none} @media print{.header .logo{display:block;margin:0 auto 6px}}
.group{margin:8px 0 12px;break-inside:avoid;page-break-inside:avoid}
.groupTitle{font-weight:bold;margin:4px 0 6px}
.w-race{width:52px;text-align:center}
.w-name{width:28%; padding:6px 8px; white-space:normal; word-break:break-word}
.w-team{width:16%; padding:6px 8px; white-space:normal; word-break:break-word}
.vcol{width:24px; text-align:center; font-size:11pt}
.vcol th, .vcol td { padding:3px 2px !important }
.vhead{writing-mode:vertical-rl; transform:rotate(180deg); white-space:nowrap; line-height:1}
.w-pts{width:28px; text-align:center; font-size:11pt}
.w-prob{width:28px; text-align:center; font-size:11pt}
.w-pts th, .w-prob th, .w-pts td, .w-prob td { padding:3px 2px !important }
.namewrap{display:inline-flex;align-items:center;gap:6px}
.avatar{width:18px;height:18px;border-radius:50%;object-fit:cover;display:inline-block}
.avatar.initials{background:#ddd;color:#555;font-weight:bold;font-size:9px;display:inline-flex;align-items:center;justify-content:center}
tr.top3{background:#fff59d} /* selected slots highlight */
tr.tie{background:#ffe9cc} /* tie rows (overlay-ish) */
tr.top3.tie{background:#ffdca8} /* tie + selected => deeper tone */
.footer{display:flex;flex-direction:column;color:#000;font-size:11pt;margin-top:10px}
.sigrow{display:flex;justify-content:space-between}
.printed{margin-top:4px;font-size:9pt}
</style>
CSS;
$out = $css;
$out .= "<div class='header'>".$logoHtml
. "<center><h3>".htmlspecialchars($eventTitle,ENT_QUOTES,'UTF-8')."</h3></center>"
. "<center><h5>".htmlspecialchars($subtitle,ENT_QUOTES,'UTF-8')."</h5></center></div>";
if (empty($groups)) {
$out .= "<p>No data.</p>";
} else {
foreach ($groups as $G) {
if (empty($G['items'])) continue;
$ag = $G['agegroup']; $gLbl = $genderLabel($G['gender']);
$events = $G['eventCols']; $labels = $G['labels'];
$out .= "<div class='group'>";
$out .= "<div class='groupTitle'>".htmlspecialchars($ag,ENT_QUOTES,'UTF-8')." - ".htmlspecialchars($gLbl,ENT_QUOTES,'UTF-8')."</div>";
$out .= "<table><colgroup><col class='w-race'><col class='w-name'><col class='w-team'>";
foreach ($events as $_) $out .= "<col class='vcol'>";
$out .= "<col class='w-pts'><col class='w-prob'></colgroup>";
// header row (vertical labels for event + points/prob)
$out .= "<thead><tr>"
. "<th class='w-race'>Race No</th>"
. "<th class='w-name'>Skater Name</th>"
. "<th class='w-team'>Team</th>";
foreach ($events as $ev) {
$lab = isset($labels[$ev]) ? $labels[$ev] : strtoupper($ev);
$out .= "<th class='vcol'><div class='vhead'>".htmlspecialchars($lab,ENT_QUOTES,'UTF-8')."</div></th>";
}
$out .= "<th class='w-pts'><div class='vhead'>Points</div></th>"
. "<th class='w-prob'><div class='vhead'>Probable</div></th>"
. "</tr></thead><tbody>";
foreach ($G['items'] as $r) {
$rowCls = array();
if (!empty($r['prob'])) $rowCls[] = 'top3';
if (!empty($r['is_tie'])) $rowCls[] = 'tie';
$cls = empty($rowCls)?'':" class='".implode(' ', $rowCls)."'";
$src = $photoSrc(isset($r['photo']) ? $r['photo'] : '');
$avatar = $src!==''
? '<img class="avatar" src="'.htmlspecialchars($src,ENT_QUOTES,'UTF-8').'" alt="" onerror="this.style.display=\'none\'">'
: '<span class="avatar initials">'.htmlspecialchars($initials($r['name']),ENT_QUOTES,'UTF-8').'</span>';
$out .= "<tr{$cls}>"
. "<td class='w-race'>".htmlspecialchars($r['chno'],ENT_QUOTES,'UTF-8')."</td>"
. "<td class='w-name'><span class='namewrap'>{$avatar}<span>".htmlspecialchars($r['name'],ENT_QUOTES,'UTF-8')."</span></span></td>"
. "<td class='w-team'>".htmlspecialchars($r['team'],ENT_QUOTES,'UTF-8')."</td>";
foreach ($events as $ev) {
$cell = isset($r['per'][$ev]) && $r['per'][$ev] !== '' ? $r['per'][$ev] : ' ';
$out .= "<td class='vcol'>".$cell."</td>";
}
$probTxt = '';
if (!empty($r['prob'])) {
$probTxt = $r['prob'];
if (!empty($r['is_tie'])) $probTxt .= ' – Tie';
}
$out .= "<td class='w-pts'>".(int)$r['pts']."</td>"
. "<td class='w-prob'>".htmlspecialchars($probTxt,ENT_QUOTES,'UTF-8')."</td>"
. "</tr>";
}
$out .= "</tbody></table></div>";
}
}
$out .= "<div class='footer'><div class='sigrow'><span>Sign.</span><span>Chief.</span></div>"
. "<div class='printed'>".htmlspecialchars($printedOn,ENT_QUOTES,'UTF-8')."</div></div>";
return $out;
}
function buildPointsProbables(mysqli $db, $discipline, $repdistrict = null) {
// Column labels
$labels = array(
'rink1'=>'RINK - I (1 LAP / 200M)','rink2'=>'RINK - II (500+D)','rink3'=>'RINK - III (1000M)',
'road1'=>'ROAD - I (1 LAP)','road2'=>'ROAD - II (1500/3000M)',
'rink4'=>'RINK - IV (1 LAP / 200M)','rink5'=>'RINK - V (500+D)','rink6'=>'RINK - VI (1000M)',
'rink7'=>'RINK - VII Dual TT (200M)',
'p2p'=>'POINT TO POINT (TRACK) (5000M)','elim'=>'ELIMINATION (RINK) (10000M)',
'road3'=>'ROAD - III (100M)','road4'=>'ROAD - IV (1 LAP)','road5'=>'ROAD - V (3000M)',
'p2prd'=>'POINT TO POINT (ROAD) (10000M)','elimrd'=>'ELIMINATION (ROAD) (15000M)',
'relay'=>'RELAY (3000M)','mixedrelay'=>'MIXED RELAY (4000M)','marathon'=>'MARATHON'
);
// Display + scoring columns per discipline
if ($discipline === 'Speed-Quad') {
$displayCols = array('rink1','rink2','rink3','road1','road2');
$pointsCols = $displayCols;
} elseif ($discipline === 'Speed-Inline') {
// Track points/elim BEFORE road
$displayCols = array('rink4','rink5','rink6','rink7','p2p','elim','road3','road4','road5','p2prd','elimrd','relay','mixedrelay','marathon');
// No points for relay/mixedrelay/marathon
$pointsCols = array('rink4','rink5','rink6','rink7','p2p','elim','road3','road4','road5','p2prd','elimrd');
} else {
throw new InvalidArgumentException('Unknown discipline: '.$discipline);
}
// Build query
$selectCols = implode('`,`', $displayCols);
$sql = "SELECT appno, chno, sname, club, clubname, agegroup, gender,
IFNULL(agorder,999999) AS agorder, `$selectCols`, photourl
FROM applications
WHERE skatertype = ?
AND COALESCE(chno,'') <> ''
AND order_status='Success'";
$types = 's';
$vals = array($discipline);
if ($repdistrict !== null && $repdistrict !== '') {
$sql .= " AND repdistrict = ?";
$types .= 's';
$vals[] = $repdistrict;
}
$sql .= " ORDER BY IFNULL(agorder,999999), agegroup, gender, CAST(chno AS UNSIGNED), sname";
$stmt = mysqli_prepare($db, $sql);
if (!$stmt) { throw new RuntimeException('Prepare failed: '.mysqli_error($db)); }
$bind = array(&$types); foreach ($vals as $i => $v) { $bind[] = &$vals[$i]; }
call_user_func_array('mysqli_stmt_bind_param', array_merge(array($stmt), $bind));
if (!mysqli_stmt_execute($stmt)) {
throw new RuntimeException('Execute failed: '.mysqli_stmt_error($stmt));
}
// Fetch
$rows = array();
if (function_exists('mysqli_stmt_get_result')) {
$res = mysqli_stmt_get_result($stmt);
if ($res) {
while ($r = mysqli_fetch_assoc($res)) { $rows[] = $r; }
mysqli_free_result($res);
}
} else {
mysqli_stmt_store_result($stmt);
$meta = mysqli_stmt_result_metadata($stmt);
$fields = array(); $row = array(); $bindRes = array();
if ($meta) {
while ($f = mysqli_fetch_field($meta)) {
$fields[] = $f->name;
$bindRes[] = &$row[$f->name];
}
call_user_func_array('mysqli_stmt_bind_result', array_merge(array($stmt), $bindRes));
while (mysqli_stmt_fetch($stmt)) {
$r = array();
foreach ($fields as $f) { $r[$f] = $row[$f]; }
$rows[] = $r;
}
}
}
mysqli_stmt_close($stmt);
// Helpers
$toGSB = function($v) {
$v = strtoupper(trim((string)$v));
if ($v === '1') return 'G';
if ($v === '2') return 'S';
if ($v === '3') return 'B';
if ($v === 'G' || $v === 'S' || $v === 'B') return $v;
return ''; // ignore P/A/-
};
$pointsFor = function($gsb) {
return ($gsb==='G') ? 5 : (($gsb==='S') ? 3 : (($gsb==='B') ? 1 : 0));
};
$probableSlots = function($discipline, $agegroup) {
$ag = strtolower((string)$agegroup);
if ($discipline === 'Speed-Inline' && strpos($ag, 'sub') !== false) return 4; // Sub-Junior Inline
if (strpos($ag, 'cadet') !== false) return 3; // Cadet
return 3; // default
};
// Group by AgeGroup|Gender
$groups = array();
foreach ($rows as $r) {
$key = $r['agegroup'].'|'.$r['gender'];
if (!isset($groups[$key])) {
$groups[$key] = array(
'agegroup' => $r['agegroup'],
'gender' => $r['gender'],
'agorder' => (int)$r['agorder'],
'eventCols'=> $displayCols,
'labels' => $labels,
'items' => array()
);
}
$team = ($r['clubname'] !== '' ? $r['clubname'] : $r['club']);
$perEvent = array(); $tot=0; $g=0; $s=0; $b=0;
foreach ($displayCols as $col) {
$gsb = isset($r[$col]) ? $toGSB($r[$col]) : '';
$perEvent[$col] = $gsb;
if (in_array($col, $pointsCols, true)) {
$pt = $pointsFor($gsb); $tot += $pt;
if ($gsb==='G') $g++; elseif ($gsb==='S') $s++; elseif ($gsb==='B') $b++;
}
}
$groups[$key]['items'][] = array(
'appno' => $r['appno'],
'chno' => $r['chno'],
'name' => $r['sname'],
'team' => $team,
'per' => $perEvent,
'pts' => $tot,
'g' => $g,
's' => $s,
'b' => $b,
'photo' => isset($r['photourl']) ? $r['photourl'] : ''
);
}
// Filter pts>0, sort, and assign selection with SLOT CONSUMPTION + ties
foreach ($groups as &$G) {
// remove zero-point rows
$G['items'] = array_values(array_filter($G['items'], function($it){ return (int)$it['pts'] > 0; }));
if (empty($G['items'])) continue;
// sort by pts desc, then G/S/B counts, then chno asc, then name
usort($G['items'], function($a,$b){
if ($a['pts'] !== $b['pts']) return $b['pts'] - $a['pts'];
if ($a['g'] !== $b['g']) return $b['g'] - $a['g'];
if ($a['s'] !== $b['s']) return $b['s'] - $a['s'];
if ($a['b'] !== $b['b']) return $b['b'] - $a['b'];
$ac=(int)$a['chno']; $bc=(int)$b['chno']; if ($ac!==$bc) return $ac - $bc;
return strcasecmp($a['name'],$b['name']);
});
// Group indices by DISTINCT points (tie blocks)
$byPoints = array(); // pts => [rowIndex,...]
foreach ($G['items'] as $idx => $it) {
$p = (int)$it['pts'];
if (!isset($byPoints[$p])) $byPoints[$p] = array();
$byPoints[$p][] = $idx;
}
// Highest points first
krsort($byPoints, SORT_NUMERIC);
$slots = $probableSlots($discipline, $G['agegroup']); // e.g., 3 or 4
$roman = array(1=>'I',2=>'II',3=>'III',4=>'IV',5=>'V');
$consumed = 0; // how many skaters taken so far
$rank = 0; // I, II, III... by block
foreach ($byPoints as $p => $idxs) {
$rank++;
$blockSize = count($idxs);
$selected = ($consumed < $slots); // if still room, take the whole block (tie at cutoff allowed)
foreach ($idxs as $i) {
$G['items'][$i]['rank'] = $rank;
$G['items'][$i]['is_tie'] = ($blockSize > 1);
$G['items'][$i]['prob'] = ($selected && isset($roman[$rank])) ? $roman[$rank] : '';
}
// ties consume all their spots
$consumed += $blockSize;
}
}
unset($G);
// Drop empty groups and order groups
foreach ($groups as $k=>$G) if (empty($G['items'])) unset($groups[$k]);
uasort($groups, function($A,$B){
if ($A['agorder'] !== $B['agorder']) return $A['agorder'] - $B['agorder'];
if ($A['agegroup'] !== $B['agegroup']) return strcmp($A['agegroup'], $B['agegroup']);
return strcmp($A['gender'], $B['gender']);
});
return array_values($groups);
}
// PHP 5.6+ compatible: no scalar type hints
function consolidateResults($db, $racename, $repdistrict = null) {
// Whitelist event columns you actually store results in
$allowed = array(
'rink1','rink2','rink3','road1','road2','rink4','rink5','rink6','rink7',
'p2p','elim','relay','mixedrelay','road3','road4','road5','p2prd','elimrd',
'marathon','figure','free','pair','solodance','pairdance','inlinefree',
'quartet','precisionskating','showgroup','quadhockey','inlinehockey',
'mixedrollerhockey','speedslalom','pairslalom','classicslalom','alpine',
'downhill','rollerderby','rollerfreestyle','skateboarding','scooter'
);
if (!in_array($racename, $allowed, true)) {
throw new InvalidArgumentException("Invalid event column: ".$racename);
}
// WHERE: medal winners only; chest number NOT required
$where = "COALESCE(`$racename`, '') IN ('1','2','3')
AND order_status='Success'";
$types = '';
$vals = array();
if ($repdistrict !== null && $repdistrict !== '') {
$where .= " AND repdistrict = ?";
$types .= 's';
$vals[] = $repdistrict;
}
// Pull medal winners + photourl
$sql = "
SELECT
appno, chno, sname, club, clubname, agegroup, gender,
IFNULL(agorder, 999999) AS agorder,
`$racename` AS pos_code,
photourl
FROM applications
WHERE $where
ORDER BY
IFNULL(agorder,999999),
agegroup, gender,
CAST(`$racename` AS UNSIGNED),
CAST(NULLIF(chno,'') AS UNSIGNED), chno
";
$stmt = mysqli_prepare($db, $sql);
if (!$stmt) { throw new RuntimeException('Prepare failed: '.mysqli_error($db)); }
if ($types !== '') {
$refs = array(&$types);
foreach ($vals as $i => $v) { $refs[] = &$vals[$i]; }
call_user_func_array('mysqli_stmt_bind_param', array_merge(array($stmt), $refs));
}
if (!mysqli_stmt_execute($stmt)) {
throw new RuntimeException('Execute failed: '.mysqli_stmt_error($stmt));
}
$rows = array();
if (function_exists('mysqli_stmt_get_result')) {
$res = mysqli_stmt_get_result($stmt);
while ($r = mysqli_fetch_assoc($res)) { $rows[] = $r; }
if ($res) mysqli_free_result($res);
} else {
mysqli_stmt_store_result($stmt);
mysqli_stmt_bind_result($stmt, $appno, $chno, $sname, $club, $clubname, $agegroup, $gender, $agorder, $pos_code, $photourl);
while (mysqli_stmt_fetch($stmt)) {
$rows[] = compact('appno','chno','sname','club','clubname','agegroup','gender','agorder','pos_code','photourl');
}
}
mysqli_stmt_close($stmt);
// Group + team points
$groups = array();
foreach ($rows as $r) {
$key = $r['agegroup'].'|'.$r['gender'];
if (!isset($groups[$key])) {
$groups[$key] = array(
'agegroup' => $r['agegroup'],
'gender' => $r['gender'],
'agorder' => (int)$r['agorder'],
'items' => array(),
'scoreboard' => array()
);
}
$pos = (string)$r['pos_code']; // 1/2/3
$team = ($r['clubname'] !== '' ? $r['clubname'] : $r['club']);
$pts = ($pos==='1') ? 5 : (($pos==='2') ? 3 : 1);
$groups[$key]['items'][] = array(
'appno' => $r['appno'],
'chno' => $r['chno'], // may be empty now
'name' => $r['sname'],
'team' => $team,
'pos' => $pos,
'photo' => $r['photourl'],
);
if (!isset($groups[$key]['scoreboard'][$team])) { $groups[$key]['scoreboard'][$team] = 0; }
$groups[$key]['scoreboard'][$team] += $pts;
}
foreach ($groups as &$G) {
usort($G['items'], function($a,$b){
$pa = (int)$a['pos']; $pb = (int)$b['pos'];
if ($pa !== $pb) return $pa - $pb;
// safe compare on chno even if empty/non-numeric
$ca = (int)$a['chno']; $cb = (int)$b['chno'];
if ($ca !== $cb) return $ca - $cb;
return strcasecmp($a['name'], $b['name']);
});
$sb = array();
foreach ($G['scoreboard'] as $team => $p) { $sb[] = array('team'=>$team,'points'=>$p); }
usort($sb, function($a,$b){
if ($a['points'] !== $b['points']) return $b['points'] - $a['points'];
return strcasecmp($a['team'], $b['team']);
});
$G['scoreboard'] = $sb;
} unset($G);
uasort($groups, function($A,$B){
if ($A['agorder'] !== $B['agorder']) return $A['agorder'] - $B['agorder'];
if ($A['agegroup'] !== $B['agegroup']) return strcmp($A['agegroup'], $B['agegroup']);
return strcmp($A['gender'], $B['gender']);
});
return array_values($groups);
}
function renderConsolidatedResults($groups, $eventTitle, $racename, $repdistrict = '') {
// Helpers
$mapGender = function($g) {
$gl = strtolower(trim((string)$g));
if (in_array($gl, array('f','female','girl','girls','women','woman'), true)) return 'Girls';
if (in_array($gl, array('m','male','boy','boys','men','man'), true)) return 'Boys';
return $g ?: '';
};
$rowClass = function($pos) {
if ($pos==='1') return 'res-first';
if ($pos==='2') return 'res-second';
if ($pos==='3') return 'res-third';
return 'res-none';
};
$medalIcon = function($pos) {
if ($pos==='1') return '🥇';
if ($pos==='2') return '🥈';
if ($pos==='3') return '🥉';
return '';
};
$initials = function($name){
$n = trim($name);
if ($n==='') return '';
$parts = preg_split('/\s+/', $n);
$first = strtoupper(mb_substr($parts[0],0,1,'UTF-8'));
$last = isset($parts[count($parts)-1]) ? strtoupper(mb_substr($parts[count($parts)-1],0,1,'UTF-8')) : '';
return $first . $last;
};
$photoSrc = function($raw){
$raw = trim((string)$raw);
if ($raw==='') return '';
if (strpos($raw, 'data:image/') === 0) return $raw; // already a data URL
return 'data:image/png;base64,'. $raw; // assume base64 PNG blob
};
// Build ONE overall team-points table by summing all group scoreboards
$overallMap = array();
foreach ($groups as $G) {
if (empty($G['scoreboard'])) continue;
foreach ($G['scoreboard'] as $row) {
$t = (string)$row['team'];
$p = (int)$row['points'];
if (!isset($overallMap[$t])) $overallMap[$t] = 0;
$overallMap[$t] += $p;
}
}
$overall = array();
foreach ($overallMap as $team=>$pts) $overall[] = array('team'=>$team,'points'=>$pts);
usort($overall, function($a,$b){
if ($a['points'] !== $b['points']) return $b['points'] - $a['points'];
return strcasecmp($a['team'], $b['team']);
});
// Header/footer bits
date_default_timezone_set('Asia/Kolkata');
$printedOn = 'Printed On : ' . date('d-m-Y h:i:sa');
$logoSafe = preg_replace('/[^A-Za-z0-9_-]/', '_', (string)$repdistrict);
$logoHtml = $logoSafe !== ''
? "<div class='logo'><img src=\"districtlogos/".htmlspecialchars($logoSafe, ENT_QUOTES, 'UTF-8').".png\" alt=\"\" style=\"width:75%;height:auto;\" onerror=\"this.style.display='none'\" /></div>"
: "";
// CSS
$css = <<<CSS
<style>
body { font-family: Arial, sans-serif; font-size: 12pt; margin: 0.6cm; }
h3, h4, h5 { margin: 4px 0; }
table { border-collapse: collapse; width: 100%; margin: 6px 0 10px; table-layout: fixed; }
th, td { border: 1px solid #444; padding: 6px 8px; text-align: left; vertical-align: middle; overflow: hidden; }
th, td { white-space: nowrap; }
.cell-name { white-space: normal; word-break: break-word; }
.namewrap { display: inline-flex; align-items: center; gap: 8px; }
.avatar { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; display: inline-block; vertical-align: middle; }
.avatar.initials {
background: #ddd; color: #555; font-weight: bold; font-size: 11px;
display: inline-flex; align-items: center; justify-content: center;
}
.cell-team { text-overflow: ellipsis; }
/* Results table column widths (no Timing) */
.r-col-app{width:14%}.r-col-chno{width:12%}.r-col-name{width:42%}.r-col-team{width:22%}.r-col-pos{width:10%;text-align:center}
.header { text-align: center; margin-bottom: 6px; }
.header .logo { display: none; } /* hide logo on screen */
@media print { .header .logo { display: block; margin: 0 auto 6px; } }
.group { margin: 10px 0 12px; break-inside: avoid; page-break-inside: avoid; }
.group h4 { margin: 2px 0 6px; }
.footer { display: flex; flex-direction: column; color: #000; font-size: 11pt; margin-top: 10px; }
.sigrow { display: flex; justify-content: space-between; }
.printed { margin-top: 4px; font-size: 9pt; }
/* Row colors for positions */
tr.res-first{background:#fff3c4}
tr.res-second{background:#eceff4}
tr.res-third{background:#f6e0d5}
tr.res-none{background:#fff}
tr.res-first td:first-child{border-left:4px solid #ffd700}
tr.res-second td:first-child{border-left:4px solid #c0c0c0}
tr.res-third td:first-child{border-left:4px solid #cd7f32}
.medal{font-size:12pt}
/* Overall scoreboard */
.scoreboard { width: 60%; margin: 12px auto 6px; }
.scoreboard th, .scoreboard td { text-align: left; }
.scoreboard th.rank, .scoreboard td.rank { width: 12%; text-align: center; }
.scoreboard th.points, .scoreboard td.points { width: 20%; text-align: right; }
@media print {
table, .group { break-inside: avoid; page-break-inside: avoid; }
}
</style>
CSS;
$out = $css;
// One header
$out .= "<div class='header'>"
. $logoHtml
. "<center><h3>".htmlspecialchars($eventTitle, ENT_QUOTES, 'UTF-8')."</h3></center>"
. "<center><h5>".htmlspecialchars(strtoupper($racename), ENT_QUOTES, 'UTF-8')." RESULTS</h5></center>"
. "</div>";
// All age-group results
if (empty($groups)) {
$out .= "<p>No medal results found.</p>";
} else {
foreach ($groups as $G) {
$ag = $G['agegroup'];
$gLbl = $mapGender($G['gender']);
$out .= "<div class='group'>\n";
$out .= " <h4>Age Group : ".htmlspecialchars($ag, ENT_QUOTES, 'UTF-8')
. " - ".htmlspecialchars($gLbl, ENT_QUOTES, 'UTF-8')."</h4>\n";
$out .= " <table>\n";
$out .= " <colgroup><col class='r-col-app'><col class='r-col-chno'><col class='r-col-name'><col class='r-col-team'><col class='r-col-pos'></colgroup>\n";
$out .= " <thead><tr><th>Appno</th><th>Race No</th><th>Name</th><th>Team</th><th>Position</th></tr></thead>\n";
$out .= " <tbody>\n";
foreach ($G['items'] as $r) {
$cls = $rowClass($r['pos']);
$icon = $medalIcon($r['pos']);
$src = $photoSrc($r['photo']);
if ($src !== '') {
$avatar = '<img class="avatar" src="'.htmlspecialchars($src, ENT_QUOTES, 'UTF-8').'" alt="Photo of '.htmlspecialchars($r['name'], ENT_QUOTES, 'UTF-8').'" onerror="this.style.display=\'none\'">';
} else {
$avatar = '<span class="avatar initials">'.htmlspecialchars($initials($r['name']), ENT_QUOTES, 'UTF-8').'</span>';
}
$out .= " <tr class='{$cls}'>"
. " <td>".htmlspecialchars($r['appno'], ENT_QUOTES, 'UTF-8')."</td>"
. " <td>".htmlspecialchars($r['chno'], ENT_QUOTES, 'UTF-8')."</td>"
. " <td class='cell-name'><span class='namewrap'>{$avatar}<span class='medal'>{$icon}</span><span>".htmlspecialchars($r['name'], ENT_QUOTES, 'UTF-8')."</span></span></td>"
. " <td class='cell-team' title=\"".htmlspecialchars($r['team'], ENT_QUOTES, 'UTF-8')."\">".htmlspecialchars($r['team'], ENT_QUOTES, 'UTF-8')."</td>"
. " <td class='r-col-pos'>".htmlspecialchars($r['pos'], ENT_QUOTES, 'UTF-8')."</td>"
. " </tr>\n";
}
$out .= " </tbody>\n";
$out .= " </table>\n";
$out .= "</div>\n";
}
}
// Overall Team Points (moved BELOW results)
if (!empty($overall)) {
$out .= "<h4 style='text-align:center;margin-top:8px;'>Team Points (Overall) <small>(5/3/1)</small></h4>";
$out .= "<table class='scoreboard'>"
. "<thead><tr><th class='rank'>Rank</th><th>Team</th><th class='points'>Points</th></tr></thead><tbody>";
$rank = 1;
foreach ($overall as $row) {
$out .= "<tr>"
. "<td class='rank'>".$rank++."</td>"
. "<td>".htmlspecialchars($row['team'], ENT_QUOTES, 'UTF-8')."</td>"
. "<td class='points'>".(int)$row['points']."</td>"
. "</tr>";
}
$out .= "</tbody></table>";
} else {
$out .= "<p style='text-align:center;margin:8px 0;'>No medal results found for team points.</p>";
}
// Footer
$out .= "<div class='footer'>"
. "<div class='sigrow'><span>Sign.</span><span>Chief.</span></div>"
. "<div class='printed'>".htmlspecialchars($printedOn, ENT_QUOTES, 'UTF-8')."</div>"
. "</div>";
return $out;
}
function scoresheet($db, $event, $maxPerHeat, $repdistrict = null) {
// allowed event columns
$allowed = [
'rink1', 'rink2', 'rink3', 'road1', 'road2', 'rink4', 'rink5', 'rink6', 'rink7', 'p2p', 'elim', 'relay', 'mixedrelay', 'road3', 'road4', 'road5', 'p2prd', 'elimrd', 'marathon', 'figure', 'free', 'pair','solodance', 'pairdance', 'inlinefree', 'quartet', 'precisionskating', 'showgroup', 'quadhockey', 'inlinehockey', 'mixedrollerhockey', 'speedslalom', 'pairslalom', 'classicslalom', 'alpine', 'downhill', 'rollerderby', 'rollerfreestyle', 'skateboarding', 'scooter'
];
if (!in_array($event, $allowed, true)) {
throw new InvalidArgumentException("Invalid event column: ".$event);
}
$W = (int)$maxPerHeat;
if ($W <= 0) throw new InvalidArgumentException("maxPerHeat must be > 0");
// events that REQUIRE chest number
$requiresChnoSet = [
'rink1','rink2','rink3','rink4','rink5','rink6','rink7',
'road1','road2','road3','road4','road5',
'p2p','elim','relay','mixedrelay','p2prd','elimrd','marathon'
];
$requiresChno = in_array($event, $requiresChnoSet, true);
// WHERE
$where = "COALESCE($event, '') <> '' AND $event NOT IN ('0','No')";
if ($requiresChno) {
$where .= " AND COALESCE(chno, '') <> ''"; // only for speed/track events
}
$where .= " AND order_status = 'Success'";
$bindTypes = '';
$bindVals = [];
if ($repdistrict !== null && $repdistrict !== '') {
$where .= " AND repdistrict = ?";
$bindTypes .= 's';
$bindVals[] = $repdistrict;
}
// Fetch rows (include event column as result_code)
$sql = "
SELECT
appno, chno, sname, club, clubname, repdistrict,
skaterid, dob, age, agegroup, gender,
IFNULL(agorder, 999999) AS agorder,
`$event` AS result_code
FROM applications
WHERE $where
ORDER BY
IFNULL(agorder, 999999),
agegroup, gender,
CAST(chno AS UNSIGNED), chno
";
$stmt = mysqli_prepare($db, $sql);
if (!$stmt) throw new RuntimeException('Prepare failed: '.mysqli_error($db));
if ($bindTypes !== '') {
$refs = [ &$bindTypes ];
foreach ($bindVals as $i => $v) { $refs[] = &$bindVals[$i]; }
call_user_func_array('mysqli_stmt_bind_param', array_merge([$stmt], $refs));
}
if (!mysqli_stmt_execute($stmt)) {
throw new RuntimeException('Execute failed: '.mysqli_stmt_error($stmt));
}
$base = [];
if (function_exists('mysqli_stmt_get_result')) {
$res = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_assoc($res)) $base[] = $row;
if ($res) mysqli_free_result($res);
} else {
mysqli_stmt_store_result($stmt);
mysqli_stmt_bind_result(
$stmt, $appno, $chno, $sname, $club, $clubname, $repdistrictOut,
$skaterid, $dob, $age, $agegroup, $gender, $agorder, $result_code
);
while (mysqli_stmt_fetch($stmt)) {
$base[] = compact(
'appno','chno','sname','club','clubname','repdistrictOut',
'skaterid','dob','age','agegroup','gender','agorder','result_code'
);
}
}
mysqli_stmt_close($stmt);
// Group and serpentine assign
$out = [];
$currKey = null; $group = [];
$flushGroup = function() use (&$out, &$group, $W) {
$n = count($group); if ($n === 0) return;
$H = (int)ceil($n / $W);
$assigned = [];
for ($i = 0; $i < $n; $i++) {
$col = intdiv($i, $H);
$row = $i % $H;
$heat = ($col % 2 === 0) ? ($row + 1) : ($H - $row);
$lane = $col + 1;
$r = $group[$i];
$assigned[] = [
'agegroup' => $r['agegroup'],
'gender' => $r['gender'],
'heat_no' => $heat,
'lane_no' => $lane,
'appno' => $r['appno'],
'chno' => $r['chno'],
'sname' => $r['sname'],
'club' => $r['club'],
'clubname' => $r['clubname'],
'repdistrict' => isset($r['repdistrictOut']) ? $r['repdistrictOut'] : $r['repdistrict'],
'skaterid' => $r['skaterid'],
'dob' => $r['dob'],
'age' => $r['age'],
'result_code' => isset($r['result_code']) ? $r['result_code'] : '',
];
}
usort($assigned, function($a, $b){
if ($a['heat_no'] === $b['heat_no']) return $a['lane_no'] <=> $b['lane_no'];
return $a['heat_no'] <=> $b['heat_no'];
});
foreach ($assigned as $row) $out[] = $row;
$group = [];
};
foreach ($base as $row) {
$key = $row['agegroup'].'|'.$row['gender'].'|'.$row['agorder'];
if ($currKey !== null && $key !== $currKey) { $flushGroup(); }
$group[] = $row; $currKey = $key;
}
$flushGroup();
return $out;
}
function renderScoresheet( array $rows, mysqli $con, $raceTitle = 'Start List', $racename = '', $repdistrict = '', $eventTitle='' ) {
if (!$rows) return "<p>No entries.</p>";
$eventCol = (string)$racename;
$safeEventCol = htmlspecialchars($eventCol, ENT_QUOTES, 'UTF-8');
// events that REQUIRE chest number (used to decide whether to show the column)
$requiresChnoSet = array_flip([
'rink1','rink2','rink3','rink4','rink5','rink6','rink7',
'road1','road2','road3','road4','road5',
'p2p','elim','relay','mixedrelay','p2prd','elimrd','marathon'
]);
$requiresChno = isset($requiresChnoSet[$eventCol]);
// Gender label
$mapGender = function($g) {
$gl = strtolower(trim((string)$g));
if (in_array($gl, ['f','female','girl','girls','women','woman'], true)) return 'Girls';
if (in_array($gl, ['m','male','boy','boys','men','man'], true)) return 'Boys';
return $g ?: '';
};
// Position text (now includes S & F)
$mapPos = function($code) {
$c = strtoupper(trim((string)$code));
if ($c === '1') return 'First';
if ($c === '2') return 'Second';
if ($c === '3') return 'Third';
if ($c === 'S') return 'Selected';
if ($c === 'F') return 'Forward';
if ($c === 'P') return 'Participated';
if ($c === 'A') return 'Absent';
return 'Not Reported';
};
// Row CSS class
$mapRowClass = function($code) {
$c = strtoupper(trim((string)$code));
if ($c === '1') return 'res-first';
if ($c === '2') return 'res-second';
if ($c === '3') return 'res-third';
if ($c === 'S') return 'res-selected';
if ($c === 'F') return 'res-forward';
if ($c === 'P') return 'res-participated';
if ($c === 'A') return 'res-absent';
return 'res-none';
};
// IST timestamp
date_default_timezone_set('Asia/Kolkata');
$printedOn = 'Printed On : ' . date('d-m-Y h:i:sa');
// Print-only header logo
$logoSafe = preg_replace('/[^A-Za-z0-9_-]/', '_', (string)$repdistrict);
$logoHtml = $logoSafe !== ''
? "<div class='logo'><img src=\"districtlogos/".htmlspecialchars($logoSafe, ENT_QUOTES, 'UTF-8').".png\" alt=\"\" style=\"width:75%;height:auto;\" onerror=\"this.style.display='none'\" /></div>"
: "";
$css = <<<CSS
<style>
body { font-family: Arial, sans-serif; font-size: 12pt; }
h2, h3, h4, h5 { margin: 6px 0; }
table { border-collapse: collapse; width: 100%; margin: 8px 0 14px; table-layout: fixed; }
th, td { border: 1px solid #444; padding: 6px 8px; text-align: left; vertical-align: top; overflow: hidden; }
th, td { white-space: nowrap; }
.cell-name, .cell-remarks { white-space: normal; word-break: break-word; }
.cell-club { text-overflow: ellipsis; }
.cell-chno { font-weight: bold; }
th.th-chno { font-weight: bold; }
/* Column widths when Ch.No. is present */
.col-lane { width: 8%; }
.col-chno { width: 12%; }
.col-name { width: 30%; }
.col-club { width: 22%; }
.col-remarks { width: 12%; }
.col-pos { width: 10%; }
.col-result { width: 16%; } /* screen only */
/* Alternate widths when Ch.No. is hidden */
.no-chno .col-lane { width: 9%; }
.no-chno .col-name { width: 36%; }
.no-chno .col-club { width: 27%; }
.no-chno .col-remarks{ width: 13%; }
.no-chno .col-pos { width: 15%; }
.no-chno .col-result { width: 18%; }
.page { page-break-after: always; min-height: 96vh; display: flex; flex-direction: column; margin-bottom: 16px; }
@media print { .page { page-break-after: always; } }
.header { text-align: center; margin-bottom: 6px; }
.header .logo { display: none; }
@media print { .header .logo { display: block; margin: 0 auto 6px; } }
.content { flex: 1 1 auto; }
.heatTitle { margin: 4px 0; font-size: 11.5pt; }
.footer { display: flex; flex-direction: column; color: #000; font-size: 11pt; margin-top: 12px; }
.sigrow { display: flex; justify-content: space-between; }
.printed { margin-top: 4px; font-size: 9pt; }
.btns { display: flex; gap: 4px; flex-wrap: wrap; }
.res-btn { font-size: 10pt; padding: 2px 6px; cursor: pointer; border: 1px solid #666; background: #f6f6f6; }
.res-btn.gold { background: #ffd700; }
.res-btn.silver { background: #c0c0c0; }
.res-btn.bronze { background: #cd7f32; color: #fff; border-color: #a15b23; }
.res-btn.sel { background: #e3f2fd; } /* Selected */
.res-btn.fwd { background: #ede7f6; } /* Forward */
.res-btn.chosen { box-shadow: inset 0 0 0 2px #000; }
@media print {
/* Hide live controls; keep Position column structure */
.td-pos { color: transparent; }
.col-result, td.col-result, th.col-result, .btns, .res-btn { display: none !important; }
}
/* Row colors */
tr.res-first { background-color: #fff3c4; }
tr.res-second { background-color: #eceff4; }
tr.res-third { background-color: #f6e0d5; }
tr.res-selected { background-color: #e8f3ff; } /* light blue */
tr.res-forward { background-color: #f0eaff; } /* light purple */
tr.res-participated { background-color: #eaf7ea; }
tr.res-absent { background-color: #fdecea; }
tr.res-none { background-color: #ffffff; }
tr.res-first td:first-child { border-left: 4px solid #ffd700; }
tr.res-second td:first-child { border-left: 4px solid #c0c0c0; }
tr.res-third td:first-child { border-left: 4px solid #cd7f32; }
tr.res-selected td:first-child { border-left: 4px solid #1976d2; }
tr.res-forward td:first-child { border-left: 4px solid #7e57c2; }
tr.res-participated td:first-child { border-left: 4px solid #2e7d32; }
tr.res-absent td:first-child { border-left: 4px solid #c62828; }
</style>
CSS;
$out = $css;
$currKey = null;
$currHeat = null;
$openTable = false;
$openPage = false;
foreach ($rows as $r) {
$ag = $r['agegroup'];
$gRaw = $r['gender'];
$gLbl = $mapGender($gRaw);
$heat = (int)$r['heat_no'];
$key = $ag . '|' . $gRaw;
$codeRaw = isset($r['result_code']) ? $r['result_code'] : (isset($r[$eventCol]) ? $r[$eventCol] : '');
$ucCode = strtoupper(trim((string)$codeRaw));
$posText = $mapPos($ucCode);
$rowCls = $mapRowClass($ucCode);
// New page (agegroup, gender)
if ($currKey !== $key) {
if ($openTable) { $out .= "</tbody></table>\n"; $openTable = false; }
if ($openPage) {
$out .= "</div><!-- .content -->\n";
$out .= "<div class='footer'>"
. "<div class='sigrow'><span>Sign.</span><span>Chief.</span></div>"
. "<div class='printed'>".htmlspecialchars($printedOn, ENT_QUOTES, 'UTF-8')."</div>"
. "</div>\n";
$out .= "</div><!-- .page -->\n";
$openPage = false;
}
$currKey = $key;
$currHeat = null;
$pageCls = $requiresChno ? '' : ' no-chno';
$out .= "<div class='page{$pageCls}' data-event=\"{$safeEventCol}\">\n";
$out .= "<div class='header'>"
. $logoHtml
. "<center><h3>".htmlspecialchars($eventTitle, ENT_QUOTES, 'UTF-8')."</h3></center>"
. "<center><h5>".htmlspecialchars($raceTitle, ENT_QUOTES, 'UTF-8')." - RACE CHART</h5></center>"
. "</div>\n";
$out .= "<div class='content'>\n";
$out .= "<h3>".htmlspecialchars($ag, ENT_QUOTES, 'UTF-8')." - ".htmlspecialchars($gLbl, ENT_QUOTES, 'UTF-8')."</h3>\n";
$openPage = true;
}
// Heat table
if ($currHeat !== $heat) {
if ($openTable) { $out .= "</tbody></table>\n"; }
$currHeat = $heat;
// Build header with/without Ch.No.
if ($requiresChno) {
$out .= "<div class='heatTitle'>Heat {$heat}</div>\n";
$out .= "<table>"
. "<colgroup>"
. "<col class='col-lane'><col class='col-chno'><col class='col-name'>"
. "<col class='col-club'><col class='col-remarks'><col class='col-pos'><col class='col-result'>"
. "</colgroup>"
. "<thead><tr>"
. "<th>Lane</th><th class='th-chno'>Ch.No.</th><th>Name</th>"
. "<th>Team</th><th>Timing/Remarks</th><th class='th-pos'>Position</th><th class='col-result'>Result</th>"
. "</tr></thead><tbody>\n";
} else {
$out .= "<div class='heatTitle'>Heat {$heat}</div>\n";
$out .= "<table>"
. "<colgroup>"
. "<col class='col-lane'><col class='col-name'><col class='col-club'>"
. "<col class='col-remarks'><col class='col-pos'><col class='col-result'>"
. "</colgroup>"
. "<thead><tr>"
. "<th>Lane</th><th>Name</th><th>Team</th>"
. "<th>Timing/Remarks</th><th class='th-pos'>Position</th><th class='col-result'>Result</th>"
. "</tr></thead><tbody>\n";
}
$openTable = true;
}
$team = ($r['clubname'] !== '' ? $r['clubname'] : $r['club']);
$appnoAttr = (int)$r['appno'];
// Preselect buttons
$sel1 = ($ucCode === '1') ? ' chosen' : '';
$sel2 = ($ucCode === '2') ? ' chosen' : '';
$sel3 = ($ucCode === '3') ? ' chosen' : '';
$selS = ($ucCode === 'S') ? ' chosen' : '';
$selF = ($ucCode === 'F') ? ' chosen' : '';
$selP = ($ucCode === 'P') ? ' chosen' : '';
$selA = ($ucCode === 'A') ? ' chosen' : '';
$out .= "<tr class=\"{$rowCls}\" data-appno=\"{$appnoAttr}\">"
. "<td>".(int)$r['lane_no']."</td>";
if ($requiresChno) {
$out .= "<td class='cell-chno'>".htmlspecialchars($r['chno'], ENT_QUOTES, 'UTF-8')."</td>";
}
$out .= "<td class='cell-name'>".htmlspecialchars($r['sname'], ENT_QUOTES, 'UTF-8')."</td>"
. "<td class='cell-club' title=\"".htmlspecialchars($team, ENT_QUOTES, 'UTF-8')."\">".htmlspecialchars($team, ENT_QUOTES, 'UTF-8')."</td>"
. "<td class='cell-remarks'></td>"
. "<td class='td-pos'>".htmlspecialchars($posText, ENT_QUOTES, 'UTF-8')."</td>"
. "<td class='col-result'>"
. "<div class='btns'>"
. "<button type='button' class='res-btn gold{$sel1}' data-code='1' data-event='{$safeEventCol}'>Gold</button>"
. "<button type='button' class='res-btn silver{$sel2}' data-code='2' data-event='{$safeEventCol}'>Silver</button>"
. "<button type='button' class='res-btn bronze{$sel3}' data-code='3' data-event='{$safeEventCol}'>Bronze</button>"
. "<button type='button' class='res-btn sel{$selS}' data-code='S' data-event='{$safeEventCol}'>Selected</button>"
. "<button type='button' class='res-btn fwd{$selF}' data-code='F' data-event='{$safeEventCol}'>Forward</button>"
. "<button type='button' class='res-btn{$selP}' data-code='P' data-event='{$safeEventCol}'>Participated</button>"
. "<button type='button' class='res-btn{$selA}' data-code='A' data-event='{$safeEventCol}'>Absent</button>"
. "</div>"
. "</td>"
. "</tr>\n";
}
if ($openTable) { $out .= "</tbody></table>\n"; }
if ($openPage) {
$out .= "</div><!-- .content -->\n";
$out .= "<div class='footer'>"
. "<div class='sigrow'><span>Sign.</span><span>Chief.</span></div>"
. "<div class='printed'>".htmlspecialchars($printedOn, ENT_QUOTES, 'UTF-8')."</div>"
. "</div>\n";
$out .= "</div><!-- .page -->\n";
}
// JS: update Position + row color + selection state
$out .= <<<JS
<script>
(function(){
function labelFor(code){
switch(String(code).toUpperCase()){
case '1': return 'First';
case '2': return 'Second';
case '3': return 'Third';
case 'S': return 'Selected';
case 'F': return 'Forward';
case 'P': return 'Participated';
case 'A': return 'Absent';
default: return 'Not Reported';
}
}
function classFor(code){
switch(String(code).toUpperCase()){
case '1': return 'res-first';
case '2': return 'res-second';
case '3': return 'res-third';
case 'S': return 'res-selected';
case 'F': return 'res-forward';
case 'P': return 'res-participated';
case 'A': return 'res-absent';
default: return 'res-none';
}
}
function clearResClasses(tr){
['res-first','res-second','res-third','res-selected','res-forward','res-participated','res-absent','res-none']
.forEach(function(c){ tr.classList.remove(c); });
}
document.addEventListener('click', function(e){
var t = e.target;
if(!t.classList.contains('res-btn')) return;
var tr = t.closest('tr');
if(!tr) return;
var appno = tr.getAttribute('data-appno');
var code = t.getAttribute('data-code');
var page = t.closest('.page');
var eventCol = (t.getAttribute('data-event') || (page && page.getAttribute('data-event')) || '');
if(!eventCol){ alert('Missing event column.'); return; }
var cell = t.closest('td');
cell.querySelectorAll('button').forEach(function(b){ b.disabled = true; });
var body = 'appno=' + encodeURIComponent(appno) +
'&event=' + encodeURIComponent(eventCol) +
'&code=' + encodeURIComponent(code);
fetch('update_result.php', {
method: 'POST',
headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
body: body,
cache: 'no-store'
}).then(function(r){ return r.json(); })
.then(function(j){
cell.querySelectorAll('button').forEach(function(b){ b.disabled = false; b.classList.remove('chosen'); });
if(j && j.ok){
t.classList.add('chosen');
var posCell = tr.querySelector('.td-pos');
if (posCell) posCell.textContent = labelFor(code);
clearResClasses(tr);
tr.classList.add(classFor(code));
}else{
alert('Update failed' + (j && j.error ? ': ' + j.error : '.'));
}
}).catch(function(){
cell.querySelectorAll('button').forEach(function(b){ b.disabled = false; });
alert('Network error. Please retry.');
});
});
})();
</script>
JS;
return $out;
}
function assignchestno()
{
include('dbconnect.php');
set_time_limit (1200);
/*$databaseQuery = 'UPDATE applications AS t
JOIN
(
SELECT @rownum:=@rownum+1 rownum,appno,club,skatertype,CONVERT(agorder,UNSIGNED INTEGER),gender,CONVERT(appno,UNSIGNED INTEGER)
FROM applications
CROSS JOIN (select @rownum := 0) rn
where status != "delete" AND skatertype LIKE "Speed%%" order by club,skatertype,CONVERT(agorder,UNSIGNED INTEGER),gender desc,CONVERT(appno,UNSIGNED INTEGER)
) AS r ON t.appno = r.appno
SET t.skaterid =r.rownum';*/
$dt=$_SESSION['teamf'];
$dbqs='SELECT @rownum:=@rownum+1 rownum,appno,club,skatertype,CONVERT(agorder,UNSIGNED INTEGER),gender,CONVERT(appno,UNSIGNED INTEGER)
FROM applications
CROSS JOIN (select @rownum := 100) rn
where repdistrict="'.$dt.'" AND status != "Delete" AND status != "Rejected" AND (order_status="Success") AND ((skatertype LIKE "Speed%%") OR (skatertype LIKE "Tenacity")) order by club,skatertype desc,CONVERT(agorder,UNSIGNED INTEGER),gender desc,CONVERT(appno,UNSIGNED INTEGER) ';
$selectresult = mysqli_query($con,$dbqs) or die('Query failed: ' . mysqli_error());
// echo $dbqs;
while($row = mysqli_fetch_array($selectresult))
{
$chno=$row['rownum'];
$appno=$row['appno'];
$updateq ='update applications set chno='.$chno.' where appno='.$appno.' and (chno="" or chno is NULL)';
$updateresult = mysqli_query($con,$updateq) or die('Query failed: ' . mysqli_error());
echo $chno." ".$appno." ".$con -> affected_rows."<br/>";
}
echo mysqli_num_rows($selectresult);
}
function sendform($appno)
{
include('dbconnect.php');
$databaseQuery = 'SELECT appno, sname, email, hashcode FROM applications WHERE appno = "' . mysqli_real_escape_string($con, $appno) . '"';
$result = mysqli_query($con, $databaseQuery) or die('Query failed - Send Form: ' . mysqli_error($con));
if ($result && $row = mysqli_fetch_array($result)) {
$appno = $row["appno"];
$sname = $row["sname"];
$email = $row["email"];
$key = $row["hashcode"];
$content = '<html><body><b>Dear Skater '.$sname.',<br/><br/></b><br/>
Your registration is complete.<br/><br/>
You can download your <b>TAMILNADU DISTRICT CHAMPIONSHIPS – 2025 - Entry Form </b> in the following link.<br/>
<a href="https://tamilnaduskate.com/tndistricts2025/application.php?appno='.$appno.'&k='.$key.'">Click Here to Print / Download Application Form</a>
<br/></b><br/>
Please contact your District / State Unit for further details and approval.
Thanks & Regards<br/><br/>
TNRSA<br/>
tamilnaduskate.com
</body></html>';
$mail = new PHPMailer(true);
try {
// SMTP settings
$mail->isSMTP();
$mail->Host = 'mail.tamilnaduskate.com';
$mail->SMTPAuth = true;
$mail->Username = 'office@tamilnaduskate.com';
$mail->Password = 'priority1@1';
$mail->SMTPSecure = ''; // no encryption
$mail->Port = 25;
// $mail->SMTPDebug = 2; // optional debug
// $mail->Debugoutput = 'html';
// Recipients
$mail->setFrom('office@tamilnaduskate.com', 'TNRSA');
$mail->addAddress($email, $sname);
// $mail->addBCC('jeganonly@gmail.com');
// Content
$mail->isHTML(true);
$mail->Subject = $sname." |Entry Form ".$appno." | TAMILNADU DISTRICT CHAMPIONSHIPS - 2025";
$mail->Body = $content;
$mail->send();
$mailres = "Success";
} catch (Exception $e) {
$mailres = "Mailer Error: " . $mail->ErrorInfo;
}
$qtext = 'UPDATE applications SET emailstatus="' . mysqli_real_escape_string($con, $mailres) . '" WHERE appno = "' . $appno . '"';
mysqli_query($con, $qtext);
}
}
function sendformold($appno)
{
include('dbconnect.php');
$databaseQuery = 'SELECT appno,sname,email,hashcode FROM applications where (appno= "'.$appno.'")';
$result = mysqli_query($con,$databaseQuery) or die('Query failed: ' . mysqli_error());
if($result)
{
$row = mysqli_fetch_array($result);
$appno=$row["appno"];
$sname=$row["sname"];
$email=$row["email"];
$key=$row["hashcode"];
$content='<html><body><b>Dear Skater '.$sname.',<br/><br/></b><br/>
Your registration is complete.<br/><br/>
You can download your <b>TAMILNADU DISTRICT CHAMPIONSHIPS – 2025 - Entry Form </b> in the following link.<br/>
<a href="https://tamilnaduskate.com/tndistricts2025/application.php?appno='.$appno.'&k='.$key.'">Click Here to Print / Download Application Form</a>
<br/></b><br/>
Please contact your District / State Unit for further details and approval.
Thanks & Regards<br/><br/>
TNRSA<br/>
tamilnaduskate.com
</body></html>';
//$to = "jeganonly@gmail.com,krishnamani_k@yahoo.com,vishnuamalraj@yahoo.com";
$to =$email;
//$to =$email.",jeganonly@gmail.com";
//$to ="jeganonly@gmail.com";
$subject = $sname." |Entry Form ".$appno." | TAMILNADU DISTRICT CHAMPIONSHIPS – 2025";
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
$headers .= "From: office@tamilnaduskate.com" . "\r\n" ;
//$headers .= "Bcc: jeganonly@gmail.com"; //disable later
$mailres=mail($to,$subject,$content,$headers);
$qtext='UPDATE applications SET emailstatus="'.$mailres.'" WHERE appno = "'.$appno.'"';
// echo $qtext;
mysqli_query($con,$qtext) or mysqli_error();
}
}
function listskaterbase()
{
include('dbconnect.php');
$dt=$_SESSION['username'];
if($dt=="secretary")
{
$dt=$_SESSION['teamf'];
// $dt="Chennai";
}
//$qtext='SELECT appno, sname, dob, agegroup, gender, club from skaterbase_'.strtolower($_SESSION['username']).' where status != "delete"';
$qtext='SELECT appno, sname, dob, agegroup, gender, clubname as club from tdrsc2021 where status != "delete"';
//where clubname="'.strtolower($_SESSION['username']).'" AND
// echo $qtext;
$result3 = mysqli_query($con,$qtext) or die('Query failed: ' . mysqli_error());
while($row = mysqli_fetch_array($result3))
{
$appno=trim($row["appno"]);
$sname=trim($row["sname"]);
$dob=trim($row["dob"]);
$ag=trim($row["agegroup"])." ".trim($row["gender"]);
$club=trim($row["club"]);
//$photo="http://".$_SERVER[HTTP_HOST]."/oldpics/".trim($row["Photo"]);
$gender=trim($row["gender"]);
echo '<li><a href="#" onclick="loadprof(\''.$appno.'\');">'.$sname." | ".$dob." | ".$club.' </a></li>';
}
}
function listentries($stypesel,$teamfilter=NULL,$del=NULL)
{
include('dbconnect.php');
$delstatus = "";
if ($del=="hidedelete") {
$delstatus='AND status != "delete" ';
}
$stype = $stypesel;
$dt = "";
$club = $_SESSION["username"];
if ($club=="secretary") {
$team = "%";
$dt = $teamfilter;
} else {
if ($club=="") { loginbox(); return; }
$team = $club;
}
$usertype = $_SESSION["usertype"];
if ($usertype=="District") {
$team=$teamfilter;
if($team=="All Entries")
{
$team = "%";
}
$dt = $_SESSION["currentdistrict"];
if($dt=="")
{
$_SESSION["currentdistrict"]=$dt;
$dt=$_SESSION["username"];;
}
} else if ($usertype=="Club") {
$team = $_SESSION["username"];
$dt = $_SESSION["currentdistrict"];
}
if($team=="All Entries")
{
$team = "%";
}
if ($stype!="Other") {
$databaseQuery = 'SELECT * FROM applications WHERE (skatertype like "%'.$stype.'%") and (club like "%'.$con->real_escape_string($team).'%")and (repdistrict like "%'.$con->real_escape_string($dt).'%") '.$delstatus.' AND (order_status="Success") order by agorder+0,gender desc,skatertype,club,CONVERT(appno,UNSIGNED INTEGER)';
} else {
$databaseQuery = 'SELECT * FROM applications WHERE (otherdiscipline <> "") and (club like "%'.$con->real_escape_string($team).'%") and (repdistrict like "%'.$con->real_escape_string($dt).'%")'.$delstatus.' AND (order_status="Success") order by skatertype,agorder+0,gender desc,club,CONVERT(appno,UNSIGNED INTEGER)';
}
$result3 = mysqli_query($con,$databaseQuery) or die('Query failed: ' . mysqli_error());
date_default_timezone_set('Asia/Kolkata');
echo '<p class="font2"> ' .mysqli_num_rows($result3) . ' Results found for "'.$dt."-".$team.'-'.$stype.'" as on '.date("d-m-Y h:i:sa").' </p>';
echo '<title>'.$team.'-'.$stype.'</title>';
if ($_SESSION['usertype']=="Club") {
echo '<a href="print.php?stype='.$stype.'" target="_blank" class="noprint ui-btn ui-btn-raised ui-btn ui-btn-inline waves-effect waves-button waves-effect waves-button" ><i class="zmdi zmdi-print zmd-2x"></i> Print Entry Form</a>';
} else if($_SESSION['username']=="secretary" || $_SESSION['usertype']=="District") {
echo '<a href="print-list.php?stype='.$stype.'" target="_blank" class="noprint ui-btn ui-btn-raised ui-btn ui-btn-inline waves-effect waves-button waves-effect waves-button" ><i class="zmdi zmdi-print zmd-2x"></i> Print List</a>';
}
echo '<table id="listtable" data-role="table" data-mode="columntoggle" style="overflow-x: auto; width:90%;" class="ui-responsive table-stroke">';
echo '<thead>';
if ($stype=="all") {
echo '<tr class="th-groups" >
<th colspan="4" data-priority="1" style="height:auto !important; text-align:center;">Skater Details</th>
<th colspan="2" data-priority="5" style="height:auto !important; text-align:center;" >DOB & Age</th>
<th colspan="2" data-priority="2" style="height:auto !important; text-align:center;">Age Group</th>
<th colspan="1" data-priority="6" style="height:auto !important; text-align:center;">Representing Team</th>
<th colspan="2" data-priority="1" style="height:auto !important; text-align:center;">Tenacity</th>
<th colspan="2" data-priority="1" style="height:auto !important; text-align:center;">Under 5 Quad</th>
<th colspan="2" data-priority="1" style="height:auto !important; text-align:center;">Under 5 Inline</th>
<th colspan="4" data-priority="1" style="height:auto !important; text-align:center;">Quad Events</th>
<th colspan="10" data-priority="1" style="height:auto !important; text-align:center;">Inline Events</th>
<th colspan="1" data-priority="4" style="height:auto !important; text-align:center;">Comments</th>
</tr>';
}
echo '<tr>
<th><div class="verticalText">Sl.No.</div></th>';
if ($stype=="Speed-Quad"|| $stype=="Speed-Inline" || $stype=="Tenacity" || $stype=="Under5-Quad" || $stype=="Under5-Inline") {
echo '<th><div>Race No.</div></th>';
}
echo '<th><div class="verticalText">AppNo</div></th>
<th><div>Status</div></th>
<th><div>RSFI App.no.</div></th>
<th ><div style=" width:120px;">Skater Name</div></th>
<th><div>Date_of_Birth</div></th>
<th><div>Age</div></th>
<th><div>AgeGroup</div></th>
<th><div>Gender</div></th>
<th><div>Representing Team</div></th>';
if ($_SESSION['username']=="secretary" || $_SESSION['usertype']=="District" || $_SESSION['usertype']=="Club") {
echo '<th class="noprint"><div class="noprint">Edit</div></th>';
}
echo '<th class="noprint"><div class="noprint">Delete</div></th>';
if ($stype=="Tenacity" || $stype=="all") {
echo '<th><div class="verticalText">Race 1</div></th>
<th><div class="verticalText">Race 2</div></th>';
}
if ($stype=="Under5-Quad" || $stype=="all") {
echo '<th><div class="verticalText">Under 5- Quad Race 1</div></th>
<th><div class="verticalText">Under 5-Quad Race 2</div></th>';
}
if ($stype=="Under5-Inline" || $stype=="all") {
echo '<th><div class="verticalText">Under 5- Inline Race 1</div></th>
<th><div class="verticalText">Under 5- Inline Race 2</div></th>';
}
if ($stype=="Speed-Quad"|| $stype=="all") {
echo '<th><div class="verticalText">Rink - I<br/>(1 Lap [200M])</div></th>
<th><div class="verticalText">Rink - II<br/>(2 Lap / 500+D)</div></th>
<th><div class="verticalText">Rink - III<br/>(3 Lap / 4 Lap / 1000 M)</div></th>
<th><div class="verticalText">Road - I<br/>(1 Lap)</div></th>
<th><div class="verticalText">Road - II<br/>(1500 / 3000 M)</div></th>';
}
if ($stype=="Speed-Inline"|| $stype=="all") {
echo '<th><div class="verticalText">Rink - IV<br/>(1 Lap [200M])</div></th>
<th><div class="verticalText">Rink - V<br/>(500+D)</div></th>
<th><div class="verticalText">Rink - VI<br/>(1000 M)</div></th>
<th><div class="verticalText">Rink - VII<br/>DUAL TT(200 M)</div></th>
<th><div class="verticalText">Points Track (5000 M)</div></th>
<th><div class="verticalText">Elimination - Rink (10000 M)</div></th>
<th><div class="verticalText">Road - III (100 M)</div></th>
<th><div class="verticalText">Road - IV (1 Lap)</div></th>
<th><div class="verticalText">Road - V (3000 M)</div></th>
<th><div class="verticalText">Point to Point - Road (10000 M)</div></th>
<th><div class="verticalText">Elimination - Road (15000 M)</div></th>
<th><div class="verticalText">Relay (3000M)</div></th>
<th><div class="verticalText">Mixed Relay (4000M)</div></th>';
}
if ($stype=="Artistic") {
echo '<th><div class="verticalText">Figure</div></th>
<th><div class="verticalText">Free</div></th>
<th><div class="verticalText">Pair</div></th>
<th><div class="verticalText">Partner Name</div></th>
<th><div class="verticalText">Solodance</div></th>
<th><div class="verticalText">Coupledance</div></th>
<th><div class="verticalText">Partner Name</div></th>
<th><div class="verticalText">Inlinefree</div></th>
<th><div class="verticalText">Quartet</div></th>
<th><div class="verticalText">ShowGroup</div></th>
<th><div class="verticalText">Precision</div></th>';
}
if ($stype=="Roller-Hockey") {
echo '<th><div class="verticalText">Roller Hockey</div></th>
<th><div class="verticalText">Roller Hockey - Mixed</div></th>
<th><div class="verticalText">Position</div></th>
<th><div class="verticalText">Jersey No.</div></th>';
}
if ($stype=="Roller-Hockey" || $stype=="Inline-Hockey") {
echo '<th><div class="verticalText">Inline Hockey</div></th>
<th><div class="verticalText">Position</div></th>
<th><div class="verticalText">Jersey No.</div></th>';
}
if ($stype=="Inline-Freestyle") {
echo '<th><div class="verticalText">Classic Slalom</div></th>
<th><div class="verticalText">Speed Slalom</div></th>
<th><div class="verticalText">Pair Slalom</div></th>';
}
if ($stype=="Other") {
echo '<th><div class="verticalText">Main Discipline</div></th>
<th><div class="verticalText">Other Discipline</div></th>
<th><div class="verticalText">Alpine</div></th>
<th><div class="verticalText">Downhill</div></th>
<th><div class="verticalText">Roller Derby</div></th>
<th><div class="verticalText">Roller Freestyle</div></th>
<th><div class="verticalText">Skateboarding</div></th>
<th><div class="verticalText">Scooter</div></th>';
}
echo '<th><div class="verticalText">Comments</div></th>';
echo '</tr></thead>';
$twocol=0;
$itcount=0;
$curag=""; $curgender=""; $curteam="";
$rink1cnt=0; $rink2cnt=0; $road1cnt=0; $road2cnt=0; $quadskaterscnt=0;
$rink3cnt=0; $rink4cnt=0; $rink5cnt=0; $rink6cnt=0; $rink7cnt=0;
$road3cnt=0; $road4cnt=0; $road5cnt=0; $p2pcnt=0; $rinkelimcnt=0; $p2prdcnt=0;
$roadelimcnt=0; $relaycnt=0; $mixedrelaycnt=0; $inlineskaterscnt=0;
$rollerhockeycnt=0; $inlinehockeycnt=0;
echo '<tbody>';
$slno=0;
// helper: normalize event result to 1/2/3/P/A/-
$normalize = function($v){
$c = strtoupper(trim((string)$v));
return in_array($c, ['1','2','3','P','A','S','F']) ? $c : '-';
};
while($row = mysqli_fetch_array($result3)) {
$status = trim($row["status"]);
$slno++;
$appno = trim($row["appno"]);
$sname = trim($row["sname"]);
$hashcode= trim($row["hashcode"]);
$discipline = trim($row["skatertype"]);
$otherdiscipline = trim($row["otherdiscipline"]);
if ($otherdiscipline=='on') { $otherdiscipline="Yes"; }
if ($discipline=="Speed-Quad") { $quadskaterscnt++; }
if ($discipline=="Speed-Inline"){ $inlineskaterscnt++; }
$skaterid= trim($row["skaterid"]);
$chno = trim($row["chno"]);
$dob = trim($row["dob"]);
$age = trim($row["age"]);
$ag = trim($row["agegroup"]);
if ($discipline=="Roller-Hockey") {
if ($age<9) { $ag="6 to 9 - Cadet Tiny Tots"; }
if ($age>=9 && $age<12) { $ag="9 to 12 - Cadet"; }
$rollerhockeycnt++;
}
if ($discipline=="Inline-Hockey") {
if ($age<9) { $ag="6 to 9 - Cadet Tiny Tots"; }
if ($age>=9 && $age<12) { $ag="9 to 12 - Cadet"; }
$inlinehockeycnt++;
}
$gender = trim($row["gender"]);
$club = trim($row["club"]);
$clubname = trim($row["clubname"]);
$school = trim($row["school"]);
$residingstate = trim($row["residingstate"]);
$residingdistrict= trim($row["residingdistrict"]);
$repstate = trim($row["repstate"]);
$repdistrict = trim($row["repdistrict"]);
$fathername = trim($row["fathername"]);
$address = trim($row["address"]);
$address2 = trim($row["address2"]);
$city = trim($row["city"]);
$pin = trim($row["pin"]);
$phone = trim($row["phone"]);
$email = trim($row["email"]);
$blood = trim($row["bloodgroup"]);
$comments = trim($row["comments"]);
$payref = trim($row["payref"]);
$paystatus = trim($row["paystatus"]);
$nodob = "";
$doburl= trim($row["doburl"]);
if ($doburl=='NA') { $nodob="true"; }
$pwd = trim($row["aadhaarpass"]);
$position = trim($row["hockeyplayertype"]);
$jerseyno = trim($row["jerseyno"]);
// ---- RESULT-CODE aware mapping + counters (1/2/3/P/A/-)
// helper that also increments counters for 1/2/3/P (not for A/-)
$setAndCount = function($raw, &$cnt) use ($normalize, $status){
$code = $normalize($raw);
if ($status!="Delete" && in_array($code, ['1','2','3','P','S','F'])) { $cnt++; }
return $code;
};
$adjrink1 = $normalize($row["adjrink1"]);
$adjrink2 = $normalize($row["adjrink2"]);
$adjrink3 = $normalize($row["adjrink3"]);
$u8race1q = $normalize($row["u8race1q"]);
$u8race2q = $normalize($row["u8race2q"]);
$u8race1i = $normalize($row["u8race1i"]);
$u8race2i = $normalize($row["u8race2i"]);
$rink1 = $setAndCount($row["rink1"], $rink1cnt);
$rink2 = $setAndCount($row["rink2"], $rink2cnt);
$rink3 = $setAndCount($row["rink3"], $rink3cnt);
$road1 = $setAndCount($row["road1"], $road1cnt);
$rink4 = $setAndCount($row["rink4"], $rink4cnt);
$rink5 = $setAndCount($row["rink5"], $rink5cnt);
$rink6 = $setAndCount($row["rink6"], $rink6cnt);
$rink7 = $normalize($row["rink7"]); // no counter needed here by your previous logic
$road2 = $setAndCount($row["road2"], $road2cnt);
$road3 = $setAndCount($row["road3"], $road3cnt);
$road4 = $setAndCount($row["road4"], $road4cnt);
$road5 = $setAndCount($row["road5"], $road5cnt);
$p2p = $setAndCount($row["p2p"], $p2pcnt);
// use rinkelimcnt (not undefined $elimcnt)
$elim = $setAndCount($row["elim"], $rinkelimcnt);
$p2prd = $setAndCount($row["p2prd"], $p2prdcnt);
$elimrd= $setAndCount($row["elimrd"], $roadelimcnt);
$relay = $setAndCount($row["relay"], $relaycnt);
$mixedrelay = $setAndCount($row["mixedrelay"], $mixedrelaycnt);
$figure = $normalize($row["figure"]);
$free = $normalize($row["free"]);
$combined = $normalize($row["combined"]);
$pair = $normalize($row["pair"]);
$pairpartnername = trim($row["pairpartnername"]);
$pairpartnerag = trim($row["pairpartnerag"]);
$inlinefree = $normalize($row["inlinefree"]);
$solodance = $normalize($row["solodance"]);
$pairdance = $normalize($row["pairdance"]);
$quartet = $normalize($row["quartet"]);
$coupledancepartnername = trim($row["coupledancepartnername"]);
$coupledancepartnerag = trim($row["coupledancepartnerag"]);
$quadhockey = $normalize($row["quadhockey"]);
$mixedhockey = $normalize($row["mixedrollerhockey"]);
$inlinehockey = $normalize($row["inlinehockey"]);
$classicslalom = $normalize($row["classicslalom"]);
$speedslalom = $normalize($row["speedslalom"]);
$pairslalom = $normalize($row["pairslalom"]);
$alpine = $normalize($row["alpine"]);
$downhill = $normalize($row["downhill"]);
$rollerderby = $normalize($row["rollerderby"]);
$rollerfreestyle = $normalize($row["rollerfreestyle"]);
$skateboarding = $normalize($row["skateboarding"]);
$precision = $normalize($row["precisionskating"]);
$showgroup = $normalize($row["showgroup"]);
$scooter = $normalize($row["scooter"]);
// row background by status (unchanged)
$bgc="";
if ($status=="Approved by state") { $bgc="Lime"; }
if ($status=="Rejected") { $bgc="grey"; }
if ($status=="Verified By Dt") { $bgc="LightGreen"; }
if ($status=="Pending") { $bgc="Red"; }
if ($status=="Held") { $bgc="Yellow"; }
if ($status=="Delete") { $bgc="LightGrey"; }
if ($curag!=$ag || $curgender!=$gender) {
if ($rollerhockeycnt>10) {
echo '<tr style="background-color:red; color:white;"><td colspan=8>Error! More than 10 skaters in a '.$curag.' '.$curgender.' Team. </td></tr>';
}
if ($inlinehockeycnt>12) {
echo '<tr style="background-color:red; color:white;"><td colspan=8>Error! More than 12 skaters in a '.$curag.' '.$curgender.' Team. </td></tr>';
}
$rollerhockeycnt=0;
$inlinehockeycnt=0;
echo '<tr style="background-color:#e6ffe6;"><td colspan=8><h5 style="-webkit-margin-after:0.5em !important; -webkit-margin-before:0.67em !important;"><b>'.$ag.' '.$gender.'</b></h5></td></tr>';
$curag=trim($ag);
$curgender=trim($gender);
$curteam=trim($club);
}
echo '<tr style="background-color:'.$bgc.'"><td>'.$slno.'</td>';
if ($stype=="Speed-Quad"|| $stype=="Speed-Inline" || $stype=="Tenacity" || $stype=="Under5-Quad" || $stype=="Under5-Inline") {
echo '<td><b>'.$chno.'</b></td>';
}
echo '<td>'.$appno.'</td>
<td id="status'.$appno.'">'.$status.'</td>
<td>'.$skaterid.'</td>
<td style=" text-align:left;">'.$sname.'<br/>'.$phone.'</td>
<td>'.$dob.'</td>
<td>'.$age.'</td>
<td>'.$ag.'</td>
<td>'.$gender.'</td>
<td style="white-space: nowrap; text-overflow:ellipsis; overflow: hidden; max-width:100px; width:80%;">'.$club.'</td>';
if ($_SESSION['username']=="secretary" || $_SESSION['usertype']=="District" || $_SESSION['usertype']=="Club") {
echo '<td class="noprint"><a href="#" onclick="editapp('.$appno.');" data-rel="popup" data-position-to="window" data-role="button" class="ui-btn ui-btn-inline ui-mini ui-btn-raised">Edit</a></td>';
}
echo '<td class="noprint"><a href="#" onclick="deleteapp('.$appno.');" data-rel="popup" data-position-to="window" data-role="button" class="ui-btn ui-btn-inline ui-mini ui-btn-raised color-red">Delete</a></td>';
if ($stype=="Tenacity" || $stype=="all") {
echo '<td>'.$adjrink1.'</td><td>'.$adjrink2.'</td>';
}
if ($stype=="Under5-Quad" || $stype=="all") {
echo '<td>'.$u8race1q.'</td><td>'.$u8race2q.'</td>';
}
if ($stype=="Under5-Inline" || $stype=="all") {
echo '<td>'.$u8race1i.'</td><td>'.$u8race2i.'</td>';
}
if ($stype=="Speed-Quad" || $stype=="all") {
echo '<td>'.$rink1.'</td><td>'.$rink2.'</td><td>'.$rink3.'</td><td>'.$road1.'</td><td>'.$road2.'</td>';
}
if ($stype=="Speed-Inline" || $stype=="all") {
echo '<td style="border-left:1px solid black !important;">'.$rink4.'</td><td>'.$rink5.'</td><td>'.$rink6.'</td><td>'.$rink7.'</td><td>'.$p2p.'</td><td>'.$elim.'</td><td>'.$road3.'</td><td>'.$road4.'</td><td>'.$road5.'</td><td>'.$p2prd.'</td><td>'.$elimrd.'</td><td>'.$relay.'</td><td>'.$mixedrelay.'</td>';
}
if ($stype=="Artistic") {
echo '<td>'.$figure.'</td><td>'.$free.'</td><td>'.$pair.'</td><td>'.$pairpartnername.'<br/>'.$pairpartnerag.'</td><td>'.$solodance.'</td><td>'.$pairdance.'</td><td>'.$coupledancepartnername.'<br/>'.$coupledancepartnerag.'</td><td>'.$inlinefree.'</td><td>'.$quartet.'</td><td>'.$showgroup.'</td><td>'.$precision.'</td>';
}
if ($stype=="Roller-Hockey") {
echo '<td>'.$quadhockey.'</td><td>'.$mixedrollerhockey.'</td>';
echo '<td>'.$position.'</td><td>'.$jerseyno.'</td>';
}
if ($stype=="Inline-Hockey") {
echo '<td>'.$inlinehockey.'</td>';
echo '<td>'.$position.'</td><td>'.$jerseyno.'</td>';
}
if ($stype=="Inline-Freestyle") {
echo '<td>'.$classicslalom.'</td><td>'.$speedslalom.'</td><td>'.$pairslalom.'</td>';
}
if ($stype=="Other") {
echo '<td>'.$discipline.'</td>';
echo '<td>'.$otherdiscipline.'</td>';
echo '<td>'.$alpine.'</td>';
echo '<td>'.$downhill.'</td>';
echo '<td>'.$rollerderby.'</td>';
echo '<td>'.$rollerfreestyle.'</td>';
echo '<td>'.$skateboarding.'</td>';
echo '<td>'.$scooter.'</td>';
}
echo '<td> '.$comments.' </td></tr>';
}
// reset counters
$rink1cnt=0; $rink2cnt=0; $road1cnt=0; $road2cnt=0; $quadskaterscnt=0;
$rink3cnt=0; $rink4cnt=0; $road3cnt=0; $road4cnt=0; $road5cnt=0; $p2pcnt=0; $rinkelimcnt=0; $p2prdcnt=0;
$roadelimcnt=0; $relaycnt=0; $mixedrelaycnt=0; $inlineskaterscnt=0; $rollerhockeycnt=0; $inlinehockeycnt=0;
echo '</tbody>';
echo "</table>";
}
?>