mysql – Style a long PHP leaderboard table with Bootstrap

I have this PHP leaderboard table that outputs players best times and additional data for World of Warcraft game. This PHP was developed by someone else. I need to style the table in Bootstrap and make it responsive. I managed to do it with another table but this one is very different and can’t figure out a way to make it work.

<!DOCTYPE html>
<html>
<head>
<title>Mythic Dungeon Leaderboards</title>
<style>
img {
    width: 26px;
    height: 26px;
}
table {
    border-collapse: collapse;
    width: 100%;
    color: #f8bc51;
    font-family: 'Roboto', 'Arial', sans-serif;
    font-size: 15px;
    text-align: left;
}
table {
    border-collapse: collapse;
    border-spacing: 0.1rem;
    max-width: 60em;
    margin: 0 auto;
}
td, th {
    border: 1px solid #2f343d;
    padding: 0.3rem;
    text-align: left;
    vertical-align: left;
    width: 1rem;
    height: 1.5rem;
}
tbody tr:hover {
    background: #1b222e;
}
h2 {
    font-family: 'Roboto', 'Arial', sans-serif;
    color: #ffffff;
}
a {
    text-decoration: none;
    font-family: 'Roboto', 'Arial', sans-serif;
    font-size: 14px;
    text-align: left;
    color: #ffffff;
    padding-right: 8px;
}
</style>

<script>var whTooltips = {colorLinks: true, iconizeLinks: true, renameLinks: true, iconSize: 'small'};</script>
<script src="https://wow.zamimg.com/widgets/power.js"></script>

</head>
<body>
<?php
$conn = mysqli_connect("redacted", "redacted", "redacted", "redacted");
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}

function getDungeonName($mapId)
{
    switch ($mapId)
    {
case 189:
return "<br /><a href="#" data-wowhead="achievement=637">Scarlet Monastery</a>";//"Scarlet Monastery";
case 556:
return "<br /><a href="#" data-wowhead="achievement=653">Sethekk Halls</a>";//"Sethekk Halls";
case 543:
return "<br /><a href="#" data-wowhead="achievement=647">Hellfire Ramparts</a>";//"Hellfire Ramparts";
case 34:
return "<br /><a href="#" data-wowhead="achievement=633">Stormwind Stockade</a>";//"Stormwind Stockade";
case 547:
return "<br /><a href="#" data-wowhead="achievement=649">The Slave Pens</a>";//"The Slave Pens";
case 47:
return "<br /><a href="#" data-wowhead="achievement=635">Razorfen Kraul</a>";//"Razorfen Kraul";
case 553:
return "<br /><a href="#" data-wowhead="achievement=659">The Botanica</a>";//"The Botanica";


case 601:
return "<br /><a href="#" data-wowhead="achievement=480">Azjol-Nerub</a>";//"Azjol-Nerub";
case 558:
return "<br /><a href="#" data-wowhead="achievement=666">Auchenai Crypts</a>";//"Auchenai Crypts";
case 619:
return "<br /><a href="#" data-wowhead="achievement=492">Ahn’kahet: The Old Kingdom</a>";//"Ahn’kahet: The Old Kingdom";
case 542:
return "<br /><a href="#" data-wowhead="achievement=648">Blood Furnace</a>";//"Blood Furnace";
case 36:
return "<br /><a href="#" data-wowhead="achievement=628">Deadmines</a>";//"Deadmines";
case 600:
return "<br /><a href="#" data-wowhead="achievement=482">Drak'Tharon Keep</a>";//"Drak'Tharon Keep";
case 632:
return "<br /><a href="#" data-wowhead="achievement=4516">Forge of Souls</a>";//"Forge of Souls";
case 604:
return "<br /><a href="#" data-wowhead="achievement=484">Gundrak</a>";//"Gundrak";
case 602:
return "<br /><a href="#" data-wowhead="achievement=486">Halls of Lightning</a>";//"Halls of Lightning";
case 599:
return "<br /><a href="#" data-wowhead="achievement=485">Halls of Stone</a>";//"Halls of Stone";
case 668:
return "<br /><a href="#" data-wowhead="achievement=4518">Halls of Reflection</a>";//"Halls of Reflection";
case 585:
return "<br /><a href="#" data-wowhead="achievement=661">Magisters' Terrace</a>";//"Magisters' Terrace";
case 576:
return "<br /><a href="#" data-wowhead="achievement=478">The Nexus</a>";//"The Nexus";
case 658:
return "<br /><a href="#" data-wowhead="achievement=4517">Pit of Saron</a>";//"Pit of Saron";
case 33:
return "<br /><a href="#" data-wowhead="achievement=631">Shadowfang Keep</a>";//"Shadowfang Keep";
case 595:
return "<br /><a href="#" data-wowhead="achievement=479">The Culling of Stratholme</a>";//"The Culling of Stratholme";
case 650:
return "<br /><a href="#" data-wowhead="achievement=4296">Trial of The Champion</a>";//"Trial of The Champion";
case 554:
return "<br /><a href="#" data-wowhead="achievement=658">The Mechanar</a>";//"The Mechanar";
case 578:
return "<br /><a href="#" data-wowhead="achievement=487">The Oculus</a>";//"The Oculus";
case 545:
return "<br /><a href="#" data-wowhead="achievement=656">The Steamvault</a>";//"The Steamvault";
case 574:
return "<br /><a href="#" data-wowhead="achievement=477">Utgarde Keep</a>";//"Utgard Keep";
case 608:
return "<br /><a href="#" data-wowhead="achievement=483">Violet Hold</a>";//"Violet Hold";
case 575:
return "<br /><a href="#" data-wowhead="achievement=488">Utgarde Pinnacle</a>";//"Utgard Pinnacle";
case 43:
return "<br /><a href="#" data-wowhead="achievement=630">Wailing Caverns</a>";//"Wailing Caverns";

        default:
            return "Unknown";
    }
    return "Unknown";
}

