4
\$\begingroup\$

I wrote a page with Laravel to manage projects with Scrumpoker through blade syntax with controllers, models and Vue.js.

My problem is that I wrote the actual Scrumpoker in a single file.php file and it is loading by using a method through an onclick event of a form.

Now I want to split it up, make some refactoring and implement in my clean written .php Laravel files. I am doing this because it does not fetch every picture of my /storage folder correctly and to create a clean project.

Here is the code (only index.php + images folder with /themes/decksize/13plus1 or /themes/decksize/6plus1 with a.png/b.png/std.png sliced up in single pictures)

<?php error_reporting(0); ?>
<?php

session_start();

if (isset($_GET['name']) && ($_GET['name'] == "UserDebug" ||
    substr($_GET['name'], 0, 4) == "tata")) {
    exit;
}


if (isset($_GET['name']) && $_GET['name'] == '') {
    // user is observer
    unset($_GET['name']);
}

if (isset($_GET['name'])) {
    $_GET['name'] = strip_tags($_GET['name']);
}
define('IDLE_TIMEOUT_SECONDS', 5);
define('IDLE_TIMEOUT_DELETE_SECONDS', 25);
define('PATH_TO_DATA_FILE', './storage/rooms');
define('LOCKFILE', './scrumlock');
define('DEBUG', false);


if (!isset($_GET['decksize'])) {
    $decksize = '13plus1';

} else {
    $decksize = $_GET['decksize'];
    $_SESSION['decksize'] = $decksize;
}

if (!isset($_SESSION['decksize'])) {
    $_SESSION['decksize'] = $decksize;
}


// valid cards - order is the same for the theme png-files
$validOptions = array(
    '13plus1' => array(
        "1" => "[ 0 ]",
        "2" => "[ 1/2 ]",
        "3" => "[ 1 ]",
        "4" => "[ 2 ]",
        "5" => "[ 3 ]",
        "6" => "[ 5 ]",
        "7" => "[ 8 ]",
        "8" => "[ 13 ]",
        "9" => "[ 20 ]",
        "10" => "[ 40 ]",
        "11" => "[ 100 ]",
        "12" => "[ ? ]",
        "13" => "[ C ]",
        // 14 => backside of card
    ),
    '6plus1' => array(
        "1" => "[ 1 ] Piece of cake",
        "2" => "[ 3 ] Hexenwerk",
        "3" => "[ 8 ] Raketenwissenschaft",
        "4" => "[ 100 ] O M G !",
        "5" => "[ ? ] Ich brauche mehr details",
        "6" => "[ C ] Kaffeepause",
        // 7 => backside of card
    ),
);

// will be used to slice the theme.png image into x slices - one per card
define('CARDS_IN_THEME', sizeof($validOptions[$_SESSION['decksize']]) + 1);


function dbg($str)
{
    if (DEBUG) {
        echo $str;
    }
}

// set standard theme if no theme is set
if (!isset($_GET['theme'])) {
    $_GET['theme'] = 'A';
}

// players name matches tablename? == admin
$admin = false;
if (isset($_GET['name']) && isset($_GET['table']) && $_GET['name'] == $_GET['table']) {
    $admin = true;
}

// calculate card width, height and check if theme is available on disk
$offsets = getCardOffset("1", $validOptions[$_SESSION['decksize']], $_GET['theme']);
if (is_array($offsets)) {
    $cardWidth = $offsets[1];
    $placeWidth = 20 + $offsets[1];
    $cardHeight = $offsets[2];
    $placeHeight = 20 + $offsets[2];
} else {
    $cardWidth = 50;
    $placeWidth = 100;
    $cardHeight = 75;
    $placeHeight = 95;
}


