About the evil of eval: How to clean up - php

I'm building a site that will (eventually) be the front-end for a game. I want to be able to dynamically build a list of "powers" that the user is able to purchase. In order to build these lists, I'm using a PHP-based SQL query, then passing it to Javascript for dynamic choices (some powers have prerequisite powers).
I know there's a simpler way to do what I'm doing, but I'm not super concerned with that right now (I will be later, but I'm trying to get this functional and then clean) (again, I know this is non-optimal).
I'm using eval to parse which divs to show, and I want to know how not to.
I'm having issues getting my div names built right in the first place.
Here's my code:
Javascript (separate file)
function upgradeList(passed)
{
var PowerArray = [];
var DetailPowerID = [];
var EscapedPowerID = [];
PowerArray.push([]);
PowerArray = eval(passed);
var OutputThing="";
for (i=0;i<PowerArray.length;i++)
{
DetailPowerID[i] = 'detail' + PowerArray[i][0];
EscapedPowerID[i] = "'" + DetailPowerID[i] + "'";
}
for (i=0;i<PowerArray.length;i++)
{
OutputThing = OutputThing + "<br><a href='#' onClick='showUpgradeDetails(" + DetailPowerID[i] + ")'>" + PowerArray[i][2] + "</a><div class='hidden' id='" +
DetailPowerID[i] + "'>" + PowerArray[i][3] + "</div>"; }
document.getElementById("secondUpgrade").innerHTML=OutputThing;
document.getElementById("secondUpgrade").style.display='block';
}
}
PHP writing HTML and JS:
{$AbleToUpgrade and $UpgradeList are both 2d arrays built from SQL queries)
echo "<script name='UpgradeList'>";
settype($UpgradesListSize[$i],"int");
for ($i=0;$i<count($AbleToUpgrade);$i++)
{
echo "var UpgradeList" . $AbleToUpgrade[$i][0] . " = new Array();";
for ($j=0;$j<=$UpgradesListSize[$i];$j++)
{
echo "UpgradeList" . $AbleToUpgrade[$i][0] . ".push(Array('"
. $UpgradeList[$i][$j][0] . "', '"
. $UpgradeList[$i][$j][1] . "', '"
. $UpgradeList[$i][$j][2] . "', '"
. $UpgradeList[$i][$j][3] . "', '"
. $UpgradeList[$i][$j][4] . "'));";
}
}
echo "</script>";
... and, later...
echo "<div id='SpendUpgrade'>
Select power to upgrade:
<ul>";
for ($i=0;$i<count($AbleToUpgrade);$i++)
{
echo "<li><a href='#' name='UpgradeList" . $AbleToUpgrade[$i][0] . "' onClick='upgradeList(this.name)'>" . $AbleToUpgrade[$i][1] . " - " . $AbleToUpgrade[$i][2] . "</a></li>";
}
echo "</select>
<div id='secondUpgrade' class='hidden'>
</div>
<div id='thirdUpgrade' class='hidden'>
</div>
</div>";
When I load the page, I wind up with generated text like this:
Real Armor
and the corresponding div:
<div class="hidden" id="detail21" style="display: none;">Your armor only works in the Waking</div>
In order to get the div to show (display:block;), I need to call the function like so:
showUpgradeDetails("detail21")
but I can't make JS / PHP write the quotes correctly. Help (with any or all of this?) please!

I found a resolution, and it wasn't JSON.parse().
I changed PowerArray = eval(passed); into PowerArray = window[passed];.
Because passed contains the name of a variable, and is not the variable itself, I couldn't work directly with it. However, because it was a string that held exclusively the name of a globally-defined variable, I could pass it to the window[] construct and have it work.

Related

Have error of syntax but don't know where