function getAffixIcon($mask)
{
    $string = "";
    
    if ($mask & 1)
        $string .= "<img src="leaderboards_img/bursting.png" style="width:26px;height:26px;padding-right:8px;" title="Bursting">";
    if ($mask & 2)
        $string .= "<img src="leaderboards_img/explosive.png" style="width:26px;height:26px;padding-right:8px;" title="Explosive">";
    if ($mask & 4)
        $string .= "<img src="leaderboards_img/fieryorb.png" style="width:26px;height:26px;padding-right:8px;" title="Fiery Orbs">";
    if ($mask & 8)
        $string .= "<img src="leaderboards_img/replication.png" style="width:26px;height:26px;padding-right:8px;" title="Replication">";
    if ($mask & 16)
        $string .= "<img src="leaderboards_img/necrotic.png" style="width:26px;height:26px;padding-right:8px;" title="Necrotic Overflow">";
    if ($mask & 32)
        $string .= "<img src="leaderboards_img/resistant.png" style="width:26px;height:26px;padding-right:8px;" title="Resisting">";
    if ($mask & 64)
        $string .= "<img src="leaderboards_img/frenzy.png" style="width:26px;height:26px;padding-right:8px;" title="Frenzy">";
    if ($mask & 128)
        $string .= "<img src="leaderboards_img/blessing.png" style="width:26px;height:26px;padding-right:8px;" title="Blessing">";
    if ($mask & 256)
        $string .= "<img src="leaderboards_img/eonar.png" style="width:26px;height:26px;padding-right:8px;" title="Eonars Trial">";
    if ($mask & 512)
        $string .= "<img src="leaderboards_img/beacon.png" style="width:26px;height:26px;padding-right:8px;" title="Beacon of Hope">";
    if ($mask & 1024)
        $string .= "<img src="leaderboards_img/demonicstoicism.png" style="width:26px;height:26px;padding-right:8px;" title="Demonic Stoicism">";
    if ($mask & 2048)
        $string .= "<img src="leaderboards_img/frozen_orb.jpg" style="width:26px;height:26px;padding-right:8px;" title="Frozen Orb">";
    if ($mask & 4096)
        $string .= "<img src="leaderboards_img/bomb.jpg" style="width:26px;height:26px;padding-right:8px;" title="Overload">";
    if ($mask & 8192)
        $string .= "<img src="leaderboards_img/lightning.jpg" style="width:26px;height:26px;padding-right:8px;" title="Lightning">";
    if ($mask & 16384)
        $string .= "<img src="leaderboards_img/frosttomb.jpg" style="width:26px;height:26px;padding-right:8px;" title="Frost Tomb">";
    if ($mask & 32768)
        $string .= "<img src="leaderboards_img/volatile.jpg" style="width:26px;height:26px;padding-right:8px;" title="Volatile Infection">";
    if ($mask & 65536)
        $string .= "<img src="leaderboards_img/angelofdeath.jpg" style="width:26px;height:26px;padding-right:8px;" title="Angel of Death">";
    if ($mask & 131072)
        $string .= "<img src="leaderboards_img/poison_orb.jpg" style="width:26px;height:26px;padding-right:8px;" title="Poison Orb">";

    return $string;
}

