I am trying to write a forum-like application where users can add comments (saved in database) and attach up to 3 files to each comment.
// SQL query to SELECT comments from database
// Echo out all comments
foreach ($resultCom as $row) {
echo $commentContent;
// Echo out up to 3 files for each comment
if (isset($commentFile1) {
echo "<a class='file-download' href='upload/$commentFile1'>$commentFileName1</a>";
}
if (isset($commentFile2) {
echo "<a class='file-download' href='upload/$commentFile2'>$commentFileName2</a>";
}
if (isset($commentFile3) {
echo "<a class='file-download' href='upload/$commentFile3'> $commentFileName3</a>";
}
}
Now I want to give the user the possibility to delete each of the files in their comment which means I need to write a delete form for each file in each comment:
<form action="delete_file.php" method="post">
<input name="id">
<input name="filename">
...
<button type="submit" name="delete-submit">Delete</button>
</form>
This same <form> would exist many times, using the same name attributes for inputs/submit buttons. If I use JavaScript to loop through every file and give each input field an unique name, I would still end up having one button that submits the information to my action="delete_file.php" which is then caught and processed in delete_file.php with something like:
if(isset($_POST['delete-file-submit'])) { delete files/update database}
I've tried a couple of approaches and each of them failed. A hint how I would set up a delete form for each of the files using their unique attributes (filename, file id, etc.) would be much appreciated.
The best way to do it. Is to use an AJAX, but if this must be in PHP here you go:
<?php
if (isset($_POST['filename'])) {
$name = $_POST['filename'];
$id= $_POST['id'];
//Direction where you store your files
$target_dir = "/";
// If u store it by name then do this:
$target_file = $target_dir . $name;
// If you store it by id then do this:
// $target_file = $target_dir . $id;
if (file_exists($target_file)) {
if(unlink($target_file)){
echo "File". $name ." was removed.";
}else{
echo "Error!". $name . "was not removed";
}
}else{
echo "Could not find file". $name;
}
}
?>
Of course it depends how do you store your data, but if it is in this same directory this is the way.
AJAX function would like like this, but you have to do some changes to fit it in your code:
const deleteFiles = (id, filename) => {
//Ask if your user wants to delete file
let confirmDelete = confirm("Are you sure you want to delete " + filename + "?");
//If yes, its doing this
if(confirmDelete){
$.post("php/deleteFile.php",
{
id: id,
filename: filename
},
function(response){
alert(response);
}
);
}
};
My idea is to create strucutre of element like this:
<div data-name="name" data-id="id">
<a>IMAGE HERE</a>
<button class="delete-file">DELETE</button>
</div>
Then search for every element with class .delete-file and set on it listener for click like this:
document.find(".deleteFile").click(function(){
deleteFile(this.parent().dataset.id, this.parent().dataset.name);
});
If you will have any problems, or dont undestand sth, let me now.
Small edit: As it was said in comments, you will need additional sanitazer for your filename to stay safe, without injections. Here is the simple one (if you will need more advanced one, you should look for it in web) :
$name = mb_ereg_replace("([^\w\s\d\-_~,;\[\]\(\).])", '', $name );
Related
I realize that there are several similar questions that have been asked, but none of those have been able to get me over the top. Maybe what I wnat to do is just not possible?
I have a page on which there is an order form. The admin can create an order for any user in the database by selecting them in the dropdown menu and then fill out the form. But each user may have a PriceLevel that will give them a discount. So I need to be able to make a database call based on the username selected in the dropdown and display their price level and be able to use the username and pricelevel variables in my PHP.
I have the an add_order.php page on which the form resides, and an ajax.php which makes a quick DB call and returns the results in a json format.
The problem I am running into is actually getting the information from jQuery into the PHP. I have tried using the isset method, but it always comes back as false.
Here's what I have:
add_order.php
<?php
// $username = $_POST['orderUser']['Username'];
$username = isset($_POST['orderUser']) ? $_POST['orderUser']['Username'] : 'not here';
echo 'hello, ' . $username;
?>
...
$('#frm_Username').change(function() {
orderUser = $(this).val();
$.post('/admin/orders/ajax.php', {
action: 'fetchUser',
orderUser: orderUser
}
).success(function(data) {
if(data == 'error') {
alert('error');
} else {
console.log(data);
}
})
})
ajax.php
<?php
$action = $_POST['action'];
if($action == "fetchUser"):
$un = $_POST['orderUser'];
/*if($un):
echo $un;
exit;
endif;*/
// SET THE REST UP WITH MYSQL
if($un):
$qid = $DB->query("SELECT u.Username, u.PriceLevel FROM users as u WHERE u.Username = '" . $un . "'");
$row = $DB->fetchObject($qid);
// $row = jason_decode($row);
echo json_encode($row);
exit;
endif;
echo "error";
endif;
?>
I am logging to the console right now and getting this:
{"Username":"dev2","PriceLevel":"Tier 2"}
Any help would be appreciated. Thanks.
After calling $.post('/admin/orders/ajax.php', ...), the PHP code which sees your POSTed variable is ajax.php.
You need to check in there (inside ajax.php), whereas currently your isset check is in add_order.php, which does not see the POST request you send.
You do seem to have some logic in ajax.php, but whatever you've got in add_order.php is not going to see the data in question.
I have a downloads section on a client wordpress site. Using Download Monitor plugin. They are protected with a form using the Ninja Forms addon for the DM plugin so users have to register details to access the download.
I'd like to add the ID from the download form URL to a field in the form so client can see which download that form registration is associated with.
The generated url of the unlock registration form for a particular download is similar to the following:
https://domain.com/no-access/download-id/572/
I have found how to do this with a query string ( https://ninjaforms.com/how-to-auto-populate-form-fields-using-query-string/ ) but not sure how to do it with the IDs in my url above.
Ideally I'd like to translate that ID to the actual download title too if that's possible.
Can anyone please advise?
Thanks!
If the id is always at the end of the url that way, you can use basename to grab it very simply:
<?php
// in your code you will do this:
//$url = $_SERVER['REQUEST_URI'];
// but for this example, i need your url:
$url = 'https://domain.com/no-access/download-id/572/';
// grab the basename:
$id = basename($url);
echo "($id)"; // (572)
ADDITION
Now that you can find that $id which is the download-id requested, put it in a variable that you can use within the code that is writing your ninja form. For instance:
$url = $_SERVER['REQUEST_URI'];
// this was just for debugging...now comment it out
// $url = 'https://domain.com/no-access/download-id/572/';
// echo "($id)"; (572)
$id = basename($url);
// instead put it in a variable you can use in your form
$GLOBALS['requested-download-id'] = (integer) $id;
Now wherever you have the code for your ninja form do something like this:
<form id="ninja-form" action="your-action" method="POST">
<?php
// sanity check...something may have gone wrong
if (empty($GLOBALS['requested-download-id'])) {
$download_id = 'NOT FOUND';
} else {
$download_id = $GLOBALS['requested-download-id'];
}
?>
<input value="<?php echo $download_id; ?>" type="hidden" name="download-id">
EVEN MORE SIMPLIFIED - DO IT ALL AT ONCE
<form id="ninja-form" action="your-action" method="POST">
<?php
$id = basename($_SERVER['REQUEST_URI']);
// be sure you ended up with a number
$id = (integer) $id;
if (empty($id)) {
$download_id = 'NOT FOUND';
} else {
$download_id = $id;
}
?>
<input value="<?php echo $download_id; ?>" type="hidden" name="download-id">
I'm trying to create a comment system on my website where the user can comment & see it appear on the page without reloading the page, kind of like how you post a comment on facebook and see it appear right away. I'm having trouble with this however as my implementation shows the comment the user inputs, but then erases the previous comments that were already on the page (as any comments section, I'd want the user to comment and simply add on to the previous comments). Also, when the user comments, the page reloads, and displays the comment in the text box, rather than below the text box where the comments are supposed to be displayed. I've attached the code. Index.php runs the ajax script to perform the asynchronous commenting, and uses the form to get the user input which is dealt with in insert.php. It also prints out the comments stored in a database.
index.php
<script>
$(function() {
$('#submitButton').click(function(event) {
event.preventDefault();
$.ajax({
type: "GET",
url: "insert.php",
data : { field1_name : $('#userInput').val() },
beforeSend: function(){
}
, complete: function(){
}
, success: function(html){
//this will add the new comment to the `comment_part` div
$("#comment_part").append(html);
}
});
});
});
</script>
<form id="comment_form" action="insert.php" method="GET">
Comments:
<input type="text" class="text_cmt" name="field1_name" id="userInput"/>
<input type="submit" name="submit" value="submit" id = "submitButton"/>
<input type='hidden' name='parent_id' id='parent_id' value='0'/>
</form>
<div id='comment_part'>
<?php
$link = mysqli_connect('localhost', 'x', '', 'comment_schema');
$query="SELECT COMMENTS FROM csAirComment";
$results = mysqli_query($link,$query);
while ($row = mysqli_fetch_assoc($results)) {
echo '<div class="comment" >';
$output= $row["COMMENTS"];
//protects against cross site scripting
echo htmlspecialchars($output ,ENT_QUOTES,'UTF-8');
echo '</div>';
}
?>
</div>
insert.php
$userInput= $_GET["field1_name"];
if(!empty($userInput)) {
$field1_name = mysqli_real_escape_string($link, $userInput);
$field1_name_array = explode(" ",$field1_name);
foreach($field1_name_array as $element){
$query = "SELECT replaceWord FROM changeWord WHERE badWord = '" . $element . "' ";
$query_link = mysqli_query($link,$query);
if(mysqli_num_rows($query_link)>0){
$row = mysqli_fetch_assoc($query_link);
$goodWord = $row['replaceWord'];
$element= $goodWord;
}
$newComment = $newComment." ".$element;
}
//Escape user inputs for security
$sql = "INSERT INTO csAirComment (COMMENTS) VALUES ('$newComment')";
$result = mysqli_query($link, $sql);
//attempt insert query execution
mysqli_close($link);
//here you need to build your new comment html and return it
return "<div class='comment'>...the new comment html...</div>";
}
else{
die('comment is not set or not containing valid value');
}
The insert.php takes in the user input and then inserts it into the database (by first filtering and checking for bad words). Just not sure where I'm going wrong, been stuck on it for a while. Any help would be appreciated.
html() in your function replacing current html with your comment html, thats why u see only new comment. Change your method to append().
$("#comment_part").append(html);
Change this line
$("#comment_part").html(html);
to this
$("#comment_part").html('<div class="comment" >' + $('#userInput').val() + '</div>' + $("#comment_part").html()).promise().done(function(){$('#userInput').val('')});
I have a remove page where it can remove an entry from my database which is pre loaded into the option box. However, it redirects to my 'remove-module-complete.php' page when I type in any random text. I only want it to direct to the 'remove-module-complete.php' if their is that actual entry from the database. My javascript doesn't seem to be working.
I currently have some validation to say that the entry 'didnt match any item' from jQuery but it still directs me to 'module remove complete' if I press submit.
Any help?
Here is my PHP
<?php
if (isset($_POST['submit'])){
$moduleCode = $_POST['moduleCode'];
$moduleCodeLen = strlen($moduleCode);
if ($moduleCodeLen=6){
$sqlTwo = "DELETE FROM MODULES WHERE id = '$moduleCode'";
mysql_query($sqlTwo);
$resTwo =& $db->query($sqlTwo);
if(PEAR::isError($res)){
$errorVar = ($res->getMessage());
echo "<script type='text/javascript'>alert('Invalid entry, please try again. Error code: $errorVar');</script>";
die;
}
else echo "<script> location.replace('http://project.ac.uk/remove-module-complete.php'); </script>";
}
else echo "<script type='text/javascript'>alert('Invalid entry, please try again');</script>";
}
?>
Seems like you have some errors(commented lines):
if (isset($_POST['submit'])) {
$moduleCode = $_POST['moduleCode'];
$moduleCodeLen = strlen($moduleCode);
// '==', not '='
if ($moduleCodeLen==6) {
$sqlTwo = "DELETE FROM MODULES WHERE id = '$moduleCode'";
mysql_query($sqlTwo);
$resTwo =& $db->query($sqlTwo);
// there is no $res variable in the given part of the code
// maybe you need to use $resTwo variable here?
if (PEAR::isError($res)) {
$errorVar = ($res->getMessage());
echo "<script type='text/javascript'>alert('Invalid entry, please try again. Error code: $errorVar');</script>";
die;
}
else echo "<script> location.replace('http://project.ac.uk/remove-module-complete.php'); </script>";
}
else echo "<script type='text/javascript'>alert('Invalid entry, please try again');</script>";
}
I have created a comment-reply system in php. It is similar to wall in facebook. User writes a comment and then post it in "wall". I use the following tables in my database to hold comments: comments(comments_id, comment, comment_date, user, comment_hash, flash) and table users that hold user's details: users(user_id, name, surname). Everything works perfect, the only problem is that I cannot delete a certain comment. Deleting a comment means to set flag=1 for this comment in my database.
On each comment there is a link named "delete". When user press delete, a light box starts in javascript and user by pressing delete, the function "deletepost" is executed. My only problem is that this function sets flag=1 to all comments in my databe and not for the certain comment that I press delete. Any idea how to improve my code?
I use the following function in order to display comments:
<?php
function getComments(){
$session_user_id = $_SESSION['user_id'];
$comments = "";
$sql = mysql_query("SELECT * FROM comments WHERE (`flag`=0) ORDER BY comment_date DESC LIMIT 40") or die (mysql_error());
if(mysql_num_rows($sql) == 0){
$comments = "<div class='each_comment'> Write your first posts ...</div> ";
}
else{
while ($row= mysql_fetch_assoc($sql)) {
$comment_id = $row['comments_id'];
$hash = $row['comment_hash'];
$personal_1 = mysql_query("SELECT `user_id`, `name`, `surname`, `email`, `profile` FROM `users` WHERE `user_id`='{$row['user']}' ");
while ($run_personal_1= mysql_fetch_assoc($personal_1)) {
$comment_user_id = $run_personal_1['user_id'];
$comment_user_name = $run_personal_1['name'];
$comment_user_surname = $run_personal_1['surname'];
}
// displays comment that includes user's name and surname and hash
$comments .= " $comment_user_surname $comment_user_name $hash";
$comments .= ".$row['comment'].";
//---- at this point I insert a delete link , that when user presses it a javascript light box ask user if wants to delete the comment. If user press the delete button it is called the function named "deletepost".
//---- first checks if the comment is from the user that is logged in ($session_user_id) in order to have the right to delete post
if($comment_user_id == $session_user_id){
if(isset($_POST['submit_2'])) {
deletepost($session_user_id, $comment_id);
header('Location: wall.php');
}
$comments .= <<<EOD
<font color='grey' >Delete</font>
<div id="light" class="white_content">
<form action="$_SERVER[PHP_SELF]" method="post">
<input type="submit" name="submit_2" value="Delete Post ">
</form>
<button>Cancel</button>
</div>
<div id="fade" class="black_overlay"></div>
EOD;
}
}
return $comments;
}
?>
I use the following function in order to post comments:
<?php
function postComments($comment){
$comment = mysql_real_escape_string(strip_tags($comment));
$session_user_id = $_SESSION['user_id'];
$random_num = rand(0, 99999999999);
$sql = mysql_query(" INSERT INTO `comments` (comment, comment_date, user, comment_hash) VALUES ('".$comment."', now(), '$session_user_id', '$random_num') ");
return getComments();
}
?>
I use the following function in order to delete comments. Deleting comments means that I set flag=1, and in my function that displays the comments (function getComments), if flag is equal to 1 I do not display this comment:
<?php
function deletepost($comment_user_id, $comment_id){
$get_hash = mysql_query("SELECT `comment_hash` from `comments` WHERE (`user`='$comment_user_id' AND `comments_id` = '$comment_id') ");
while ($run_hash= mysql_fetch_assoc($get_hash)) {
$hash = $run_hash['comment_hash'];
}
$sql="UPDATE `comments` SET `flag`=1 WHERE (`user`='$comment_user_id' AND `comment_hash`='$hash')";
$result=mysql_query($sql) or die("Error when trying to delete...");
}
?>
My first instinct is to guess that comment_hash isn't working quite right, for whatever reason. Try simplifying your delete function:
function deletepost($comment_user_id, $comment_id){
$sql="UPDATE `comments` SET `flag`=1 WHERE (`user`='$comment_user_id' AND `comments_id`='$comment_id')";
$result=mysql_query($sql) or die("Error when trying to delete...");
}
I'm not sure why your current delete function is querying your database to grab a hash from a table and then using the hash to find the same row from the same table. It seems pointless and inefficient, and introduces more things that can break.
Incidentally, Vascowhite is correct that you shouldn't be using the old mysql library, but I don't think changing that would fix your problem here.
In deletepost why did you run while loop to get the hash , if you are deleting one comment one time . Another thing is that flag=1 happens in all your comment because hash may be common for that users all comment . You need to make hash unique for every comment of a particular user .