简体   繁体   中英

Capturing/INSERT specific value from an input element added to a foreach loop that uses a SQL query array

So, I have been working on this one issue for about a week. I've found a lot of similar questions with solutions like this one or this one , but I haven't had much luck with them.

My issue is, I am trying to capture a specific value from any one of the input elements associated with returned results from a foreach loop. Like a search engine, a query is submitted, results are returned, and each result has a "Rating" slider added to it which a user should be able to rate and submit, on any of the results, a unique rating for that result.

My "rating" range input object:

<form action='#' method='POST'>
<input class='rating' type='range' name='rating_s' min='0' max='100' step='1' value='50' /></i>
<input class="rateglowbutton" type=submit value=Rate />
</form>

That sits within a foreach loop (I know, lots of echoes for formatting, it is what it is):

// array
$audios = $wpdb->get_results($wpdb->prepare("
SELECT a.aud_id
     , a.date
     , a.teacher
     , a.title
     , a.teach_desc
     , a.venue
     , a.genre
     , a.url
     , GROUP_CONCAT(t.tag_name SEPARATOR ', ') tag_name
  FROM audio_tag_xref atx
 RIGHT 
  JOIN audios a 
    ON atx.aud_id = a.aud_id
  LEFT 
  JOIN audio_tags t 
    ON atx.tag_id = t.tag_id
WHERE (a.title LIKE '%$strKey%' 
     OR a.venue LIKE '%$strKey%' 
     OR a.teach_desc LIKE '%$strKey%' 
     OR a.genre LIKE '%$strKey%')
 GROUP 
    BY a.aud_id
 ORDER 
    BY a.aud_id DESC
     ",$strKey));

<?php echo "<table>"; ?>
<?php foreach($audios as $i => $audio){ ?>
<?php echo "<tr>";
echo "<tr><h3>".$audio->title."</h3></tr>";
echo "<tr>".$audio->url."</tr>";
echo "</br>";
echo "<tr>".$audio->aud_id."</tr>";
echo "</br>";
echo "<tr><b>".$audio->teacher."</b></tr>";
echo "</br>";
echo "<tr><i>".$audio->date."</i></tr>";
echo " &nbsp| &nbsp";
echo "<tr><i>".$audio->venue."</i></tr>";
echo "</br>";
echo "<tr>".$audio->genre."</tr>";
echo "</br>";
echo "<tr>".$audio->teach_desc."</tr>";
echo "</tr>";
echo "</br>";
echo "</br>"; ?>

<form action='#' method='POST'>
<input class='rating' type='range' name='rating_s[]' min='0' max='100' step='1' value='50' /> &nbsp<i class="fa fa-plus" aria-hidden="true"></i></div>
<input class="rateglowbutton" type=submit value=Rate />
</form>

<?php } ?>
<?php echo "</table>"; ?>

The submitted rating of which is then inserted into a rating table in my database:

<?php
if (isset($_POST['rating_s'])) {
$userid = md5($_SERVER['REMOTE_ADDR']);
$rate = $_POST['rating_s'];
$aud_id = "$audio->aud_id";
$sql = $wpdb->query($wpdb->prepare("INSERT INTO ratings (rate, aud_id, user_id) VALUES ('$rate', '$aud_id', '$userid')",$rate,$aud_id,$userid));
if ($sql) {
    echo "</br>";
    echo "<div class='rate_msg_cont'><div class='rate_msg'>You gave a rating of $rate for teaching ID: $aud_id.</div></div>";
        }
    }
?>

But, I can't get both the rate, and the aud_id to correctly be inserted into the rating table. At best, I was able to get the rating, but not the aud_id it "belongs" to on the page (the input object that is rendered for its respective returned $audio result). I've tried to following:

  • The POST/insert php code above left inside (at end) of the foreach. This results in all returned results from the string search ($strKey) that are returned by the foreach being given the rating that was submitted for any of the input element (so, index [0],[1],[2],[3],[n]...get the same rating). Though, it does grab the aud_ids correctly, it just grabs all of them in a single submission.
  • The POST/insert php code above left outside (below) of the foreach. This results in only the LAST returned result (if 5 audios returned, index [4]) regardless of which result's input element is used to submit the rating. Still, it captures the rating and the aud_id, just for the wrong (always the last) returned result.
  • Trying to sort out the use of the index key by adding [] to the input name=, as in the included code here, trying to implement the $i (key) to various elements I thought would work ($aud_id, $rate), etc.

Is this a matter of not indexing the input elements correctly in the foreach? Maybe an issue with handling the arrays? Something else entirely?

To sum up: I have a search page that uses an input text box for users to enter a keyword string. The string returns an array that a foreach loop uses to output the queried results, including an input object to allow users to rate the audio. The rates can be submitted just fine, but they end up not being associated with the result audio that the user it actually trying to rate.

How can I ensure that when a result is rated, the rating and the respective aud_id are inserted together as a new entry in the ratings table?

Visual, if it helps:

Query result

Huge thanks to anyone in advance for some help.

First off looking at this from a distance... I see you using PDO, but then I see you escaping the entire point of PDO.

You should not echo your values directly into your query string... You should bind them.

I just want to give you a small PDO example(not particularly related to yours), that way maybe you can use it as a guide to fix your own errors.

            <table class="table table-bordered table-striped mb-none" id="datatable-editable">
                <thead>
                    <tr>
                        <th>Accout Type | User's Name | Email Address</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody id="tablebody">
                    <?
                        $DbHost     = ""; // The host where the MySQL server resides
                        $DbDatabase = ""; // The database you are going to use
                        $DbUser     = ""; // Username
                        $DbPassword = ""; // Password
                        // --- PDO Info
                        $dsn = 'mysql:host='.$DbHost.';dbname='.$DbDatabase; 
                        $DbOptions = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
                        $DBH = new PDO($dsn, $DbUser, $DbPassword, $DbOptions);
                        $qs = "SELECT * FROM `users` WHERE `accountid`=:accountid";
                        $q = $DBH->prepare($qs);
                        $q->bindValue(':accountid',(integer)$userrow['accountid'], PDO::PARAM_INT);
                        $q->execute();
                        while($row = $q->fetch(PDO::FETCH_ASSOC))
                        {
                            if($userrow['access'] >= $row['access'])
                            {
                                ?>
                                    <tr id="row<?=$row['id'];?>">

                                        <?
                                            $qs2 = "SELECT COUNT(*) AS `count` FROM `accounts` WHERE `admin` = :id";
                                            $q2 = $DBH->prepare($qs2);
                                            $q2->bindValue(':id', (integer)$row['id'], PDO::PARAM_INT);
                                            $q2->execute();
                                            $count = $q2->fetch(PDO::FETCH_ASSOC)['count'];
                                            $isAdmin = 'false';
                                            $fontStyle = " style='color:blue;'";
                                            $userType = "Developer";
                                            if($row['access'] == 40)$userType = "Accountant";
                                            if($row['access'] == 60)$userType = "Administrator";
                                            if($row['access'] == 99)$userType = "Internal Administrator";
                                            if($row['access'] == 100)$userType = "Internal Developer";                                                
                                            $root = "<span class='label label-info'>$userType</span>&nbsp;";
                                            if($count > 0)
                                            {
                                                $isAdmin = 'true';
                                                $fontStyle = " style='font-weight:bold;color:red;'";
                                                $root = "<span class='label label-danger'>Root</span>&nbsp;";
                                            }

                                        ?>
                                        <td><span style="color:red;"><?=$root;?></span><span<?=$fontStyle;?>><?=ucfirst(strtolower($row['firstname']))."&nbsp;".ucfirst(strtolower($row['lastname']));?> - <?=$row['email'];?></span></td>
                                        <?
                                            if($count == 0)
                                            {
                                                ?>
                                                    <td><a class="mb-xs mt-xs mr-xs" href="javascript:edit(<?=$row['id'];?>, '<?=$row['firstname'];?>', '<?=$row['lastname'];?>', '<?=$row['email'];?>', <?=$row['access'];?>, <?=$isAdmin;?>)">Edit</a></td>
                                                <?
                                            }
                                            else
                                            {
                                                ?><td>This account cannot be modified here.</td><?
                                            }
                                        ?>

                                    </tr>
                                <?
                            }
                            else
                            {
                                ?>
                                    <tr id="row<?=$row['id'];?>">

                                        <?
                                            $qs2 = "SELECT COUNT(*) AS `count` FROM `accounts` WHERE `admin` = :id";
                                            $q2 = $DBH->prepare($qs2);
                                            $q2->bindValue(':id', (integer)$row['id'], PDO::PARAM_INT);
                                            $q2->execute();
                                            $count = $q2->fetch(PDO::FETCH_ASSOC)['count'];
                                            $isAdmin = 'false';
                                            $fontStyle = " style='color:blue;'";
                                            $root = "<span class='label label-info'>User Account</span>&nbsp;";
                                            if($count > 0)
                                            {
                                                $isAdmin = 'true';
                                                $fontStyle = " style='font-weight:bold;color:red;'";
                                                $root = "<span class='label label-danger'>Root Account</span>&nbsp;";
                                            }
                                        ?>
                                        <td><span style="color:red;"><?=$root;?></span><span<?=$fontStyle;?>><?=ucfirst(strtolower($row['firstname']))."&nbsp;".ucfirst(strtolower($row['lastname']));?> - <?=$row['email'];?></span></td>
                                       <td>You do not have access to modify this account.</td>                                            
                                    </tr>
                                <?
                            }
                        }
                    ?>

                </tbody>
            </table>            

OK, thanks to everyone's help here and some further input/trial and error, I've landed on a solution. I still will be doing some cleanup as suggested, but here is the idea and code that got each input element to act uniquely:

The form element revised:

<?php echo " <form action='#' method='POST'>"; ?>
<?php echo " <input type='hidden' name='audio_index' value='" . $i . "' />"; ?>
<?php echo " <input type='hidden' name='audio_id' value='" .$teaching->aud_id. "' />"; ?>
<?php echo " <div class='range_container'>"; ?>
<?php echo " <div class='rate_sym'>"; ?>
<?php echo " <i class='fa fa-minus' aria-hidden='true'></i> &nbsp"; ?>
<?php echo " <input class='rating' type='range' name='rating_s' min='0' max='100' step='1' value='50' /> &nbsp"; ?>
<?php echo " <i class='fa fa-plus' aria-hidden='true'></i>"; ?>
<?php echo " </div>"; ?>
<?php echo " </div>"; ?>
<?php echo " <div class='rate_container'>"; ?>
<?php echo " <div class='ratescr_container'></div>"; ?>
<?php echo " <input class='rateglowbutton' type='submit' value='Rate' />" ?>
<?php echo " </div>"; ?>
<?php echo " </form>"; ?>
echo " </td>";
echo " </tr>"; ?>

The POST code revised:

<?php
if (isset($_POST['rating_s']) && isset($_POST['audio_id'])) {
$table = "ratings";
$parama = $_POST['audio_id'];
$paramb = $_POST['rating_s'];
$paramc = md5($_SERVER['REMOTE_ADDR']);
$sql = $wpdb->query($wpdb->prepare("INSERT INTO $table (a_id, rating, u_id) VALUES ('$parama', '$paramb', '$paramc')"));
if (query) {
    echo "</br>";
    echo "<div class='rate_msg_cont'><div class='rate_msg'>Hooray! You rated 
audio $parama a $paramb.</div></div>";
    }
}
?>

Notice the additional hidden input elements in the form to generate the index for each audio returned and the "audio_id" for the rating input to utilize. Again, I understand the cleanup and security improvements that can (will) be implemented, but I wanted to post this as a working solution for anyone who needs a tip if dealing with the same or similar.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM