rmdir() Not Deleting an Empty Folder - PHP - php

I'm currently building a very low level CMS for friend's artist web page that will allow her to upload, edit, and delete images along with designating categories for them and posting news posts about shows and so on.
I'm sure there is a very easy solution to this problem of mine but my inexperience in programming has me left at a loss; so here goes.
The Problem
The problem occurs on a page where the user can delete an image that has been uploaded. Here is the snippet of code where the problem occurs:
// Assign selection to variables in memory...
$img_id = $data["img_name"];
// First, collect the file path to the image being deleted...
$rs = mysql_query("SELECT img_path FROM img_uploads WHERE img_id = '$img_id'") or die(mysql_error());
list($img_path) = mysql_fetch_row($rs);
// Then delete that row from the DB...
mysql_query("DELETE FROM img_uploads WHERE img_id = '$img_id'") or die(mysql_error());
// Now, using the file path collected earlier, delete that file from the server.
unlink($img_path);
// Quickly make sure that the file has been deleted by checking if it exists... if it still exists return error.
if(file_exists($filename)) {
$err[] = "ERROR - There was an error deleting the file! Please try again.";
$_SESSION["errors"] = $err;
header("Location: img_del.php?doDel=failed");
exit();
}
// Scan the directory now that a file has been deleted to see if the dir is empty. If so, delete it. (No use in having empty folders!)
$file_types = array("gif","jpg","png"); // file types to scan for...
$path_parts = pathinfo($img_path); // get the directory from the file path...
$dir = $path_parts["dirname"] . "/"; // assign it to a new variable...
$handle = opendir($dir);
$scan = scandir($dir); // now, scan that directory...
$image_found = FALSE;
for($i=0; $i<count($scan); $i++) {
if ($scan[$i] != '.' && $scan[$i] != '..' && in_array(end(explode('.', $scan[$i])), $file_types)) {
$image_found = TRUE;
}
}
closedir($handle);
if(!$image_found) {
rmdir($dir);
}
I first delete the DB row containing image info, then delete the file from the server. this works fine, however, I also want to check if the directory is left empty after deleting that file. I check if the directory is empty using a loop and if no file is found, I run mkdir(). For some reason it keeps returning an error saying that the directory is not empty
I've searched the web and this site for a solution but I've yet to find one. I'm sure it's out there but I'm having trouble finding it which why I came here. What should I do?
Thanks in advance for any help submitted!
NOTE
I have also checked for hidden files and folders but no luck...
Here is a link to an image that pretty much sums up my problem in a nutshell

Are you sure PHP has permission to delete the file? Since you say you've checked for hidden files, this seems to be the only remaining option. CHMOD 0777 when in doubt (I'd never recommend this usually, but if you're deleting it anyway...), and make sure the folder has the proper owner to let php delete it.

Related

upload file and register it in a database

If there is any mistake in my writing, please excuse me. I'm not very good at translating from Spanish to English.
I am using pluploadQueue, reading the example script (upload.php). I have tested it and it works fine.
In addition to all that, I need to record information about the files that are attached in a database.
I have tried to add the statements that save the information in the database, but it only works halfway. It generates just one entry in my database table.
I notice that in the "upload" directory it generates a 1024kb .part for the 1st file but it doesn't do anything else there. Although visually the Widget tells me that it has uploaded all the files.
I need to save as many entries as files are selected (many can be uploaded, so it has been thought).
Could someone point me to a reference? I have tried to search for something about my problem but I have not been able to find anything.
I use version 2.3.9 of plupload
Correct me if I'm wrong, but I'm understanding that the upload.php script is executed (or should be) for each file to be uploaded, right?
My logic is such that:
Insert into db basic "header" information for the first time. In the following operations it is recovered.
plupload upload routine
Insert in db file information
thus forming a master-detail relationship bettween 2 tables.
For some reason, it stays at point 2. And this part would not be running:
while (($file = readdir($dir)) !== false) {
$tmpfilePath = $targetDir . DIRECTORY_SEPARATOR . $file;
// If temp file is current file proceed to the next
if ($tmpfilePath == "{$filePath}.part") {
continue;
}
// Remove temp file if it is older than the max age and is not the current file
if (preg_match('/\.part$/', $file) && (filemtime($tmpfilePath) < time() - $maxFileAge)) {
#unlink($tmpfilePath);
}
}
closedir($dir);
}
Help me?
EDIT:
Okay. I have found a typo error. I corrected it and now it saves me for each file. What I can't figure out right now is why it has generated hundreds of .part files in the directory instead of overwriting it. And this led to hundreds of records being stored, one for each generated .part.

