Steven Posted April 2, 2014 Share Posted April 2, 2014 I'm trying to add a simple comments, or notes, system to the job/client manager app I've been working on. I have a viewjob.php page that display a particular job's details based on the jobid in the url. So, http://localhost/job-manager/viewjob.php?jobid=10000 This page displays all the relevant information for the job with id 10,000. And each note that is submitted, needs to be linked with the job it is being submitted to. I have made a new table, "notes". This has the following fields: noteid (primary key), notebody, noteuser, notetime. The ID uniquely id's each individual note, notebody is the body of text that makes up the note itself, noteuser is a foreign key to my "users" table that indicates who wrote the note, and notetime is a current_timestamp to show when the note was posted. I started writing out my prepared statements, placeholders, insert queries and form, but then realized I have a problem. Whether I run the "posting script" on the same page or on something like "insertNote.php", how do I connect the note to the current jobid within "viewjob.php"? Hopefully that makes sense. Link to comment Share on other sites More sharing options...
justsomeguy Posted April 3, 2014 Share Posted April 3, 2014 You need a foreign key to identify the job that the note is for. Link to comment Share on other sites More sharing options...
Steven Posted April 3, 2014 Author Share Posted April 3, 2014 Alright, I added a column "notejob" and made it a foreign key of jobs.jobid. I'm running into a problem, however. It's giving me an error report of "Column 'notejob' cannot be null". Well, in the middle of writing this up, I realized my form's action was "viewjob.php". I had a hunch that my problem was because there was no corresponding jobid=$id appended to the url. I changed the form to this: <form action='viewjob.php?jobid=".$getid."' method='post'> And now it works! Link to comment Share on other sites More sharing options...
Steven Posted April 3, 2014 Author Share Posted April 3, 2014 (edited) There's a bug showing up that is causing comment posts to duplicate whenever the page is reloaded. My code seems like it's a mess right now. Especially the error reporting lines beneath "// POST USER NOTES". I'll just paste everything I have: <?php require('includes/config.php');?><!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>Modern Office | Management System</title> <link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" href="css/foundation.css"></head><body><?php session_start(); // Access the existing session. ?><div class="row"><div class="large-12 columns"> <?php include ('includes/header.php'); ?> <?php include ('includes/navigation.php'); ?></div> <!-- / columns --></div> <!-- / row --> <?php $getid = $_GET['jobid']; // ------- DISPLAY JOB DETAILS ------- if ($stmt = mysqli_prepare($con, "SELECT j.*, c.*, date_format(datein, '%M %d, %Y') AS dates FROM jobs AS j INNER JOIN clients AS c ON j.clientid = c.id WHERE j.jobid = ? ORDER BY j.jobid DESC")) { mysqli_stmt_execute($stmt); // bind param mysqli_stmt_bind_param($stmt, 'i', $getid); // execute mysqli_stmt_execute($stmt); // bind result mysqli_stmt_bind_result($stmt, $clientid, $jobid, $datein, $description, $id, $name, $dates); while (mysqli_stmt_fetch($stmt)) { echo '<div class="row">'; echo '<div class="large-3 medium-3 columns">'; echo '<div class="panel jobText--panel">'; echo '<p><strong>Job ID</strong><br>'; echo $jobid.'</p>'; echo '<p><strong>Client</strong><br>'; echo '<a href="viewclient.php?clientid='.$id.'">'.$name.'</a></p>'; echo '<p><strong>Job Date</strong><br>'; echo $dates.'</p>'; echo '</div>'; // close panel echo '</div>'; // close large-3 column echo '<div class="large-9 medium-9 columns">'; echo '<div class="jobText">'; echo '<h2>Job '.$jobid.'</h2>'; echo '<h3>Description</h3>'; echo '<p>'.$description.'</p>'; echo '<h3>Notes & Conversation</h3>'; } // close stmt mysqli_stmt_close($stmt); } ?> <?php // ------- DISPLAY USER NOTES ------- if ($stmt = mysqli_prepare($con, "SELECT j.jobid, u.userid, u.username, n.* FROM notes AS n INNER JOIN jobs AS j ON n.notejob = j.jobid INNER JOIN users AS u ON n.noteuser = u.userid WHERE n.notejob = ? ORDER BY n.noteid DESC")) { mysqli_stmt_execute($stmt); $notejob = $getid; // bind param mysqli_stmt_bind_param($stmt, 'i', $notejob); // execute mysqli_stmt_execute($stmt); // bind result mysqli_stmt_bind_result($stmt, $jobid, $userid, $username, $noteid, $notebody, $noteuser, $notetime, $notejob); // fetch values while (mysqli_stmt_fetch($stmt)) { echo "<p>".$notebody."</p>"; } } ?> <?php // ------- POST USER NOTES ------- if (isset($_SESSION['userid'])) { // Check for form submission if ($_SERVER['REQUEST_METHOD'] == 'POST') { // Initialize an error array $errors = array(); // Check for a note entry if (empty($_POST['note'])) { // ...send form to the database // Make the query $q = 'INSERT INTO notes (notebody, noteuser, notejob) VALUES (?,?,?)'; // Prepare the statement $stmt = mysqli_prepare($con, $q); // Assign the values to variables $notebody = $_POST['notebody']; $noteuser = $_SESSION ['userid']; $notejob = $getid; // Bind variables mysqli_stmt_bind_param($stmt, 'sii', $notebody, $noteuser, $notejob); // Execute mysqli_stmt_execute($stmt); if (mysqli_stmt_affected_rows($stmt) == 1) { echo "<p>Duly noted, Mr. {$_SESSION ['username']}!</p>"; echo "<p class='small'>(You may need to reload the page to see your freshly crafted note)</p>"; } else { echo '<p>Sadly, the query could not be executed.</p>'; echo '<p>'.mysqli_stmt_error($stmt).'</p>'; } // Close statement mysqli_stmt_close($stmt); if ($q) {// If $q ran with no errors: echo "<h3>Thank you!</h3>"; echo "<p>Your note has been added.</p>"; } else { echo "<h3>Dag-gummit...</h3>"; echo "<p>Something happened, better nag Steve.<p>"; // Debugging message echo "<p>".mysqli_error($con)."</p>"; echo "<p>Query: ".$q."</p>"; } // end of $q IF } else { // Report the errors echo "<div calss='error'>"; echo "<h3>Error!</h3> <p>The following error(s) occured:<br>"; foreach ($errors as $msg) { // Print each error echo " - $msg<br> "; } echo "</p><p>Please try again.</p>"; echo "</div>"; // end error div } // end of (empty($errors)) IF } // end of the main Submit conditional echo "<p class='small'>Hi there, {$_SESSION ['username']}. Want to leave a note? Knock yourself out:</p>"; echo "<form action='viewjob.php?jobid=".$getid."' method='post'>"; echo "<textarea name='notebody' class='textarea--notes'></textarea>"; echo "<p>"; echo "<input type='submit' label='Submit'>"; echo "</form>"; } else { echo "<p>You are not logged in. <a href='login.php'>Go to the login page.</a>.</p>"; } ?></div> <!-- close jobText --></div> <!-- close large-7 column --></div> <!-- close row --></div> <!-- / columns --></div> <!-- / row --></body></html> ---- EDIT ------ Came across this page: http://webprogrammings.net/tutorial/individual_topic/12 I'll give this a try after I fill up my coffee mug and clear my head a bit. Edited April 3, 2014 by Steven Link to comment Share on other sites More sharing options...
Steven Posted April 3, 2014 Author Share Posted April 3, 2014 I'm trying to use "PRG" to avoid duplicate entries after a page refresh, and am having some trouble. I came across this page: http://geekpad.ca/blog/post/avoiding-re-submission-of-forms But where exactly do I put that code? And what part of my code goes where "/* --- process form here --- */" is? Link to comment Share on other sites More sharing options...
justsomeguy Posted April 3, 2014 Share Posted April 3, 2014 What they are calling "PRG" is a method where, after you are finished processing the form, you redirect the user with a location header. Since the user got redirected, if the refresh the page it will not submit the form again, it will refresh the page that they were redirected to. So, after you are finished processing the form, redirect the user. You can redirect them to the same page, that's fine, but you need to redirect if you want to remove the post request from when they hit refresh. Link to comment Share on other sites More sharing options...
Steven Posted April 3, 2014 Author Share Posted April 3, 2014 I think I've got it: // check if post array contains data if (count($_POST) > 1 ) { // Make the query $q = 'INSERT INTO notes (notebody, noteuser, notejob) VALUES (?,?,?)'; // Prepare the statement $stmt = mysqli_prepare($con, $q); // Assign the values to variables $notebody = $_POST['notebody']; $noteuser = $_SESSION ['userid']; $notejob = $getid; // Bind variables mysqli_stmt_bind_param($stmt, 'sii', $notebody, $noteuser, $notejob); // Execute mysqli_stmt_execute($stmt); if (mysqli_stmt_affected_rows($stmt) == 1) { echo "<p>Duly noted, Mr. {$_SESSION ['username']}!</p>"; echo "<p class='small'>(You may need to reload the page to see your freshly crafted note)</p>"; } else { echo '<p>Sadly, the query could not be executed.</p>'; echo '<p>'.mysqli_stmt_error($stmt).'</p>'; } // Close statement mysqli_stmt_close($stmt); if ($q) {// If $q ran with no errors: echo "<h3>Thank you!</h3>"; echo "<p>Your note has been added.</p>"; } else { echo "<h3>Oops</h3>"; echo "<p>There is an error:<p>"; // Debugging message echo "<p>".mysqli_error($con)."</p>"; echo "<p>Query: ".$q."</p>"; } // end of $q IF // prevent re-posting header ('Location: '.$_SERVER['PHP_SELF'], true, 303); exit; } (Sorry about the ugly tabs in these code snippets, they keep getting messed up when I paste them here)... Anyway, I did trial-and-error, and wrapped the query with the "if count($_POST)>1)", and it appears to be working. After I write out a note and hit submit, it prints the success message just fine. When I reload the page, the new note is there. Despite the browser giving me a prompt about resending data, no duplicates are popping up. So, it seems like it is working, but should I be concerned that the browser is still complaining (via the pop-up) about resending data on refresh? Thanks Link to comment Share on other sites More sharing options...
justsomeguy Posted April 3, 2014 Share Posted April 3, 2014 You can't print data and also redirect. The redirect is not happening since you already sent data. If there was an error with the form submission then collect the error messages and print them out when you show the form again. If there were no errors, then redirect to a page that shows the success message. It's the same concept as when you log in here, and it takes you to a page that says thank you for logging in, and then you get redirected again. If it's telling you it is re-sending data then that means it is submitting the post data again. If you were redirecting then it wouldn't say that. Link to comment Share on other sites More sharing options...
Steven Posted April 3, 2014 Author Share Posted April 3, 2014 If I split my form process into different pages, how can I transfer the jobid from viewjob.php to insertComment.php? That is part of why I tried to keep everything on viewjob.php, because the way it knows what job the comment is for, is by grabbing the jobid from the url. Link to comment Share on other sites More sharing options...
justsomeguy Posted April 3, 2014 Share Posted April 3, 2014 Why can't you put the job ID in the URL when they go to the next page? PHP gets data through $_GET, $_POST, or $_COOKIE, and you can also save data in the session. Link to comment Share on other sites More sharing options...
Steven Posted April 4, 2014 Author Share Posted April 4, 2014 Oh, okay. Yeah, that's pretty obvious. Not sure why I thought of that... Thanks! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now