Well, i have a table generator, with the data of mysql db.
First, the code:
PHP
while($result = mysqli_fetch_assoc($SQL)){
$tbl->addCell("<p onBlur = 'editTable(" . $result['id_user'] . ", this, 'Name')' contentEditable = 'true'>" . $result['Name'] . "</p>");
$tbl->addCell("<p onBlur = 'editTable(" . $result['id_user'] . ", this, 'Username')' contentEditable = 'true'>" . $result['Username'] . "</p>");
$tbl->addCell("<p onBlur = 'editTable(" . $result['id_user'] . ", this, 'Email')' contentEditable = 'true'>" . $result['Email'] . "</p>");
$tbl->addCell("<p onBlur = 'editTable(" . $result['id_user'] . ", this, 'Grade')' contentEditable = 'true'>" . $result['Grade'] . "</p>" );
$tbl->addCell("<input type = 'button' class = 'Edit-TBB' value = 'Edit'>
<input type = 'button' class = 'Delete-TBB' value = 'Delete'>");
$tbl->addRow();
}
AJAX
function editTable(id, new_text, column) {
$.ajax({
url: "../PHP/Configuracion/edit_grade.php",
type: "POST",
data: 'id='+id+'&text='+new_text.innerText,
success: function(data){
alert(column);
}
});
}
Here is the problem:
I have this 'editTable(" . $result['id_user'] . ", this, 'Name')'
In Chrome, it show me this
if i change the code in Chrome like this ... It works, but i don't know what i need to change at the code editor.
What i need to change?
THANKS!
You have to use double quotes for your onBlur value since you are using single quotes to denote a js string as a parameter. To do this, you need to escape a double quote in your php. So change the addCell calls to look like:
addCell("<p onBlur=\"editTable(" . $result['id_user'] . ", this, 'Name')\" contentEditable = 'true'>");

Open different modal-diaglog with foreach()

I'am trying to implement a modal that shows always different information. This depends on the name you click. At this moment he always shows the modal of the latest link.
Here I'm printing out the different information. For each line i want a specific modal
PHP
foreach ($badgesNotifications as $notifications) {
echo "<p>Congratulations! You've earned the <a href='#' data-reveal-id='myModal'>" . $notifications['challenge_badge_title'] ." badge</a></p>";
echo "<div id='myModal' class='reveal-modal' data-reveal>
<h2>" . $notifications['challenge_title'] . "</h2>
<p class='lead'>Your couch. It is mine.</p>
<p>" . $notifications['challenge_description'] . " </p>
<a class='close-reveal-modal'>×</a>
</div>";
}
?>
I tried to replace 'myModal' with $notifications['challenge_badge_title'] in the link and the id of the mail but then he isn't opening the modal.
The title is always different so I thought he would open an other window. The id don't have to be necessary "MyModal" because it's working with other words to.
I also tried to put the data in different arrays because they are overwriting each other. But also that won't fix my problem.
public function BadgeNotifications($user_id)
{
$db = new Db();
$select = "SELECT
c.challenge_id,
c.challenge_title,
c.challenge_target,
c.challenge_description,
c.challenge_badge_img,
c.challenge_badge_title,
p.challenge_id,
p.user_id,
p.challenge_progress
FROM (tblchallenges c INNER JOIN tblchallenges_progress p ON c.challenge_id = p.challenge_id) WHERE p.user_id = " . $user_id . " ";
$result = $db->conn->query($select);
$result_count = mysqli_num_rows($result);
$result_array = array();
for($i = 0; $i < $result_count; $i++)
{
$result_data = mysqli_fetch_assoc($result);
$result_array[$i]["challenge_id"] = $result_data["challenge_id"];
$result_array[$i]["challenge_title"] = $result_data["challenge_title"];
$result_array[$i]["challenge_description"] = $result_data["challenge_description"];
$result_array[$i]["challenge_badge_title"] = $result_data["challenge_badge_title"];
}
return $result_array;
}
It looks like there's an error here with your code:
echo "<div id='myModal' class='reveal-modal' data-reveal>";
You should perhaps give each modal a unique ID. Properly written Javascript applications fall over when ID's are used more than once as the CSS/JS specification says that you may only use an ID once.
My solution below introduces an iterator $i which you can use to make each echoed element unique.
You will notice that the modal ID now has a number at the end of it, (myModal0, myModal1, etc.).
foreach ($badgesNotifications as $i => $notifications)
{
echo "<p>Congratulations! You've earned the <a href='#' data-reveal-id='myModa" . $i . "l'>" . $notifications['challenge_badge_title'] ." badge</a></p>";
echo "<div id='myModal" . $i . "' class='reveal-modal' data-reveal>
<h2>" . $notifications['challenge_title'] . "</h2>
<p class='lead'>Your couch. It is mine.</p>
<p>" . $notifications['challenge_description'] . " </p>
<a class='close-reveal-modal'>×</a>
</div>";
}
?>

PHP/MySQL - Trying to Pass Query Variables From MySQL Fetch Array Through Page URL

I'm running a script that fetches a row from a MySQL table and is supposed to then pass certain variables from that row to the next page to be used in a form that allows user updating.
Here's the excerpt from the script that is trying to pass the variables to the next page:
if ($row['home_score'] == '0' && $row['away_score'] == '0') {
echo '<td><img src="images/report_icon.png" alt="Report Score" /></td>';
}
If I omit everything after "&game_id=" in the href, it displays fine. However, once I start adding the variables, it cuts off the function and stops displaying the page.
Am I doing something simple wrong with the syntax? I've tried playing around with different ways to write it, but to no avail. Do I need to utilize a http_build_query() to make this work?
Here's the entire script code if you need more info:
<?php
// Connect to the database:
require ('../mysqli_connect.php');
// Make the query for games from the schedule database and determine the game location:
$q = "SELECT tl.game_date, tl.game_time, tl.away_team, tl.home_team, tl.home_score,tl.away_score, tl.arbiter_id, us.football_location, us.football_map
FROM test_league tl
INNER JOIN user_schools us ON (tl.home_team = us.school_name)
ORDER BY tl.game_id";
$r = mysqli_query($db, $q);
// Declare two variables to help determine the background color of each row:
$i = 0;
$bgcolor = array('row1', 'row2');
// Begin function to print each game as a row:
while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
echo '<tr class="' . $bgcolor[$i++ % 2] .'"><td>' . $row['game_date'] . '</td><td>' . $row['game_time'] . '</td><td class="alignleft">' . $row['away_team'] . ' vs<br>' . $row['home_team'] . '</td>';
// Determine if the score has been reported:
if ($row['home_score'] == '0' && $row['away_score'] == '0') {
echo '<td><img src="images/report_icon.png" alt="Report Score" /></td>';
} else {
echo '<td>' . $row['home_score'] . '<br>' . $row['away_score'] . '</td>';
}
echo '<td>' . $row['football_location'] . '</td><td>' . $row['arbiter_id'] . '</td></tr>';
}
mysqli_free_result ($r);
mysqli_close($db);
?>
Any and all advice is greatly appreciated!
Try this, you've got your speech marks and dots mixed up :)
if ($row['home_score'] == '0' && $row['away_score'] == '0') {
echo '<td><img src="images/report_icon.png" alt="Report Score" /></td>';
}
Hope this helps!
$url = 'www.example.com?' . http_build_query($row,'','&');

