PHP UNIQUE user movie rating - php

On my site when a user is logged in, they can give a 1-5 rating on a movie.
What I want to do is make it so that database knows which user gave the rating and to update there rating if they click it again rather than creating a new entry, so each user can not have more than one rating per movie.
Tables:
login - id, user, password
movies - id, movie_name, movie_year
user_movie_ratings - id, user_id, movie_id, rating
At the moment when you login, you're taken to a members page the session is checked to ensure you're logged in, and then the list of all the movies is displayed and then when you click the move name you get take to a rating page where you can give it a rating of 1-5, then you are taken back to the movie page and the avg total rating is displayed beside the move name.
The user can just keep doing this over and incorrectly changing the avg rating.
I think I know what I have to do I just dont know how to do it:
Get session user name compare to database user name
Get the id linked to that user name
Post that id with the rating
Use UNIQUE KEY and ON DUPLICATE KEY UPDATE in some way to insure that they can only post once else it gets updated
movie.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<?php
require_once 'sessionCheck.php';
require_once 'init.php';
$movie = null;
if(isset($_GET['id']))
{
$id = (int)$_GET['id'];
$movie = $con->query
("
SELECT movies.id, movies.movie_name, AVG(user_movie_ratings.rating) AS rating
FROM movies
LEFT JOIN user_movie_ratings
ON movies.id = user_movie_ratings.movie_id
WHERE movies.id = {$id}
")->fetch_object();
}
?>
<head>
<title>Movies</title>
</head>
<body>
<div id="wrapper">
<div id="header">
<div id="login">
<?php include 'loginCheck.php';?>
</div>
</div>
<div class="content">
<?php if ($movie): ?>
<div class="movie">
Movie Name: <?php echo $movie->movie_name; ?>.
<div class="movie_rating">
Rating: <?php echo round($movie->rating); ?>/5
</div>
<div class="movie-rate">
Rate this movie:
<?php foreach(range(1, 5) as $rating): ?>
<?php echo $rating; ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
</div>
<div id="footer"> This is the Footer</div>
</div>
</body>
</html>
rate.php
<?php
require_once 'init.php';
if(isset($_GET['movie'], $_GET['rating'])) {
$movie = (int)$_GET['movie'];
$rating = (int)$_GET['rating'];
if(in_array($rating, array(1, 2, 3, 4, 5))) {
$exists = $con->query("SELECT id FROM movies WHERE id = {$movie}")->num_rows ? true : false;
if ($exists) {
$con->query("INSERT INTO user_movie_ratings (movie_id, rating) VALUES ({$movie}, {$rating} )");
}
}
header('Location: movie.php?id=' . $movie);
}
login
<!doctype html>
<html>
<body>
<p>Register</p>
<form action="" method="POST">
Username: <input type="text" name="user"><br />
Password: <input type="password" name="pass"><br />
<input type="submit" value="Login" name="submit" />
</form>
<?php
if(isset($_POST["submit"])){
if(!empty($_POST['user']) && !empty($_POST['pass']))
{
$user=$_POST['user'];
$pass=$_POST['pass'];
require_once 'init.php';
$query=mysql_query("SELECT * FROM login WHERE username='".$user."' AND password='".$pass."'");
$numrows=mysql_num_rows($query);
if($numrows!=0)
{
while($row=mysql_fetch_assoc($query))
{
$dbusername=$row['username'];
$dbpassword=$row['password'];
}
if($user == $dbusername && $pass == $dbpassword)
{
session_start();
$_SESSION['sess_user']=$user;
/* Redirect browser */
header("Location: member.php");
}
}
else
{
echo "Invalid username or password!";
}
}
else
{
echo "All fields are required!";
}
}
?>
</body>
</html>

I'll list the steps you need to undertake in order to achieve what you want.
Store the USER_ID to the session along with their username (or any other data). Do not store username and then query every time to obtain their ID. That makes no sense
Add a unique key (user_id, movie_id) and this is the fun step - do not perform any kind of checks, just insert the data. If the user has voted for the movie, the key will be there and the insert will fail. In PHP this will be interpreted as an exception and that's what you want
Catch the exception in case of failure and notify the user they have already voted.
Use prepared statements to avoid any potential SQL injections and to speed things up (MySQL plays nicely with performance and prepared statements)
Overall, you can reduce your logic and your code if you follow these steps.

Related

PHP Delete Form Not Deleting With no Errors

The form is supposed to delete a customer row from the customer table by entering customer ID, but it is not doing what it is supposed to, I dont know why! When I executed the PHP file I dont get any errors.
I know it should work because I used the same code to delete information from the employee table and it worked fine.
Delete Customer Form
<!DOCTYPE html>
<head>
<?php include 'project_header.php'; ?>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<form action="customer_delete.php" method="post">
<h2> Delete a Customer</h2>
<p>Please Enter Customer Information:</p>
Customer ID: <input type="text" ID="Customer_ID"/><br>
<input type="submit" value= "Delete"/><input type="reset"/>
</form>
</body>
<?php include 'project_footer.php'; ?>
</html>
Delete Customer PHP
<!DOCTYPE html>
<html>
<?php include 'project_header.php'; ?>
<body>
<?php
include_once 'db.php';
include_once 'display.php';
#form data
$Customer_ID=$_POST['Customer_ID'];
$sql = "delete from CUSTOMERS where Customer_ID = :Customer_ID;";
$stmt = $conn->prepare($sql);
# data stored in an associative array
$data = array( 'Customer_ID' => $Customer_ID);
if($stmt->execute($data)){
$rows_affected = $stmt->rowCount();
echo "<h2>".$rows_affected." row deleted sucessfully!</h2>";
display("select Customer_ID as Customer ID FROM CUSTOMERS;");
}
else
{
echo "\nPDOStatement::errorInfo():\n";
print_r($stmt->errorInfo());
}
$stmt = null;
$conn = null;
?>
</body>
<?php include 'project_footer.php'; ?>
</html>
It seems that there is no name attribute on your text box. This is how PHP gets the POST information, so without it being set, you can't access what the user inputted. Simply change the attribute from ID to name(or just add the name attribute if id is needed) and that should fix the issue.
Customer ID: <input type="text" ID="Customer_ID"/>
In this line you need to add the "name" attribute, and that should fix the issue.
What you should do is:
Customer ID: <input type="text" ID="Customer_ID" name="Customer_ID"/>
Greetings!

Share $_POST variables to another page meaning the main page to the ajax response page?

Here's my situation I have a perfect membership system I realized it's been easier to just use a form with some hidden input with predetermined values created from previous button clicks from previous pages to send the user id and the other user id aka the other member to other pages which the post data becomes variables eventually in each page deeper in each code document which are eventually use in SQL statements. My method has been working but now I have a new problem now I have a private messaging system page where users can send private messages to each other so I found this really cool script which I later semi modify it to work on my membership system but it consist of two main pages that are used to make it work completely the first page consist of pretty much the private messaging system primary components the second page aka chat.php is a AJAX response page designed to show new messages. So how can I share the main page post data variables with the AJAX response page. I tried to put the ajax response page code on the same page of the main page but it looked strange and it gave me strange results. Note in this situation the partner_id is aka the other user id and since the first include of each page consist of the login member id already aka messenger_id it's just the other user id i'm concern of aka the partner_id and just know that the SQL column call message belongs to the messenger_id the partner_id in the SQL database is designed to show who the login member aka messenger_id talked to (partner_id) Here's the code
MAIN PAGE
<?php
include("0/instructions/php/session.php");
$messenger_id = $user_id;
$partner_id= $_POST['partner_id'];
?>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width">
<meta charset="UTF-8">
<title>Chat System in PHP</title>
<link rel="stylesheet" href="style.css" media="all"/>
<script>
function ajax() {
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4 && req.status == 200) {
document.getElementById('chat').innerHTML = req.responseText;
}
}
req.open('GET', 'chat.php', true);
req.send();
}
setInterval(function() {
ajax()
}, 1000);
</script>
</head>
<body onload="ajax();">
<div class="main_container">
<div id="container">
<div id="chat_box">
<div id="chat"></div>
</div>
</div>
<form method="post" action="">
<input type="text" name="messenger_id" placeholder="messenger_id" value="<?php echo $messenger_id; ?>"/>
<textarea name="message" placeholder="enter message"></textarea>
<input type="text" name="partner_id" placeholder="partner_id" value="<?php echo $partner_id; ?>"/>
<input type="submit" name="submit" value="Send it"/>
</form>
<?php
if(isset($_POST['submit'])) {
$messenger_id = $_POST['messenger_id'];
$message = $_POST['message'];
$partner_id = $_POST['partner_id'];
$query = "INSERT INTO messages_x (messenger_id,message,partner_id) values ('$messenger_id','$message','$partner_id')";
$run = $connect->query($query);
if($run) {
echo "<div id='hide_audio'><embed loop='false' src='chat.mp3' hidden='true' autoplay='true'/></div>";
}
}
?>
</div>
</body>
</html>
THE AJAX RESPONSE PAGE AKA CHAT.PHP
<?php
include("0/instructions/php/session.php");
$messenger_id = $user_id;
$partner_id = $_POST['partner_id'];
$query= "SELECT * FROM messages_x WHERE messenger_id='$messenger_id' AND partner_id='$partner_id' ORDER BY messenger_id DESC";
$run = $connect->query($query);
while($row = $run->fetch_array()) :
$messenger_id = $row['messenger_id'];
?>
<div id="chat_data">
<span style="color:green;"><?php echo $row['messenger_id']; ?></span> :
<span style="color:brown;"><?php echo $row['message']; ?></span>
<span style="float:right;"><?php echo formatDate($row['date']); ?></span>
</div>
<?php
endwhile;
$query_other= "SELECT * FROM messages_x WHERE messenger_id='$partner_id' AND partner_id='$messenger_id' ORDER BY messenger_id DESC";
$run_other = $connect->query($query_other);
while($row_other = $run->fetch_array()) :
?>
<div id="chat_data">
<span style="color:gold;"><?php echo $row_other['messenger_id']; ?></span> :
<span style="color:purple;"><?php echo $row_other['message']; ?></span>
<span style="float:right;"><?php echo formatDate($row_other['date']); ?></span>
</div>
<?php
endwhile;
In this example the hidden form inputs are shown for simple explanation here and as a result I want it to look like this.

