I have a simple market and user customisation system, when a user equips an item it goes to (URL)/render.php?id=item ID , in the render.php file it has simple code found below. How would I make the file check if the user actually owns the item before equiping it? (at the moment it doesn't and you can wear stuff you don't own by abusing that)
<? include "../../header.php";
$id = $_GET['id'];
$item = $handler->query("SELECT * FROM items WHERE id=" . $_GET['id']);
$gI = $item->fetch(PDO::FETCH_OBJ);
$handler->query("UPDATE `users` SET `$gI->type`='$gI->wearable' WHERE `id`='$myu->id'");
?>
<head><meta http-equiv="refresh" content="1; url=/Customize/"></head>
You can make a table for users_items and use the table to save the users items when a user obtains an item. You would insert a row in this table that links the user to the item, i.e: id, user_id, item_id, then instead of directly selecting from the items table, you select from users_items and JOIN from the items table the details of the item.
SELECT items.type,
items.wearable
FROM users_items
LEFT JOIN items ON items.id = users_items.item_id
WHERE users_items.item_id = ?
Then use prepared queries on ?, instead of string concatenation to prevent SQL injection
Related
I have been trying everything to achieve this task, but it is rather difficult.
I am trying to do this in Wordpress as shortcode.
The shortcode itself is fine, I don't need any help with that, but just the output here which is giving me a difficult time. The Shortcode has an attribute that can be used to show the ID of the list using $listID
As an example, I have 3 database tables.
complete (variables: id, itemID, listID, userID)
item (variables: id, listID, description, creator)
list (id, name)
What I need to do is show a list from a shortcode variable, in this case database id 1 for the list. Then show the items in that list (using listID in item variable as well as wordpress user function to grab the ID of the logged in user and compare it to the creator variable of the item) -- and have the completed marked in there (using itemID, listID and the logged in user to wordpress to compare with the userID).
I tried this for SQL, but it returned nothing
global $wpdb;
$q_checked = $wpdb->prefix.'checked';
$q_item = $wpdb->prefix.'items';
$q_list = $wpdb->prefix.'list';
$q_results = $wpdb->get_results("
SELECT * FROM (($q_item INNER JOIN $q_list ON $q_item.listID = $listID)
INNER JOIN $q_checked ON $q_list.id = $q_checked.listID;
I also tried this with sql but it only shows from the two tables and not the third, and it will show all instead of excluding the completed.
$q_items = $wpdb->prefix.'items';
$q_checked = $wpdb->prefix.'checked';
$q_result = $wpdb->get_results("SELECT $q_items.title, $q_checked.userID FROM $q_items INNER JOIN $q_checked ON $new_items.id = $q_checked.itemID");
I thought about using a foreach, but none of the above would work well with that would it? Since you can only use one result. Maybe if I could do 2 separate foreach, 1 for the items in the list but exclude them if the id of the item matches the itemID in the completed database? Then do another foreach that would show the completed items for that list.
<?php foreach($q_result as $i ) {
$userID = $i->userID;
$itemNAME = $i->title; ?>
<?php if($userID === ''.$current_user->ID.'') { ?> <?php echo $itemNAME; ?><?php }?>
<?php }; ?>
I honestly think I should rethink the entire thing. Maybe I am overcomplicating it?
This is a fairly standard MySQL query:
SELECT i.description, i.creator,
IF(c.id IS NOT NULL, 'Completed', 'Not Completed') AS status
FROM item i
LEFT JOIN complete c
ON c.itemID = i.id AND
c.listID = i.listID AND
c.userID = ?
WHERE i.listID = ?
The ? placeholders represent parameters that you would bind to the current user ID and list ID supplied by your shortcode.
This performs a left join from items to completed items, and checks for a match on all join conditions. If a match is found, then a row will exist in c, and we mark the item as completed. Otherwise, the c.id will be NULL and we mark it as not completed.
I have a table named purchase_details_master and another is sales_detais_master Where all the purchase and sales details are available.
Structure of Purchase Table: These are the data which I have purchased
Structure of Sales Table: These are the data which I have sell
Now I need to show the data like this, This image is showing the iPhone 12 data. In the Inward field showing tha pieces of purchased item, In the Outward field showing the data of sells pieces, and the closing data showing like Opening + Inward or Opening - Outward = Closing
I am using Core Php with Sqlite database
$item = $_POST['item'];
$sql = "SELECT * FROM purchase_details_master WHERE item_id = '$item'";
$sql_run = $conn->query($sql);
I have used while loop it's not solving the problem
Kindly solve this out for me! Thank you in Advance
A JOIN clause is used to combine rows from two or more tables, based on a related column between them.
like that.
SELECT * FROM purchase_details_master AS pdm INNER JOIN sales_detais_master AS sdm ON sdm.item_id = pdm.item_id WHERE sdm.item_id = ?
this will select all fields from the two tables
$sql = "SELECT * FROM purchase_details_master, sales_detais_master WHERE purchase_details_master.item_id = '$item' AND purchase_details_master.item_id = sales_details_master.item_id";
or select exact fields from the two tables
SELECT table1.field1, table1.field2, table2.field1, table2.field3
FROM table1, table2,
WHERE table1.field1 = something, or table1.field1 = table2.field2
My tables are structured as follows:
TAGS (more of a category): id, tag name, description, slug
POSTS: id, title, url ...
POSTSTAGS: id, idPost, idTag
USERS: id, username, userSlug...
VOTES: id, idPost, idUser
Every post can have up to five tags and every user can vote only once. Currently, as the tags are not implemented yet, I retrieve my paginated result set with the following query:
SELECT p.*, u.username, u.userSlug, u.id as userId,
exists (select 1 from votes v where v.idUser=$id AND p.userId=v.idUser AND p.url = v.url) as voted
FROM posts p
JOIN users u ON u.id=p.userId
ORDER BY p.created DESC
LIMIT 10 OFFSET :offset
The query gets ran via PDO and returned in JSON format to an angularjs ng-repeat. The $id is the logged in user's id. I use it in the exists subquery to gray out the vote buttons in my angular view (there is also a check on the server side). If someone clicks the username in the view, he will be taken to a detail page where all the user's posts are shown (userSlug to the rescue).
The next step is to include the tags in the result list and here I stuttered. Each post in the list must contain all the associated tags (tagName, description, slug) and each tag must take you to a details page where all the associated posts for that particular tag are shown.
The first solution that came to mind was to bruteforce my way through this after running the previously mentioned query:
foreach ($postsResult as &$post) {
$sql ="SELECT t.* FROM tags t JOIN poststags pt ON t.id=pt.idTag WHERE pt.idPost=$post->id";
$stmt=$db->prepare($sql);
$stmt->execute();
$tagsResult=$stmt->fetchAll(PDO::FETCH_OBJ);
$post->tags = $tagsResult;
}
$response->write(json_encode($postsResult));
Done, easy peasy! Lot's of queries that will generate a huge amount of strain on the server. And we don't want to do that.
The second solution was to fire another query that fetches all tags associated with the postsResult(s) and then insert the corresponding tags in each post letting PHP do the dirty job.
$sql = "
SELECT t.*,
pt.idPost
FROM tags t JOIN poststags pt ON t.id=pt.idTag
WHERE pt.idPost IN (array of post ids)
";
$stmt=$db->prepare($sql);
$stmt->execute();
$tagsResult = $stmt->fetchAll(PDO::FETCH_OBJ);
foreach ($postsResult as &$post) {
$arr = array();
foreach ($tagsResult as $tag) {
if ($post->id==$tag->idPost) {
$arr[]=$tag;
}
}
$post->tags = $arr;
}
$response->write(json_encode($postsResult));
Is there any better or faster way to do this?
Is there any better or faster way to do this?
If you index $tagsResult by postId, which you can do by using FETCH_GROUP, then you can remove the inner nested loop and grab all tags with a certain postId in constant time:
$sql = "
SELECT pt.idPost, — select idPost first so it’s grouped by this col
t.*
FROM tags t JOIN poststags pt ON t.id=pt.idTag
WHERE pt.idPost IN (array of post ids)
";
$stmt=$db->prepare($sql);
$stmt->execute();
$tagsResult = $smt->fetchAll(\PDO::FETCH_GROUP|\PDO::FETCH_OBJ);
//$tagsResult is now grouped by postId
//see https://stackoverflow.com/questions/5361716/is-there-a-way-to-fetch-associative-array-grouped-by-the-values-of-a-specified-c
foreach($postsResult as &$post) {
if(isset($tagsResult[$post->id])) {
$post->tags = $tagsResult[$post->id];
}
else {
$post->tags = array();
}
}
Im trying to find an efficient way to display all posts from people who are being followed by the logged in account holder.
There are two key tables:
1- Posts
table name : posts
id, account_name, published, body
2- Follows
Table name : follows
id, account_name, followed_name
I'm trying to find a way that i can display all the posts from all the accounts that are being followed. The connection between Posts and Follows is the Account_name.
I understand that it will probably be a join, but it's how I construct the WHERE clause. So far I have the following (The account name is set via $_SESSION['account_name']):
$sql = "SELECT * FROM posts LEFT JOIN follows ON posts.account_name = follows.account_name WHERE --- How would I only get the posts from the accounts being followed ?---"
I'm sure this is something simple my brain just feels drained and I cant seem to work it out.
UPDATE Attempting in PDO
Returning NULL at the moment,
$sql = "SELECT * FROM share_posts WHERE account_name IN (SELECT followed_name FROM $this->account_follows WHERE account_name = :account_name)";
return $this->AC->Database->select($sql, array('account_name' => $account_name));
The goes to my Database Class:
public function select($sql, $array = array(), $fetch_mode = PDO::FETCH_ASSOC)
{
$stmt = $this->AC->PDO->prepare($sql);
foreach ($array as $key => $value)
{
$stmt->bindValue("$key", $value);
}
$stmt->execute();
return $stmt->fetchALL($fetch_mode);
}
The returned data is NULL at the moment even though the logged in account has followed other accounts.
$account = $_SESSION['account_name'];
//do some sql injection checking on $account here
$sql = "SELECT * FROM posts WHERE account_name IN (SELECT followed_name FROM follows WHERE account_name='".$account."')";
This will get all the posts where the account name matches somebody you follow. I wasnt sure who was following who, but in this case the followed_name are the people account_name is following. If thats the other way around, switch the values
$sql = "SELECT * FROM posts WHERE account_name IN (SELECT account_name FROM follows WHERE followed_name='".$account."')";
I will write this the way I interpret your question.
What you need to do is select only the posts from the users that are followed by your logged in user.
To break this down, first you want to select the users followed by the logged in user. To do this, we use the Follows table.
We then want to select the posts by these users. As such my query would be this.
SELECT posts.* FROM follows
LEFT JOIN posts ON posts.account_name = follows.follows_name
WHERE follows.account_name = $logged_in_user
I am trying to add data into 3 table using PHP, atm I can only view the results of the tables that are joined .
RESULTS QUERY
$sql = mysql_query("SELECT PART_ID, PART_DESC, SERIAL_NUM, PART.RACK_NUM, PART.PART_TYPE_ID, PART_TYPE_DESC, LOCATION
FROM PART
INNER JOIN PART_TYPE ON PART.PART_TYPE_ID = PART_TYPE.PART_TYPE_ID
INNER JOIN RACK ON RACK.RACK_NUM = PART.RACK_NUM
This will get all the rows from the PART table, and for each of the rows we find, match that row to a row in the PART_TYPE table (the condition being that they have the same PART_TYPE_ID). If no match between the PART and PART_TYPE tables can be found for a given row in the PART table, that row will not be included in the result.
My Insert Query This is where im having trouble
How do I add the data to the PART_ID, PART_TYPE and RACK tables?
<?php
// Parse the form data and add inventory item to the system
if (isset($_POST['PART_ID'])) {
$id = mysql_real_escape_string($_POST['PART_ID']);
$PART_DESC = mysql_real_escape_string($_POST['PART_DESC']);
$SERIAL_NUM = mysql_real_escape_string($_POST['SERIAL_NUM']);
$RACK_NUM = mysql_real_escape_string($_POST['RACK_NUM']);
$PART_TYPE_ID = mysql_real_escape_string($_POST['PART_TYPE_ID']);
$LOCATION = mysql_real_escape_string($_POST['LOCATION']);
$PART_TYPE_DESC = mysql_real_escape_string($_POST['PART_TYPE_DESC']);
// See if that product name is an identical match to another product in the system
$sql = mysql_query("SELECT PART_ID FROM PART WHERE PART_ID='$id' LIMIT 1");
$productMatch = mysql_num_rows($sql); // count the output amount
if ($productMatch > 0) {
echo 'Sorry you tried to place a duplicate "Product Name" into the system, click here';
exit();
}
// Add this product into the database now
**$sql = mysql_query("INSERT INTO PART (PART_ID, PART_DESC, SERIAL_NUM, RACK_NUM, PART_TYPE_ID)
VALUES('$id','$PART_DESC','$SERIAL_NUM','$RACK_NUM','$PART_TYPE_ID')") or die (mysql_error());**
header("location: inventory_list.php");
exit();
}
?>
Micheal if I understood your problem you just need to do 2 other SQL INSERT to add data in the other table
$sql = mysql_query("INSERT INTO PART (PART_ID, PART_DESC, SERIAL_NUM, RACK_NUM, PART_TYPE_ID)
VALUES('$id','$PART_DESC','$SERIAL_NUM','$RACK_NUM','$PART_TYPE_ID')") or die (mysql_error());
$currentID = mysql_inserted_id();
$sql2 = mysql_query("INSERT INTO PART_TYPE [..]");
$sql3 = mysql_query("INSERT INTO RACK [..]");
You can use $currentID if you need the ID of the last record inersted into PART
But still I strongly suggest you to learn PDO http://php.net/pdo for sql
your table management is wrong, you never use arrows just to show that you are joining it with that table from this table, but rather from the key in first table to foreign key in the second table, that's what i would start from, maybe a better idea would be to join them using JOIN look up in google how joins are working, that may be the cause...
I agree with #yes123, that is the correct way to insert into tables, if you have a program called heidisql then use it, because there is a window to run your queries... that way to test if it is properly written also use mysql_error.
Debug, debug, and one more time debug your code.
Your tables are not correctly designed.
Try this table structures .
In your base table Part. -
The columns in this should be:
Part_id
part_desc
serial_num
The part_type should have following columns:
part_type_id
part_type_desc
part_id -> foreign key to the parent table
The rack table should be:
Rack_num
location
part_id -> foreign key to the parent table.
So your select query to get all the part related information would be:
$sql="select * from part join part_type pt on tp.part_id=part.part_id join Rack_num rn on rn.part_id=part.part_id";
With this structure the data remains normalized. And is flexible, so if the parts are on multiple racks you just go to the rack table and add and new rack number and the part id.