Remove "Attachments" folder after PHPMailer email is sent

I've got a web form which has a unique upload folder for each user (using their PHP session_id() as the folder name) which works well. When the form is submitted (after error checking) PHPMailer is used to send the email and the attachments. This is also working well. However, after the email is sent, I would like to remove the uploads from the folder and then the folder itself (sort of a self-cleanup!) The files are removed as expected but the folder remains (albeit empty). I wonder if the folder is somehow "still in use" so doesn't get deleted or something similar? This is the code:
// Empty the contents of the upload folder
if (is_dir($dir)) { // Target directory ($dir) is set above in photos POST section
// Check for any files inside the directory
$files = glob($dir.'/*'); // Get all file names
foreach($files as $file) { // Iterate through the files
if(is_file($file)) { // Check its a file
unlink($file); // Delete the file
}
}
// Remove the upload folder
rmdir($dir); //NOT WORKING? NEEDS SOME TROUBLESHOOTING...
}
Any other ideas on why this folder is remaining?
Ben
I would guess that your folders might contain hidden files (starting with .) which the default glob pattern won't match, so try this:
$files = glob($dir . '/{,.}*'); // Get all file names including hidden ones
foreach($files as $file) { // Iterate through the files
if(is_file($file)) { // Check its a file
unlink($file); // Delete the file
}
}
Also check the return value on both unlink and rmdir so you can see exactly where it's failing.
Turns out after much testing that the problem was not actually with rmdir at all! My web form uses a Dropzone for photo uploads to a unique folder for each user using their php session_id() and this folder is supposed to be created when they add a photo to Dropzone (if it doesn’t already exist). Problem was I’d put the folder creation code outside of the actual upload script so the folder was in fact being deleted but them instantly created again when the form submitted and the page reloads! Sorry about that but thanks for all your help. :)

Clarifcation - Delete files which are not in a mySQL TABLE