PHP session_id() being overridden

I really don't know how to describes this, but here goes. I'm trying to make a Login for an online multiplayer game (cluedo to be exact) that is written using mainly the LAMP stack (php,js,etc), and creating a session when someone logs in/registers works for me and all and I even save it to a sql database, but it seems that as soon as a next user Logs in/registers the session id to the previous user is overridden to the new ones details. In other words they both now have the same session for some reason.
My Game LogIn basically:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="StyleSheet.css">
<meta charset="UTF-8">
<title>Game Setup</title>
</head>
<body>
<header>
<h1>Game Setup</h1>
</header>
//My form for user details and character select
<form name="Registration" id=Form1 action="Lobby.php" method="POST">
<fieldset>
<legend>Player information:</legend>
<label for="Pid">Player Name(required): </label><br>
<input autofocus type="text" id="Pid" name="Pid" placeholder="Player ID" required><br>
<label for="Avatar">Character(required):</label><br>
<select name="Avatar">
<option value="Miss White">Miss White</option>
<option value="Col Mustard">Col Mustard</option>
<option value="Miss Scarlet">Miss Scarlet</option>
<option value="Mr Green">Mr Green</option>
<option value="Madame Plum">Madame Plum</option>
<option value="Benjamin Blue">Benjamin Blue</option>
</select><br><br>
<input type="submit" value="Register">
</fieldset>
</form>
</body>
and the lobby (where I wait for someone to press game start or for more people to register)
<?php
session_start() ;
session_regenerate_id();
$_SESSION["UserName"]=$_POST['Pid'];
$_SESSION["Avatar"]=$_POST['Avatar'];
?>
<?php require 'DatabaseConnect.php' ?>
<?php include 'Users.php' ?>
<?php
$PlayerID = mysqli_real_escape_string($conn, $_POST['Pid']);
$PlayerChar = mysqli_real_escape_string($conn, $_POST['Avatar']);
$SesID = session_id();
$sql = "INSERT INTO users (UserName, Avatar, sessionID)
VALUES ('$PlayerID', '$PlayerChar','$SesID')";
if ($conn->query($sql) === TRUE) {
echo "Welcome $PlayerID , currently in Lobby: <br>";
$User = new Users();
$User->setUserName($_SESSION['UserName']);
$User->setAvatar( $_SESSION['Avatar']);
$User->isPlaying = false;
$_SESSION['User'] = serialize($User);
?>
<html>
<body>
<div id="Players"> </div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src ="Display.js"></script>
</body>
</html>
<?php
}
else {
if($conn->errno == 1062){//when a userName or Character already in use
$sql = "SELECT * FROM users";
$result = $conn->query($sql);
$sql = "ALTER TABLE users AUTO_INCREMENT = ".$result->num_rows;
$conn->query($sql);
echo "<script type='text/javascript'>alert('ERROR :Username or Character already in use!')</script>";
echo" <script>
window.location = 'LogIn.php';
</script>";
}
}
?>
and then the Display.js runs in a loop until either 6 people connect or a user presses start. It also displays everyone currently waiting for a game by outputting the SQL database, but I don't think that code is necessary to add, but then when that's done I go to the Cluedo.php page and if I echo session_id() there on two different browsers(same machine) I get the same session_id()
<?php
session_start() ;
?>
<?php require 'DatabaseConnect.php' ?>
<?php include 'Users.php' ?>
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="StyleSheet.css">
<meta charset="UTF-8">
<title>Cluedo</title>
</head>
<body>
<?php
$User = unserialize($_SESSION['User']);
echo session_id();
?>
</body>
</html>
Also I'm using XAMPP and running it all locally at the moment so don't know if there's a problem there maybe?
Here's an example of my database with the saved values, the table saves unique sessions however when the session_id() is echoed at the Cluedo.php page it is always the last registered user:
UserTable