Putting dynamically created ID into javascript

So I have a script that auto-generates ID's based on a column in a database. like such:
echo "<tr class='task' id='task-" . $row['task_id'] . "'>";
And then I have a script that is below that I am wanting it to change each tr class name based on some information from another column. I tried placing the same code 'task-". $row[task_id] ."' into the document.getElementById field but it didn't resolve in the browser. resolve meaning it stayed as 'task-" . $row[task_id] . "' instead of changing $row[task_id] into a number. I need to make that change to a number so it matches the id's of the tr.
var resolved = <?php echo $_SESSION['resolved']; ?>;
if (resolved == 1)
{
document.getElementById('task-" . $row[task_id] . "').className ="task resolved";
}
else
{
document.getElementById('task-" . $row[task_id] . "').className =" task";
}
You need to echo out the variables like so:
var resolved = <?php echo $_SESSION['resolved']; ?>;
if (resolved == 1)
{
document.getElementById('task-<?php echo $row['task_id'] ?>').className ="task resolved";
}
else
{
document.getElementById('task-<?php echo $row['task_id'] ?>').className =" task";
}
But it's better to not do it in javascript but to just do it in your PHP like so:
echo "<tr class='task " . ($_SESSION['resolved'] == 1 ? 'resolved' : '') ."' id='task-" . $row['task_id'] . "'>";
that adds the resolved class to as you are generating your HTML. However you will probably need a better way to test if a task is resolved because with the $_SESSION['resolved'] == 1 it's going to mark ALL tasks as resolved. So assuming your row has a column like `$row['resolved'] you could do:
echo "<tr class='task " . ($row['resolved'] == 1 ? 'resolved' : '') . "' id='task-$row[task_id]'>";
No need for javascript, if your status is in a column of that table....
if($row['resolved']=="1){
$class="task resolved";
} else {$class = "task";}
echo "<tr class='".$class."' id='task-" . $row['task_id'] . "'>";
Or a much simpler version...
echo "<tr class='task ".($row['resolved'] == 1 ? 'resolved' : '')."' id='task-".$row['task_id']."'>";

Creating Div using Zend_Form?

I want to hidden/store dynamically generated div inside parent div.I have taken the following piece of code from my form page.
....
$existing_billing_address = array();
if (count($all_addr) > 0) {
$hidden_existing_addr_div = '';
foreach ($all_addr as $addrvalue) {
$existing_billing_address[$addrvalue['address_id']] = $addrvalue['address1'];
$exname = $addrvalue['address_name'];
$exaddress1 = $addrvalue['address1'];
$exaddress2 = $addrvalue['address2'];
$excountry = $addrvalue['country'];
$exstate = $addrvalue['state'];
$excity = $addrvalue['city'];
$exzipcode = $addrvalue['zipcode'];
$exphone = $addrvalue['phone'];
$exaddress_id = $addrvalue['address_id'];
$hidden_existing_addr_div .= "<div id='selectBilling_" . $exaddress_id . "' style='display:none'>";
$hidden_existing_addr_div .= $exname . "||" . $exaddress1 . "||" . $exaddress2 . "||" . $excountry . "||" . $exstate . "||" . $excity . "||" . $exzipcode . "||" . $exphone . "||" . $exaddress_id;
$hidden_existing_addr_div .= "</div>";
}
}
....
This will generate some thing like below,
> <div style="display: none;" id="selectBilling_40">Dinesh
> billing||billing add1||Billing
> add2||IN||TA||Chennai||625001||1234567891||40</div><div
> style="display: none;" id="selectBilling_41">kumar shipping||shipping
> add1||shipping add2||US||CA||chennai||72944||1234567891||41</div>
I want to store the above hidden div using zend_form.
Kindly help me on this.
Well, in this case you can use a Zend_Form, hidden it and then store its values so you can make validation too.
If you want to display it as a div, you can change how it looks using Zend_Decorator. Anyway, you don't need to hide every element, you can just hide the whole form.
I have used hidden text box, Using jquery i ve taken the hidden text box value and create DIV with that content and clear the input box value.
$(function(){
var val = $('#edit_existing_billingaddr').val();
$('#edit_existing_billingaddr').after('<div>'+val+'</div>');
$('#edit_existing_billingaddr').val('');
});
But i am not use zend completely here.

Categories