// Handle AJAX requests
// new players come here, their cards or ajax-commands to reset the table
if (isset($_GET['table']) && isset($_GET['ajax'])) {
    // tabledata is stored in a file named same as table within /tmp
    // for security - prevent writing to other directories than /tmp by stripping all dots and slashes
    $table = str_replace(array('.', '/'), '', $_GET['table']);

    // create a new game if the player is admin and no game exists
    if (!file_exists(PATH_TO_DATA_FILE . $table) && $admin) {
        touch(PATH_TO_DATA_FILE . $table);
    }

    // stop all players on playing on non existing tables
    // ajax requests to non existing tables stop here
    if (!file_exists(PATH_TO_DATA_FILE . $table)) {
        echo 'Table does not exist.';
        exit;
    }

    // making sure just ONE player fiddles arround with the array on the disk at the same time
    while (!@mkdir(LOCKFILE)) {
        sleep(2);
    }

    // read the tabledata from file
    $filedata = unserialize(file_get_contents(PATH_TO_DATA_FILE . $table));
    if (!is_array($filedata)) {
        $filedata = array();
    }

    // kill the game if requested
    if (isset($_GET['kill']) && $admin) {
        $filedata = array();
        unlink(PATH_TO_DATA_FILE . $table);
        echo "table killed.";
        rmdir(LOCKFILE);
        exit;
    }

    // initiate new game when not done yet
    if (!isset($filedata['table'])) {
        $filedata['table'] = array();
    }
    if (!isset($filedata['history'])) {
        $filedata['history'] = array();
    }
    if (!isset($filedata['message'])) {
        $filedata['message'] = 'Welcome to Scrummy:';
    }

    // split game array in sub parts
    $tabledata = $filedata['table']; // array of the current game (on the red blanket)
    $tabledatahistory = $filedata['history']; // array holding previous game arrays (below the red blanket)
    $players = $filedata['players']; // array holding last seen timestamps for players
    $message = $filedata['message']; // message of the table


    if (isset($_GET['options']) && $_GET['options']) {
        // override message for the table  
        if (strpos($_GET['options'], 'https://it.ly/2NDNWF8') !== false) {
            $_GET['options']
                =
                '<A href="' . $_GET['options'] . '" target="_blank">' . str_replace(
                    'https://it.ly/2NDNWF8',
                    '',
                    $_GET['options']
                ) . '</A>';
        }
        $filedata['message'] = $_GET['options'];
        $message = $filedata['message'];
        file_put_contents(PATH_TO_DATA_FILE . $table, serialize($filedata));
    }

    // check for user manipulation
    $userIsSpoofingArround = false;
    if (isset($_GET['name']) && isset($_GET['ID']) && $tabledata[$_GET['name']]['ID'] != $_GET['ID']) {
        $userIsSpoofingArround = true;
    }

    if (isset($_GET['name']) && isset($tabledata[$_GET['name']]) && $userIsSpoofingArround) {
        if ((time() - $players[$_GET['name']]) < IDLE_TIMEOUT_DELETE_SECONDS) {
            dbg("[" . $tabledata[$_GET['name']]['ID'] . "] == [" . $_GET['ID'] . "]<br>");
            echo 'AUTHENTICATION PROBLEM - FRAUD DETECTED!';
            rmdir(LOCKFILE);
            exit;
        } else {
            // user is spoofing another user who idled out. user can take the session
            if ($_GET['ID']) {
                $tabledata[$_GET['name']]['ID'] = $_GET['ID'];
                dbg("updating ID<br>");
            }
        }
    } else {
        //        echo "[".$tabledata[$_GET['name']]['ID']."] == [".$_GET['ID']."]<br>";
    }


    // put the current game into the history
    if (isset($_GET['add']) && $admin) {
        $tabledatahistory[] = $tabledata;
        $tabledata = array();
        $filedata['table'] = $tabledata;
        $filedata['history'] = $tabledatahistory;
        file_put_contents(PATH_TO_DATA_FILE . $table, serialize($filedata));
        rmdir(LOCKFILE);
        exit;
    }

    // set a card for a player if all _GET data is valid
    if (
        isset($_GET['guess']) && $_GET['guess'] != '' && isset($_GET['name']) && $_GET['name']
        && isset($tabledata[$_GET['name']])
        && $tabledata[$_GET['name']]['ID'] == $_GET['ID']
    ) {
        if (in_array($_GET['guess'], array_keys($validOptions[$_SESSION['decksize']]))) {
            dbg("saving guess and updating time<br>");
            $tabledata[$_GET['name']] = array('name' => $_GET['name'], 'guess' => $_GET['guess'], 'ID' => $_GET['ID']);
            $players[$_GET['name']] = time();
        }
    }

    // recognition of new player without a card - prepare slot
    if (isset($_GET['name']) && !isset($tabledata[$_GET['name']]) && isset($_GET['name']) && $_GET['name']) {
        $tabledata[$_GET['name']] = array('name' => $_GET['name'], 'guess' => '...', 'ID' => $_GET['ID']);
        dbg("adding new player with guess ...<br>");
    }

    // drop ideling players after IDLE_TIMEOUT_SECONDS
    if (isset($_GET['name']) && isset($tabledata[$_GET['name']]) && $_GET['name'] && !$userIsSpoofingArround) {
        $players[$_GET['name']] = time();
        dbg("updating time<br>");
    }

    // combine history and current game into one array
    $filedata['table'] = $tabledata;
    $filedata['history'] = $tabledatahistory;
    $filedata['players'] = $players;
    $filedata['message'] = $message;

    // write table data to disk
    if (isset($_GET['name']) && $_GET['name']) {
        file_put_contents(PATH_TO_DATA_FILE . $table, serialize($filedata));
        dbg("writing data to disk<br>");
    }

    // prepare layout of the webpage
    // show all cards
    $showAllCards = true;

    // echo table header with names
    ksort($players);
    $playernames = array();
    if (is_array($players)) {
        $playernames = array_keys($players);
    }

    $totalPlayers = 0;
    $activePlayers = 0;
    $playersOnTable = 0;
    // check if some players did not choose yet
    if (is_array($playernames)) {
        foreach ($playernames as $eachPlayername) {
            $totalPlayers++;
            if ((time() - $players[$eachPlayername]) < IDLE_TIMEOUT_SECONDS) {
                $activePlayers++;
            }
            if ((time() - $players[$eachPlayername]) < IDLE_TIMEOUT_DELETE_SECONDS) {
                $playersOnTable++;
            }
            if (
                $tabledata[$eachPlayername]['guess'] == '...'
                && (time() - $players[$eachPlayername]) < IDLE_TIMEOUT_SECONDS
            ) {
                $showAllCards = false;
            }
        }
    }

    // automatic new row
    if ($showAllCards && $activePlayers > 1) {
        $tabledatahistory[] = $tabledata;
        //$tabledata = array();  <-- will not work - enables session hijacking
        foreach ($tabledata as $username => $userarray) {
            $tabledata[$username]['guess'] = '...';
        }
        $filedata['table'] = $tabledata;
        $filedata['history'] = $tabledatahistory;
        file_put_contents(PATH_TO_DATA_FILE . $table, serialize($filedata));
    }
    rmdir(LOCKFILE);

    echo '<A href="javascript:clearTimeout(TIMEOUT)">Take A Break(STOP REFRESH)</A><br><br>';
    echo '<h2>' . $message . '</h2>';

    echo '<style>
     .striped-border {
        border: 1px dashed #000;
        width: 50%;
        margin: auto;
        margin-top: 5%;
        margin-bottom: 5%;
    }
    hr {
        height: 1px;
        color: #123455;
        background-color: #123455;
        border: none;
    }
    .center {
        margin: auto;
        width: 60%;
        border: 15px solid #000000;
        padding: 10px;
        text-align: center
      }
      </style>
     <div class=center>Players On Table: ' . $playersOnTable . "<br>";


    echo 'Total Player:' . $totalPlayers . "<br>";
    echo 'Active Players: ' . $activePlayers . "<br>";
    echo '<div class="header">';
    if (is_array($playernames)) {
        foreach ($playernames as $eachPlayerName) {
            $id = '(' . $tabledata[$eachPlayerName]['ID'] . '/' . $_GET['ID'] . ')';
            $id = '';
            if (time() - $players[$eachPlayerName] < IDLE_TIMEOUT_SECONDS) {
                echo '<div class="place" style="text-align:left"' . $placeWidth . 'px;overflow:hidden">' . '<strong>' . 'Player:' . '</strong>' . ' ' . $eachPlayerName . '<br>' ./*'<b>'.hash('sha512',session_id($eachPlayerName)).'</b>'.*/ $id
                    . '</div>';
            } elseif (time() - $players[$eachPlayerName] < IDLE_TIMEOUT_DELETE_SECONDS) {
                echo '<div class="place" style="width:' . $placeWidth . 'px;overflow:hidden">' . $eachPlayerName . $id
                    . '<br><i>INACTIVE</i></div>';
            }
        }
        echo '</div>';


        // CURRENT TABLE
        echo '<div class="currentTable" style="width:' . ($playersOnTable * $placeWidth) . '"><nobr>';
        foreach ($playernames as $eachPlayerName) {
            $styleaddon = '';

            $ownPlace = (isset($_GET['name']) && $tabledata[$eachPlayerName]['name'] == $_GET['name']);
            $playerPlayedACard = ($tabledata[$eachPlayerName]['guess'] != '...');
            if (time() - $players[$eachPlayerName] < IDLE_TIMEOUT_DELETE_SECONDS) {
                echo '<div class="place"><center>';
                $offsets = getCardOffset($tabledata[$eachPlayerName]['guess'], $validOptions[$_SESSION['decksize']], $_GET['theme']);
                if (is_array($offsets)) {
                    // show nifty cards
                    echo '' . (($showAllCards || ($ownPlace && $playerPlayedACard))
                        ?
                        // show card face up
                        '<div style="width:' . $cardWidth . ';height:' . $cardHeight . ';background-image:url(\'/storage/'
                        . $offsets[3] . '\');background-position:' . $offsets[0] . ' 0px;">&nbsp;</div>'
                        : ($playerPlayedACard
                            ?
                            // show card face down
                            '<div style="width:' . $cardWidth . ';height:' . $cardHeight
                            . ';background-image:url(\'' . $offsets[3] . '\');background-position:'
                            . (-(CARDS_IN_THEME - 1) * $cardWidth) . 'px 0px;">&nbsp;</div>'
                            :
                            // show empty place
                            '<div style="' . $styleaddon . 'width:' . $cardWidth . ';height:' . $cardHeight
                            . ';overflow:hidden;">&nbsp;</div>')) . '';

                } else {
                    // theme not found or erroneous - show text cards
                    echo '' . (($showAllCards || ($ownPlace && $playerPlayedACard))
                        ?
                        // show card face up
                        '<div class="card"><span style="height:' . $cardHeight
                        . 'px; width:1px; vertical-align:middle"></span>'
                        . $validOptions[$_SESSION['decksize']][$tabledata[$eachPlayerName]['guess']] . '</div>'
                        : ($playerPlayedACard
                            ?
                            // show card face down
                            '<img src="/storage/images/back.jpg?t=' . filemtime('images/back.jpg') . '>'
                            :
                            // show empty place
                            '<div style="' . $styleaddon . 'width:' . $cardWidth . ';height:' . $cardHeight
                            . ';overflow:hidden;">&nbsp;</div>')) . '';
                    // '<img src="./images/blank2.jpg">'));
                }
                echo '</center></div>';
            }
        }
        echo '</nobr></div>';

        $tabledatahistory = array_reverse($tabledatahistory);
        // HISTORY
        foreach ($tabledatahistory as $eachHistory) {
            echo '<div class="historyTable" style="width:' . ($playersOnTable * $placeWidth) . '">';
            foreach ($playernames as $eachPlayerName) {
                if (time() - $players[$eachPlayerName] < IDLE_TIMEOUT_DELETE_SECONDS) {
                    echo '<div class="place"><p><i>' . $eachPlayerName . '<hr>' . '</i><center>';
                    $offsets = getCardOffset($eachHistory[$eachPlayerName]['guess'], $validOptions[$_SESSION['decksize']], $_GET['theme']);
                    if (is_array($offsets)) {
                        // show nifty cards
                        echo '<div style="width:' . $cardWidth . ';height:' . $offsets[2] . ';background-image:url(\'themes/13plus1/std.png?1435657352'\');background-position:' . $offsets[0] . ' 0px;">&nbsp;</div>';
                    } else {
                        // theme not found or erroneous - show text cards
                        echo '<div class="card"><span style="height:' . $cardHeight
                            . 'px; width:1px; vertical-align:middle"></span>'
                            . $validOptions[$_SESSION['decksize']][$eachHistory[$eachPlayerName]['guess']] . '</div>';
                    }
                    echo '</center></div>';
                }
            }
            echo '</div>';
        }
    }
    // echo '<pre>';

    exit;
}
$ID = session_id();