Delete button for SQL

I have a member/account site that posts "notes" and saves them in your account. When someone post's a note, each note gets an edit and a delete button. I want the delete button to delete the corresponding post, however its deleting whichever note is on top. I assume the problem lies within either the else when the delete button is pressed or during the while when the button is created. Wouldn't I need a way to assign the buttons an id?
Thanks in advance.
<!-- connections.php connects to the database -->
<?php require 'connections.php'; ?>
<!-- check to make sure the user is logged in,
if not then redirect them to login.php -->
<?php session_start();
if(isset($_SESSION["UserID"])){
} else {
header('Location: Login.php');
die();
}?>
<!-- $result is a query containing all the notes
of the current user -->
<?php $UserID = $_SESSION["UserID"];
$result = mysqli_query($con, "SELECT * FROM notes WHERE UserID = '$UserID'");
?>
<!-- when you click 'save' upload the new note
to the database and refresh the page.
when you click 'delete' remote the note
that goes with that button from the database -->
<?php if(isset($_POST['save'])) {
session_start();
$note = $_POST['note'];
$UserID = ($_SESSION["UserID"]);
$sql = $con->query("INSERT INTO notes (UserID, note)Values('{$UserID}','{$note}')");
header('Location: Account.php');
} else if (isset($_POST['delete'])){
$result = mysqli_query($con, "SELECT * FROM notes WHERE UserID = '$UserID'");
$row = mysqli_fetch_array($result);
$noteID = $row['noteID'];
$UserID = ($_SESSION["UserID"]);
$sql = $con->query("DELETE FROM notes WHERE noteID = '$noteID'");
header('Location: Account.php');
} else if (isset($_POST['edit'])){
}?>
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>My Account</title>
<link rel="stylesheet" type="text/css" href="stylesheet.css">
</head>
<body>
<h1 class="titleAct">Welcome</h1>
<form action="" method="post" name="notesubmit" id="notesubmit">
<div>
<textarea name="note" cols="50" rows="4" form="notesubmit" id="noteinput">New Note
</textarea>
</div>
<input name="save" type="submit" class="button" id="save" value="Save">
<!-- Whenever a note is saved, print out the
note with timestamp followed by the edit
and delete buttons for each note -->
<?php while ($row = mysqli_fetch_array($result)): ?>
<?php $note = $row['note'];?>
<?php $date = $row['time'];?>
<div id="note">
<p class="note"><?php echo $date; ?></br> ---------------- </br><?php echo $note; ?></p>
</div>
<input name="edit" type="submit" class="button" id="edit" value="Edit">
<input name="delete" type="submit" class="button" id="delete" value="Delete">
<?php endwhile; ?>
</form>
<div>
<a class="link" href="Logout.php">Logout</a>
<div>
<a class="link" href="Deactivate.php">Deactivate My Account</a>
</div>
</div>
</body>
</html>
You have a logical error... Your not sending back the ID of the note you want to delete anywhere, you just say you want to delete something, then fetches the list of notes from the database, and deletes the first that pops in...
What I would do, is change the delete button to a link, and sett a query parameter ($_GET['noteID']) to select which ID to delete...
Then I would select the NoteID from the database, but also make sure the user tries to delete his own post, and not someone elses...
Good luck :)