Delete files which are not in a mySQL TABLE
The link above is to a Stack Overflow question with an answer that is (I believe) pretty close to what I'm looking for. I'm actually just seeking further clarification on the answer given.
The Question
I'm trying to delete files (picture files) in a folder only if they're
not present in a specific database table.
Just like a check of filenames and if they're present in the table
it's ok but if not delete them.
Any ideas how to do that?
The accepted answer
$result = mysql_query("SELECT filename FROM no_delete");
while($row = mysql_fetch_assoc($result)) {
$do_not_delete[] = $row['filename']; }
foreach(glob("*") as $filename) {
if (!in_array($filename, $do_not_delete)) {
//delete them
}
}
I'm not too savvy with PHP, but I don't believe they are specifying a folder path on the server here, are they? I'd like to be able to look inside a specific folder and check whether any images in that folder are within any database tables. If not, delete that image.
Before calling glob("*") just add a line chdir(""). Then you can search whichever directory you want to look at. I just went one level higher in the call below. You may specify whichever directory you want. Before doing a delete, just add an echo statement to $filename to verify if the correct files are being deleted.
chdir("../");
foreach(glob("*") as $filename) {
if (!in_array($filename, $do_not_delete)) {
//delete them
}
As described in this answer the first parameter, i.e. pattern, can contain the path to a directory relative to the current working directory of the script (which can be changed with chdir()) or an absolute path.
Consider this example from this tutorial page:
$dir = "/etc/php5/*";
// Open a known directory, and proceed to read its contents
foreach(glob($dir) as $file)
{
echo "filename: $file : filetype: " . filetype($file) . "<br />";
}

move_uploaded_file() won't replace existing image

I'm using the script below, so user can upload their profile picture. The first time an image is uploaded (when the image doesn't exist at the location) it works great. However, if the image is already exist at the path (if the user tries to change the profile picture) the new image won't replace the old one. I do get success for the query.
Any help would be very appreciated!
Thanks
<?php
ini_set('display_errors',1);
error_reporting(E_ALL);
require_once('db.php');
$name = $_POST['name'];
$dir = '../uploadImages/';
$file = basename($_FILES['image']['name']);
$uploadfile = $dir . $file;
if(move_uploaded_file($_FILES['image']['tmp_name'], $uploadfile))
{
$path = $name;
$path .= 'Image.png';
$query = mysql_query("UPDATE users SET imagePath='$path' WHERE username='$name'");
if ($query)
{
echo 'success';
}
else
{
echo 'error';
}
}
else
{
echo mysql_error();
}
?>
A better way would be un-linking the file if it exists
if(file_exists('your-filename.ext')) {
chmod('your-filename.ext',0755); //Change the file permissions if allowed
unlink('your-filename.ext'); //remove the file
}
move_uploaded_files($_FILES['image']['tmp_name'], 'your-filename.ext');
If move_uploaded_file fails, it returns false. In that case, no SQL is executed at all, so mysql_error, which is echoed in the else branch, indeed won't output an error.
if move_uploaded_file fails, it issues a warning, that will become visible depending on your PHP settings. However, this problem doesn't have anything to do with MySQL.
If you try to explicitly delete the target file first, if it exists. Check with file_exists and then with unlink to delete the file. If unlink fails, it's probably a permissions issue than won't allow you to delete or overwrite the file.
No, your logic is wrong.. take a look at the URL of your profile image, either here, in facebook or twitter..do you see they use a fixed predictable name ? They don't, and there is a very good reason for that, you need unique, unpredictable filenames.
Try this:
$file = hash('sha256', openssl_random_pseudo_bytes(8)) . 'yourallowedextension';
Then query the name of the old picture from your database, after that, upload the new pic, if that succeeds, update the user's profile picture in the database and unlink() the old file using the information previously obtained if any.
Ensure that you are not allowing to upload php files or any other nasty stuff, for that you can use php fileinfo extension.
$file=$_FILES['image']['name'];
$path="your/location/".$file;
if(file_exists($path))
{
chmod($path,0755);
unlink($path);
}
Then move the file using move_uploaded_file().
If you do this, the new image will be replaced:
$sourcePath = $_FILES['image']['tmp_name'];
list($width,$height)=getimagesize($sourcePath);
$uploadedImage = imagecreatefromjpg($sourcePath);
$newImage=imagecreatetruecolor($newWidth,$newHeight);
imagecopyresampled($newImage,$uploadedImage,0,0,0,0,$newWidth,$newHeight,$width,$height);
imagejpeg($newImage, $destinationPath,100);

PHP - upload and overwrite a file (or upload and rename it)?

I have searched far and wide on this one, but haven't really found a solution.
Got a client that wants music on their site (yea yea, I know..). The flash player grabs the single file called song.mp3 and plays it.
Well, I am trying to get functionality as to be able to have the client upload their own new song if they ever want to change it.
So basically, the script needs to allow them to upload the file, THEN overwrite the old file with the new one. Basically, making sure the filename of song.mp3 stays intact.
I am thinking I will need to use PHP to
1) upload the file
2) delete the original song.mp3
3) rename the new file upload to song.mp3
Does that seem right? Or is there a simpler way of doing this? Thanks in advance!
EDIT: I impimented UPLOADIFY and am able to use
'onAllComplete' : function(event,data) {
alert(data.filesUploaded + ' files uploaded successfully!');
}
I am just not sure how to point THAT to a PHP file....
'onAllComplete' : function() {
'aphpfile.php'
}
???? lol
a standard form will suffice for the upload just remember to include the mime in the form. then you can use $_FILES[''] to reference the file.
then you can check for the filename provided and see if it exists in the file system using file_exists() check for the file name OR if you don't need to keep the old file, you can use perform the file move and overwrite the old one with the new from the temporary directory
<?PHP
// this assumes that the upload form calls the form file field "myupload"
$name = $_FILES['myupload']['name'];
$type = $_FILES['myupload']['type'];
$size = $_FILES['myupload']['size'];
$tmp = $_FILES['myupload']['tmp_name'];
$error = $_FILES['myupload']['error'];
$savepath = '/yourserverpath/';
$filelocation = $svaepath.$name.".".$type;
// This won't upload if there was an error or if the file exists, hence the check
if (!file_exists($filelocation) && $error == 0) {
// echo "The file $filename exists";
// This will overwrite even if the file exists
move_uploaded_file($tmp, $filelocation);
}
// OR just leave out the "file_exists()" and check for the error,
// an if statement either way
?>
try this piece of code for upload and replace file
if(file_exists($newfilename)){
unlink($newfilename);
}
move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $newfilename);

Categories