Manipulate PDO Object Results Into a Template - php

I'm making a news page that will update everytime an admin adds a row into the 'news' table. The rows are as follows:
ID, POSTTITLE, POSTDATE, POSTAUTHOR, MESSAGE
I have created a foreach loop that takes all of the data retrieved from that table and takes the data from the nested array:
<?php
$pdo->beginTransaction();
$query = $pdo->prepare("SELECT * FROM news");
$query->execute();
$results = $query->fetchAll(PDO::FETCH_OBJ);
foreach($results as $row) {
foreach($row as $key => $value) {
dump( $key . " = " . $value);
}
}
$pdo->commit();
?>
This outputs this data:
(Which is all of the data inside of the table)
"id = 1"
"posttitle = Welcome To Universal Link Media Group"
"postdate = 2018-10-02"
"postauthor = Ethan (Super Administrator)"
"message = Dummy Text. "
Now here's my question. I want to create a template for each post. So they are uniform. Each post will have a 'title' field, a 'date' field, a 'author' field ect... and I want to put the values from the table into the fields.
It will look something like this:
TITLE: $posttitle
AUTHOR: $postauthor
DATE CREATED: $postdate
MESSAGE: $message
And I'd like it to be dynamic, so it doesn't matter how many rows are in the table, there will always be a template post with the posts data inside of it.
Any help would be greatly appreciated, been stuck on this issue for quite a while.
Thanks!

To get your desired output you just need to change your loop to this:
foreach($results as $row) {
echo 'TITLE: ' . $row->posttitle . '<br>';
echo 'AUTHOR: ' . $row->postauthor . '<br>';
echo 'DATE CREATED: ' . $row->postdate . '<br>';
echo 'MESSAGE: ' . $row->message . '<br>';
}
If you really want to make Templates, you should take a look at some templating-languages like Twig. https://twig.symfony.com/

Related

Inserting wrong data in to the database with $wpdb->insert