/**
 * @param $guess
 * @param $validOptions
 * @param $theme
 * @return string
 */
function getCardOffset($guess, $validOptions, $theme)
{
    $return = 0;
    $found = false;
    $imageName = 'storage/themes/' . $_SESSION['decksize'] . '/' . str_replace(array('/', '.'), '', $theme) . '.png';

    if (file_exists($imageName)) {
        $img = imagecreatefrompng($imageName);
        if ($img) {
            $width = imagesx($img);
            $cardWidth = $width / CARDS_IN_THEME;
            foreach ($validOptions as $key => $val) {
                if ($guess != $key) {
                    $return -= $cardWidth;
                } else {
                    $found = true;
                    break;
                }
            }
        } else {
            return false;
        }
    } else {
        return false;
    }
    if (!$found) {
        return false;
    }
    return array($return . "px", $cardWidth, imagesy($img), $imageName . '?' . filemtime($imageName));
}

if (!isset($_GET['table'])) {

    $folder = 'themes/' . $_SESSION['decksize'] . '/';
    $otherfolder = 'themes/6plus1' . $_SESSION['secdecksize'] . '/';



    exit;
} else {


    // handle HTML page for the client
    ?>
    <html>

    <head>
        <title>Scrummy</title>

        <link href="//cdn.muicss.com/mui-0.9.43/css/mui.min.css" rel="stylesheet" type="text/css" />
        <script src="//cdn.muicss.com/mui-0.9.43/js/mui.min.js"></script>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.5/css/bulma.min.css">
        <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>



        <style>
            body {
                background-color: coral ;
            }

            .card {
                width: <?php echo $cardWidth; ?>px;
                height: <?php echo $cardHeight; ?>px;
                overflow: hidden;
                background-image: url('/storage/images/blank.jpg');
                background-size: <?php echo $cardWidth; ?>px auto;
                border: 0px solid red;
            }

            * {
                font-family: Verdana;
                font-size: 8pt;
            }

            .currentTable {
                border: 0px solid black;
                background-image: url('storage/images/rw.png');
                height: <?php echo $placeHeight; ?>px;
            }

            .historyTable {
                border: 0px solid dotted;
                height: <?php echo $placeHeight; ?>px;
            }

            .place {
                border: 0px solid black;
                overflow: hidden;
                float: left;
                text-align: center;
                width: <?php echo $placeWidth; ?>px;
            }

            .currentTable .place {
                margin-top: 10px;
            }

            .historyTable .place {
                margin-top: 10px;
            }

            .header {
                border: 0px solid black;
                height: 25px;
                clear: both;
            }
        </style>
        <script>
            var TIMEOUT;
            var VALUE = "...";

            function statusCommand(cmd, user, table, options) {
                if (options == undefined) {
                    options = '';
                }
                if (window.XMLHttpRequest) {
                    // code for IE7+, Firefox, Chrome, Opera, Safari
                    xmlhttp = new XMLHttpRequest();
                } else {
                    // code for IE6, IE5
                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                }
                xmlhttp.onreadystatechange = function() {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {

                    }
                }
                xmlhttp.open("GET", "?ID=<?php echo session_id(); ?>&ajax&name=" + user + "&table=" + table + "&" + cmd + "&options=" + options, true);
                xmlhttp.send();
            }

            function showUser(str, name, table) {
                if (str == "") {
                    document.getElementById("txtHint").innerHTML = "";
                    return;
                }
                if (str != "..." && str != "AUTO") {
                    VALUE = str;
                    document.getElementById("guess").value = "...";
                }
                if (window.XMLHttpRequest) {
                    // code for IE7+, Firefox, Chrome, Opera, Safari
                    xmlhttp = new XMLHttpRequest();
                } else {
                    // code for IE6, IE5
                    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                }
                xmlhttp.onreadystatechange = function() {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        document.getElementById("txtHint").innerHTML = xmlhttp.responseText;
                    }
                }
                if (str == "AUTO") {
                    xmlhttp.open("GET", "?theme=<?php echo $_GET['theme']; ?>&ID=<?php echo session_id(); ?>&ajax&table=" + table + "&name=" + name, true);
                } else {
                    xmlhttp.open("GET", "?theme=<?php echo $_GET['theme']; ?>&ID=<?php echo session_id(); ?>&ajax&table=" + table + "&guess=" + str + "&name=" + name, true);
                }
                xmlhttp.send();
                if (document.getElementById("txtHint").innerHTML != "Table does not exist.") {} else {
                    VALUE = "...";
                }
                timeout_init();
            }

            function timeout_init() {
                clearTimeout(TIMEOUT);
                TIMEOUT = setTimeout('showUser("AUTO","<?php echo $_GET['name']; ?>","<?php echo $_GET['table']; ?>")', 2000);
            }

            function initCards() {
                showUser("AUTO", "<?php echo $_GET['name']; ?>", "<?php echo $_GET['table']; ?>");
                timeout_init();
            }
        </script>
    </head>

    <body onLoad="initCards()">
        <?php
            for ($i = 8; $i > 0; $i--) {
                //echo '<img src="cards/E'.$i.'.png" width="50">';
            }
            //echo '<br>';
            ?>



        <form method="GET" onsubmit="javascript:return false;" class="mui-form">
            <?php
                if (isset($_GET['name'])) {
                    ?>
                <div class="mui-select">
                    <select id="guess" name="guess" onchange="showUser(this.value,'<?php echo $_GET['name']; ?>','<?php echo $_GET['table']; ?>')">
                        <option value="...">Select Your Card:</option>
                        <?php
                                foreach ($validOptions[$_SESSION['decksize']] as $key => $val) {
                                    echo "<option value=\"" . $key . "\">" . $val . "</option>\n";
                                }
                                ?>
                    </select></div>


                <?php
                        foreach ($validOptions[$_SESSION['decksize']] as $key => $val) {
                            $offsets = getCardOffset($key, $validOptions[$_SESSION['decksize']], $_GET['theme']);
                            echo '<div class="place"><center><A href="javascript:showUser(\'' . $key . '\',\'' . $_GET['name']
                                . '\',\'' . $_GET['table'] . '\')">';
                            if (is_array($offsets)) {
                                // show nifty cards
                                echo '' .
                                    '<div style="width:' . $cardWidth . ';height:' . $cardHeight . ';background-image:url(\''.
                                     $offsets[3] . '\');background-position:' . $offsets[0] . ' 0px;">&nbsp;</div>';
                            } else {
                                // theme not found or erroneous - show text cards
                                echo '' .
                                    // show card face up
                                    '<div class="card"><span style="height:' . $cardHeight
                                    . 'px; width:1px; vertical-align:middle"></span>'
                                    . $validOptions[$_SESSION['decksize']][$tabledata[$eachPlayerName]['guess']] . '</div>';
                            }
                            echo '</A></center></div>';
                        }
                        echo '<br style="clear:both">';
                        //    echo '<A href="javascript:clearTimeout(TIMEOUT)">STOP REFRESH</A>';
                        ?>
            <?php
                } else {
                    ?>
                <input name="message" size="100" onkeypress="statusCommand('message', '<?php echo $_GET['name']; ?>', '<?php echo $_GET['table']; ?>', this.value)" onkeyup="statusCommand('message', '<?php echo $_GET['name']; ?>', '<?php echo $_GET['table']; ?>', this.value)" onchange="statusCommand('message', '<?php echo $_GET['name']; ?>', '<?php echo $_GET['table']; ?>', this.value)" onblur="statusCommand('message', '<?php echo $_GET['name']; ?>', '<?php echo $_GET['table']; ?>', this.value)">
            <?php
                }
                ?>
        </form>
        <br>
        <?php

            if ($admin) {
                echo '<mark>' . 'You`re the Scrumleader' . '</mark>' . '<br>';
                ?>
            <A href="javaScript:statusCommand('kill','<?php echo $_GET['name']; ?>','<?php echo $_GET['table']; ?>')">Reset</A> the current game
            <br>
            <A href="javaScript:statusCommand('add','<?php echo $_GET['name']; ?>','<?php echo $_GET['table']; ?>')">New</A> Round? (Adds new game row)
            <br>
        <?php
            }
            ?>

        <div id="txtHint"><b>Cards are shown here</b></div>

    </body>

    </html>