function getTimeString($time)
{
    $secs = $time / 1000;

    $string = "";
    
    $hours = intval($secs / 3660);
    if ($hours != 1)
        $string .= $hours . ":";

    $minutes = intval((($secs % 3600) / 60));
    if ($minutes != 0)
        $string .= sprintf("%02d", $minutes) . ":";
    else
        $string .= "00:";

    $seconds = $secs % 60;
    if ($seconds != 0)
        $string .= sprintf("%02d", $seconds);
    else
        $string .= "00";
    
    if ($minutes != 0)
        $string .= " Minute(s)";
    else
        $string .= " Second(s)";
    
    return $string;
}

function getClassIcon($class)
{
    return "/leaderboards_img/".$class.".png";
}
?>
<?php
for ($dungeon = 0; $dungeon < 700; $dungeon++)
{
    if (getDungeonName($dungeon) != "Unknown")
    {
        $sql = "SELECT guids, level, time, affixesMask FROM mythic_finish_groups WHERE map = ".$dungeon." ORDER BY level desc, time asc LIMIT 3";
        $result = $conn->query($sql);
        if ($result->num_rows > 0) 
        {
            echo getDungeonName($dungeon) . "<br>
            <table>
            <tr>
                <th>Players</th>
                <th>Affixes</th>
                <th>Level</th>
                <th>Time</th>
            </tr>";
            // output data of each row
            while($row = $result->fetch_assoc()) 
            {
                echo "<tr><td>";
                $guids = explode("|", $row["guids"]);
                $counter = 0;
                foreach($guids as $guid)
                {
                    if ($guid == "")
                        continue;
                    $sqlSelectName = "SELECT guid, name, class FROM characters WHERE guid = " . $guid;
                    $resultName = $conn->query($sqlSelectName);
                    $rowName = $resultName->fetch_assoc();
                    
                    if ($resultName->num_rows > 0)
                        echo "<a href="/armory/player/".$rowName["guid"]."" base target="_blank"><img src="".getClassIcon($rowName["class"])."" title="".$rowName["name"].""></img></a>";                   
                    $counter++;
                }
                
                echo "</td><td>".getAffixIcon($row["affixesMask"])."</td><td>" . $row["level"] . "</td><td>" . getTimeString($row["time"]). "</td></td></tr>";
            }
        }
        echo "</table>";
    }
}

$conn->close();
?>
</body>
</html>

You can see the table here: https://dev.northrend.gg/en/page/mythicplusleaderboards

Here is the table I have done and would like to match: https://dev.northrend.gg/en/pvp

They are both going to be used in an iFrame using: https://github.com/davidjbradshaw/iframe-resizer which I have done for the PVP table on the new website (localhost atm)

Because the length of the table I would like to have two columns which would then break down into single column as responsive. Same as I have done for the PVP table.

Appreciate any help or guidance, spent two days trying to get this working so far.

Leave a Comment