So hey guys!
I currently have a code that gets data from a custom table called wp_refundrequests, and prints them as a table to the page. On the page the admin can either Accept, or Deny the request by pressing a button on the side of each order. Denying the request just deletes the request from the table, but accepting should delete it from the current table and insert the information to the next table called "accepted requests".
The wp_refundrequests table contains customer's order that they want to refund.
The code that gets the info and prints it:
global $wpdb;
$requests = $wpdb->get_results("SELECT * FROM wp_refundrequests", ARRAY_A);
foreach ($requests as $row) {
echo "<div class='requests'>" . "<li class='refunds'>" . "Palauttajan nimi: ".
$row['customer_name'] . "</br>" ."Palautettavat tuotteet: ".$row['product_name']."<br> "."Määrä: ".
$row['product_qty'] . " "
. "<br>Kommentti: " . $row['comment'] . "<br> " . "Hinta: " . $row['refund_total'] . "€ " .
"<br>" . "Päivämäärä: " . $row['request_date'] . " " .
"<a class='right' href='admin-page?deleteid=" . $row['request_id'] . "'>Deny</a></li>" .
"<li class='refundaccepts'><a href='admin-page?acceptid=" . $row['request_id']
. "'>Accept</a></li>" . "</div>";
$_SESSION['custname'] = $row['customer_name'];
$_SESSION['prodname'] = $row['product_name'];
}
With my current code, the "Accept" button deletes it, and inserts information in to the new table, BUT the information that is inserted is wrong. It seems like it wants to either insert the latest data that had been inserted in to the wp_refundrequests table to the wp_acceptedrequests, or it keeps the data from the latest refund request and tries to insert that instead because for example as seen here(Sorry for the bits of Finnish as well):
If I were to click the "Accept" button on the above, older one, the query would still insert it like this:
So it basically inserts the info from the latest refund_request insert and inserts that instead of the one selected. However the one that had been selected still gets deleted from the table.
Here's the code that is triggered when the user clicks on "Accept"
$custname = $_SESSION['custname'];
$prodname = $_SESSION['prodname'];
if(isset($_GET['acceptid'])) {
$accept = $_GET['acceptid'];
/* Query to do whatever here */
$wpdb->print_error();
$wpdb->insert("wp_acceptedrequests", [
"customer_name" => "$custname",
"name_product" => "$prodname",
"date" => date("Y/m/d/G:i:sa") ,
]);
$wpdb->print_error();
$wpdb->query("DELETE FROM wp_refundrequests WHERE request_id = $accept");
}
I have to say I have no idea why it doesn't want to insert the selected request, please comment if there's something confusing, I'll try to clear it up then.
Thanks in advance!
You redefine $_SESSION with in foreach loop so at the end of foreach it will equal to the last one, pass each row parameter to it is accept link like this
"<li class='refundaccepts'><a href='admin-page?acceptid=" . $row['request_id']."&custname=".$row['customer_name']."&prodname=".$row['product_name']."'>Accept</a></li></div>";
Then call it the same way you get $accept-ID
if(isset($_GET['acceptid'])) {
$accept = $_GET['acceptid'];
$custname = $_GET['custname'];
$prodname = $_GET['prodname'];
Note:Iuse my phone so make sure if it was a syntax error in the href part of the code
Please try like this and comment out the session variable.
if(isset($_GET['acceptid'])) {
$accept = $_GET['acceptid'];
$accepted_requests = $wpdb->get_results("SELECT * FROM wp_refundrequests WHERE id = $accept", ARRAY_A);
if( !empty($accepted_requests) ) {
$insert = $wpdb->insert("wp_acceptedrequests", $accepted_requests);
if($insert) {
$wpdb->query("DELETE FROM wp_refundrequests WHERE request_id = $accept");
}
}
}

How can I use the results of my query in a dropdown menu?

I am trying to create a dropdown menu that will have as options certain fields recovered from a database using a for loop.
I am doing the following:
for ($article_id=1; $article_id <=30; $article_id++)
{
$sqltitles = "SELECT title FROM articles WHERE article_id='$article_id'";
$cursor = mysqli_query($db, $sqltitles) or die($sqltitles."<br/><br/>".mysql_error());
$row = mysqli_fetch_row($cursor);
$titles = $row[0];
echo $titles;
echo "</br>";
}
Which draws all the titles from the database and shows them one at a time.
Is there any way to make all those titles appear as options to a dropdown menu, so the user can select which one to read?
Something like this should work. I made a modification to how the query is working. If you specify article IDs for a range of articles in your query rather than just one specific ID, you should be able to execute only one query instead of one for each ID you want to retrieve. Regardless of whether or not you decide to use the approach I suggested, the syntax for creating the dropdown menu should be the same.
<select>
<?php
$sqltitles = "SELECT title FROM articles WHERE article_id BETWEEN 1 AND 30" ;
$cursor = mysqli_query($db, $sqltitles) or die($sqltitles."<br/><br/>".mysql_error());
while ($row = mysqli_fetch_row($cursor)) {
echo '<option value ="' . $row[0] . '">' . $row[0] . '</option>';
}
?>
</select>
Here is a good reference for how to create HTML <select> tags.
try something along the lines of...
echo '<select name="dropdownname">';
foreach ($titles as $key => $val) {
echo('<option value="' . $val .'">' . $val . '</option>');
}
echo '</select>';

All rows displayed when trying to display rows that contain a string

I have some code where I want it to only show rows where there is a certain string in a column. I have a column called "Tags" where it has tags in this format "tag1, tag2" Etc. I want to have links so people can only show products with a certain tag. This is where I run into problems. I can't get it to show rows with certain tags, it shows every row.
<?php
try {
//open the database
$db = new PDO('sqlite:prodDb.sqlite');
$tag = $_POST['tag'];
if (isset($tag)) {
$result = $db->query('SELECT * FROM Products WHERE instr(Tags, $tag) > 0');
} else {
$result = $db->query('SELECT * FROM Products ');
}
//now output the data to a simple html table...
$result = $db->query('SELECT * FROM Products');
foreach ($result as $row) {
print "" . $row['Id'] . "<br />";
print "" . $row['Name'] . "<br />";
$tags = explode(', ', $row['Tags']);
foreach ($tags as $tag) {
print "Tag: " . $tag . "<br />";
}
print "" . $row['Link'] . "<br />";
print "" . $row['Screenshot'] . "<br />";
print "" . $row['Download'] . "<br />";
}
// close the database connection
$db = NULL;
}
catch (PDOException $e) {
print 'Exception : ' . $e->getMessage();
}
?>
Any ideas where I went wrong?
Get rid of the $db->query line here:
//now output the data to a simple html table...
$result = $db->query('SELECT * FROM Products');
You're discarding the results from the query that matched the tag, and using this query that returns all products.
In the query with the tag, you have a syntax error, because you need quotes around the string. It would be better to use a prepared query:
$stmt = $db->prepare('SELECT * FROM Products WHERE INSTR(Tags, :tag)');
$stmt->execute(array(':tag' => $tag));
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
Also, if you have all the tags in a single column, you have a poor table design. You should normalize your data by moving the tags into a separate table, with one row per tag for each product.
It probably doesn't work because here:
//now output the data to a simple html table...
$result = $db->query('SELECT * FROM Products');
You are simply selecting all products and ignoring the previous query/filter.

Populate table with field names and values taken from mysql database

I'm trying to populate a table with values extracted from a mysql table stored in a wordpress database.
I've successfully managed to populate the body of the table with the record's fields but I'm wanting to show the column name for each particular field as a header. Note, I'm wanting the headers on the left and values on the right, not above and below like a traditional table.
I've tried using "SHOW COLUMNS FROM $table_name" and also the mysqli_fetch_field_direct function but I can't work out a way of making it work in the format I'm looking for where it's part of a loop. I'm new to PHP so I'm sure it's pretty simple but I'm completely stuck.
My code is below, I've marked where I want to echo the field names.
What I basically want to acheive is a table like this:
column_1_name:field_in_column_1
column_2_name:field_in_column_2
column_3_name:field_in_column_3
...
Thanks for any help in advance!
<table class="widefat">
<tbody>
<?php
global $wpdb;
$table_name = $wpdb->prefix . "consultation";
$query = "SELECT * FROM $table_name WHERE id=$_GET[id]";
$results = $wpdb->get_results($query);
// Test if there was a query error
if (!$results) {
die ("Please select a user from the Consultation admin homepage");
} else {
foreach ($results as $record) {
foreach ($record as $field) {
echo "<tr><th>" . **THIS IS WHERE I WANT COLUMN NAME OF $field** . "</th><td> {$field}</td></tr>";
}
}}
?>
</tbody>
foreach($results as $key => $val){
echo '<tr><td>' . $key . '</td><td>' . $val . '</td></tr>';
}

Show results from different queries on one page, either or, not all at the same time

Not sure if that was the best way to phrase what I'm trying to do. Here goes:
I want users to be able to show results form my DB based on three different tables, one at a time.
I have the queries ready, but only want to show one result on the page at a time, based on what the user clicks. The queries are based on 3 different tables. There is a Today table, a This Week table, and a This Month table.
So when a users clicks Today, I want to show the results from the Today table. When they click This Week, I want the results to switch to come from the This Week table. I'm assuming this can be done with a simple if-then logic in PHP.
Here's how I'm calling from the Today table:
<?php
global $wpdb;
$result = $wpdb->get_results('SELECT name, count FROM wp_celebcount_today');
foreach($result as $row) {
echo '<a href="http://www.celebrything.com/?s=' .
urlencode($row->name) . '&search=Search">' . $row->name .
'</a> - ' . $row->count . ' Posts<br/>';}
?>
I would call from the This Week table like so:
<?php
global $wpdb;
$result = $wpdb->get_results('SELECT name, count FROM wp_celebcount_thisweek');
foreach($result as $row) {
echo '<a href="http://www.celebrything.com/?s=' .
urlencode($row->name) . '&search=Search">' . $row->name .
'</a> - ' . $row->count . ' Posts<br/>';}
?>
This query is currently running from the page load. How do I insert logic to make it run from a click on "Today", "This Week", or "This Month"?
OK - Thanks for the help so far! I have this:
<div id="sidebar">
<div class="post">
<h2>
<font color="#333333">Most Popular Celebrities</font><br>
<font color="#333333">in last 24 hours</font>
<br>
<br>
Today
Week
Month
<?php
if (!in_array($table, array('today', 'week', 'month')) {
return false;
}
global $wpdb;
$result = $wpdb->get_results('SELECT name, count FROM wp_celebcount_' . $table);
foreach($result as $row) {
echo '<a href="http://www.celebrything.com/?s=' .
urlencode($row->name) . '&search=Search">' . $row->name .
'</a> - ' . $row->count . ' Posts<br/>';
}
}
showTable($_GET['table']);
?>
</h2>
</div>
</div>
<div class="clear"></div>
I'm getting this error:
Parse error: syntax error, unexpected '{' in /home/content/c/e/l/celebrything/html/wp-content/themes/celebrything/sidebar.php on line 16
You can make the code into a function, and choose the table via a request param. Like so below. Note I added in_array check to make sure the table is not any table.
Today
Week
PHP
function showTable ($table) {
if (!in_array($table, array('today', 'week', 'month')) {
return false;
}
global $wpdb;
$result = $wpdb->get_results('SELECT name, count FROM wp_celebcount_' . $table);
foreach($result as $row) {
echo '<a href="http://www.celebrything.com/?s=' .
urlencode($row->name) . '&search=Search">' . $row->name .
'</a> - ' . $row->count . ' Posts<br/>';
}
}
Call the function in your page.php:
if (empty($_GET['table'])) {
showTable($_GET['table']);
} else {
showTable('today');
}
You can make it based on URL parameters.
The link will look something like this: site.php?type=today.
Then, in your PHP script, you could for example do this:
if (isset($_GET['type']))
{
switch ($_GET['type'])
{
case 'today':
// Query and list for today
break;
case 'thisweek':
// Query and list for this week
break;
case 'thismonth':
default:
// Query and list for this month
break;
}
}
else
// Error handling here
EDIT: I made the example be more concrete and used a switch construct, because it allows to mess with the default case more easily.
This is now assuming that when an invalid type is given, the list for this month is displayed. I think that's what you want...
Let me ask you, though: Why exactly do you even have these three tables? Please tell me you're not using some sort of cron-like script to move items from the today table to the this week column and so on... If so, you should just do it in one table, with one date column.
EDIT 2: To fix your example code, though, you need to change the variable name from $table to $_GET['table']. You should also check whether the variable exists at all (by checking with isset($_GET['table'])).

Categories