<?php
}
?>
\$\endgroup\$
1
  • \$\begingroup\$ I changed the title so that it describes what the code does per site goals: "State what your code does in your title, not your main concerns about it.". Feel free to edit and give it a different title if there is something more appropriate. \$\endgroup\$ Commented Jan 8, 2022 at 18:52

1 Answer 1

1
\$\begingroup\$

This doesn't look like typical code from a Laravel project, though it sounds like that is what you are working towards. The HTML can be put into a blade template, and most of the logic can go into a controller (or multiple controllers if necessary). For handling the $_GET['ajax'] requests - those should have a separate route - either in routes/web.php or routes/ajax.php.

The function getCardOffset() appears to return an array or a boolean when the file doesn't exist, the image can't be created from the png file or the width isn't found. The docblock claims it returns a string.

* @return string

It should be updated accordingly.

* @return array | boolean

The variable name $return could have a better name - like $offset or something that is significant to the background position.


In the JavaScript code the variable TIMEOUT is declared in all capitals. In idiomatic JavaScript, as is the case in many other c-based languages - that is a convention for constants, which are never re-assigned. The const keyword can be used to declare a variable that is never re-assigned, though bear in mind that does not mean it is immutable.


The JS function statusCommand appears to check for XMLHttpRequest support- if the browser doesn't support it then it uses ActiveXObject for IE - is there a requirement to support IE? It is quite rare for that.

Also the callback for that request appears to be incomplete:

xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {

    }
}
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.