How do you return login form errors to the same page using PHP?

I'm relatively new to PHP and have exhausted the internet trying to find an answer to this problem. I've looked at countless examples but people seem to very different login systems to mine and I have trouble deciphering it.
Here is my code so far:
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Video for Education Log In</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="wrapper">
<div id="header">
<div id="logo">
videoedu.edu </div>
<div id="menu">
<ul>
<li>Create Account</li>
<li>About Us</li>
</ul>
</div>
</div>
<br><br><br><br>
<div id="page">
<div id="content">
<h2>Video for Education helps you connect and share with the videos in your life.</h2>
<h3>Upload Share Create Using video for your education purposes. Lecturers Welcome
Upload Share Create Using video for your education purposes. Lecturers Welcome
Upload Share Create Using video for your education purposes. Lecturers Welcome</h3>
<div class= "form">
<form name="login" method="post" action="checklogin.php">
Username: <input type="text" name="myusername" id="myusername" class="textb"/><br />
Password : <input type="password" name="mypassword" id="mypassword" class="textb"/><br />
<br>
<input type="submit" name="login" value="Login" id="login" class="texta" />
</form>
</div>
</div>
</div>
</div>
</body>
</html>
checklogin.php
<?php
$host = "localhost";
$username = "root";
$password = "";
$db_name = "test";
$tbl_name = "members";
mysql_connect("$host", "$username", "$password")or die("Cannot connect.");
mysql_select_db("$db_name")or die("Cannot select DB.");
$myusername=$_POST["myusername"];
$mypassword=$_POST["mypassword"];
if ($myusername&&$mypassword)
{
$myusername = stripslashes($myusername);
$mypassword = stripslashes($mypassword);
$myusername = mysql_real_escape_string($myusername);
$mypassword = mysql_real_escape_string($mypassword);
$sql = "SELECT * FROM $tbl_name WHERE username='$myusername' and password='$mypassword'";
$result = mysql_query($sql);
$count = mysql_num_rows($result);
if($count == 1){
session_register("myusername");
session_register("mypassword");
header("location:login_success.php");
}
else
{
echo "Wrong Username or Password";
}
}
else
echo "You have left one or more fields blank.";
?>
login_success.php
<?
session_start();
if( !isset( $_SESSION['myusername'] ) ){
header("location:account.html");
}
echo "Welcome, ".$_SESSION['myusername']." - You are now logged in.<br>";
echo "<a href=logout.php>Logout</a>"
?>
<html>
<body>
</body>
</html>
logout.php
<?php
session_start();
session_destroy();
echo "You have been logged out, <a href='index.php'>click here</a> to return."
?>
I have tried inserting this into index.html and changing the file name to index.php.
$submit = $_POST["login"];
if($submit)
{
}
...but it just constantly displays one of the errors ('Wrong username or password') down the bottom of the page at all times.
I want it so that if the user enters a wrong username or password, or leaves a required field blank, the error will pop up on the same page, instead of going to a new ugly, blank PHP page with the error message in the top left-hand corner.
In checklogin.php, instead of echoing an error, use this:
die(header("location:index.html?loginFailed=true&reason=password"));
or something similar, and in your index.html page, just have PHP generate the HTML message, something like this:
<input type="submit" name="login" value="Login" id="login" class="texta" /><br /><br />
<?php $reasons = array("password" => "Wrong Username or Password", "blank" => "You have left one or more fields blank."); if ($_GET["loginFailed"]) echo $reasons[$_GET["reason"]]; ?>
</form>
Also, make sure to die() or exit() when you use header to redirect the page, otherwise the rest of your script continues to run.
What you can do is, redirect back to your page if data is invalid. Put errors into session and display them on page:
e.g.:
<?php if(isset($_SESSION['Login.Error']) { echo $_SESSION['Login.Error'];
unset($_SESSION['Login.Error']); } ?>
<form ....
and your error will be visible on page.
In your PHP
$_SESSION["Login.Error"] = 'Invalid credentials';//redirect back to your login page
In checklogin.php, if the user enters a wrong username or password, use the code like this:
echo "<script language=\"JavaScript\">\n";
echo "alert('Username or Password was incorrect!');\n";
echo "window.location='login.php'";
echo "</script>";
It will pop up the error message at the same page (login page), instead of going to a blank PHP page.
You would want to make your index.html page a PHP page, and have the form submit to itself, i.e. to index.php. In this way, you your index page can do the login check for the form values and display the output of the page appropriately, or use headers to redirect if everything validates.
It's hard to tell the effect that your attempt may have had without seeing it in the full context, but the gist of the situation is you need the form to submit to itself and handle it's login processing.
It looks like you want/need to integrate it with jQuery or some other Javascript/AJAX library
to make things more presentable. jQuery has an plugin for form validation that's is very easy to integrate to your project (obviously jQuery library is minimum requirement).
jQuery site and
jQuery validation plugin.
You may also consider using a PHP Framework like CodeIgniter which is also has a very helpful form validation library. CodeIgniter is scary at the beginning (like all MVC based programming library/framework) but it's worth it. you can watch some tutorials on netTuts+ they've created a series of tutorials called CodeIgniter From Scratch, is not from the latest version but is easy to adapt.

Categories