I currently have the function:
function deleteFileUsingID($fileID) {
$this->service->files->delete($fileID);
}
How would I have to modify it such that after deleting the file, if no files exists within that folder, it deletes the folder itself.
I believe your goal as follows.
When there are no files in the specific folder, you want to delete the folder.
In this case, you can check whether the files are in the folder using the method of "Files: list" in Drive API.
Modified script:
Please set the folder ID to $folderId = '###';.
function deleteFileUsingID($fileID) {
$this->service->files->delete($fileID);
$folderId = '###'; // Please set the folder ID.
$fileList = $this->service->files->listFiles(array("q" => "'{$folderId}' in parents"));
if (count($fileList->getFiles()) == 0) {
$this->service->files->delete($folderId);
}
}
Or, when you want to retrieve the folder ID from $fileID, you can also use the following script.
function deleteFileUsingID($fileID) {
$folderIds = $this->service->files->get($fileID, array("fields" => "parents"))->getParents();
$this->service->files->delete($fileID);
if (count($folderIds) > 0) {
$folderId = $folderIds[0];
$fileList = $this->service->files->listFiles(array("q" => "'{$folderId}' in parents"));
if (count($fileList->getFiles()) == 0) {
$this->service->files->delete($folderId);
}
}
}
In this modified script, after $this->service->files->delete($fileID); was run, it checks whether the files are in the folder using the method of "Files: list". When no files in the folder, the folder is deleted.
Note:
In this case, the folder is deleted. So please be careful this. I would like to recommend to use the sample folder for testing the script.
Reference:
Files: list
Related
For the birthday party of my wife I have setup a website through which I am collecting images from the party guests to create a nice book afterwards as a souvenir. The guests have an account and do upload the images to 'their' folders. I now have a tool in place that is dynamically creating a slide show from the pictures - but unfortunately it cannot go through subfolders.
So my primary goal is to copy the image files to one specified folder, from where the slideshow can pick it up. I would then run the PHP script as a cron every 5 minutes or so, and show the images on a screen during the party.
I already found a bunch of code snippets that all do the same thing:
They copy recursively all files and folders to a defined destination.
E.g. this one (taken from here: https://code-boxx.com/copy-folder-php/):
<?php
// (A) COPY ENTIRE FOLDER
function copyfolder ($from, $to, $ext="*") {
// (A1) SOURCE FOLDER CHECK
if (!is_dir($from)) { exit("$from does not exist"); }
// (A2) CREATE DESTINATION FOLDER
if (!is_dir($to)) {
if (!mkdir($to)) { exit("Failed to create $to"); };
echo "$to created\r\n";
}
// (A3) GET ALL FILES + FOLDERS IN SOURCE
$all = glob("$from$ext", GLOB_MARK);
print_r($all);
// (A4) COPY FILES + RECURSIVE INTERNAL FOLDERS
if (count($all)>0) { foreach ($all as $a) {
$ff = basename($a); // CURRENT FILE/FOLDER
if (is_dir($a)) {
copyfolder("$from$ff/", "$to$ff/");
} else {
if (!copy($a, "$to$ff")) { exit("Error copying $a to $to$ff"); }
echo "$a copied to $to$ff\r\n";
}
}}
}
// (B) GO!
copyfolder("C:/SOURCE/", "C:/TARGET/");
?>
This works fine besides the fact, that it is not what I need. The script is copying files and folders and is placing the files into the same subfolders where they are coming from. My issue is that I do not want the subfolders to be created. I just want the script to go through all the subfolders and copy the image files found into one single folder.
I thought this should be an easy thing for a newbie, but seems as if I am wrong here.
Can anyone help me to achieve that? Thanks!
IT goldman was right - keep the $to out of the loop; I have even removed the $to variable completely and placed my path in the copy-argument:
<?php
// (A) COPY ENTIRE FOLDER
function copyfolder ($from, $ext="*") {
// (A1) SOURCE FOLDER CHECK
if (!is_dir($from)) { exit("$from does not exist"); }
// (A3) GET ALL FILES + FOLDERS IN SOURCE
$all = glob("$from$ext", GLOB_MARK);
print_r($all);
// (A4) COPY FILES + RECURSIVE INTERNAL FOLDERS
if (count($all)>0) { foreach ($all as $a) {
$ff = basename($a); // CURRENT FILE/FOLDER
if (is_dir($a)) {
copyfolder("$from$ff/");
} else {
if (!copy($a, "C:/TARGET/$ff")) { exit("Error copying $a to C:/TARGET/$ff"); }
echo "$a copied to C:/TARGET/$ff\r\n";
}
}}
}
// (B) GO!
copyfolder("C:/SOURCE/");
?>
function ftpDeleteDirectory($directory)
{
global $conn_id;
if(empty($directory))//Validate that a directory was sent, otherwise will delete ALL files/folders
return json_encode(false);
else{
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($conn_id,$directory) || #ftp_delete($conn_id,$directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($conn_id, $directory);
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file)
{
// return json_encode($filelist);
ftpDeleteDirectory($directory.'/'.$file);/***THIS IS WHERE I MUST RESEND ABSOLUTE PATH TO FILE***/
}
#if the file list is empty, delete the DIRECTORY we passed
ftpDeleteDirectory($directory);
}
}
return json_encode(true);
};
How can I use this function written about ftp?
Trying to add the ability to delete a Folder using FTP and all subfolders and files contained within that folder.
Im building an application where I need to dynamically create some directories using the Azure's PHP SDK.
I did it using a loop but Im unsure if thats the correct way of doing it so heres my code;
I cant create a path that already exists so I have to check level by level if a directory and exists, than enters it and repeat.
public function generateDirectory($path)
{
$pathArray = explode("/", $path);
$currentPath = "";
try {
foreach ($pathArray as $key => $slice) {
$directories = $this->fileClient->listDirectoriesAndFiles("abraco", $currentPath)->getDirectories();
$currentPath .= $slice . "/";
$exists = false;
foreach ($directories as $key => $directory) {
if ($directory->getName() === $slice) {
$exists = true;
break;
}
}
if (!$exists) {
$this->fileClient->createDirectory("abraco", $currentPath);
}
}
return true;
} catch (Exception $e) {
return false;
}
}
Doesnt it should have a method to create a full path with subfolders? I think that this way is not performatic.
Doesnt it should have a method to create a full path with subfolders? I think that this way is not performatic.
I agree with you that there is a method to create a full path with subfolders will be better.
But currently, as you metioned that if we want to create full path with subfolders, we need to create the directory folder level by level.
If you use fiddler to capture request while you create multi-level directory structure via PHP SDK,you could find it use the following Rest API
https://myaccount.file.core.windows.net/myshare/myparentdirectorypath/mydirectory?
restype=directory
For more information please refer to Azure file Storage Create directory API.
myparentdirectorypath Optional. The path to the parent directory where mydirectory is to be created. If the parent directory path is omitted, the directory will be created within the specified share.
If specified, the parent directory must already exist within the share before mydirectory can be created.
I have created one process to read information from files and save into database, everything works fine in my desenv environment, but when I have put files in my php host (production environment) the process fail when read files.
to execute my process, I have created one cron job on cpanel, whith the command bellow:
php -q /home/<hostfolder>/batch/index.php
When my process is executed by cron, the output say that don't have files. Bellow part of my code:
private $sourceFilesFolder = "/home/<host folder>/public_html/batch/arquivos";
private $destFilesFolder = "/home/<host folder>/public_html/batch/processados";
private $log;
private $trataException;
function __construct($log, $trataException) {
$this->log = $log;
$this->trataException = $trataException;
}
/**
* Read the source folder and select only files
* #return array - Array of valid files
*/
function selectFiles() {
// Save the first read of ftp folder
$listSourceFolder = scandir ( $this->sourceFilesFolder );
// Array tho save only valid files
$listFiles = array ();
// read the array with ftp content and save in listFiles only files
foreach ( $listSourceFolder as $file ) {
$verifica = $this->sourceFilesFolder . "\\" . $file;
// if is a file type, try save in listFiles array
if (($file != ".") && ($file != "..") && (!is_dir ( $verifica ))) {
// verifiy if the file exists
if (file_exists ( $verifica )) {
$this->log->gravaLog ( $file . " -> ADDED TO PROCESS" );
//verificaArquivoEmUso ( $verifica );
array_push ( $listFiles, $verifica );
} else
$this->log->gravaLog ( $file . "-> do not exist." );
} else
$this->log->gravaLog ( $file . "-> not is a file." );
}
return $listFiles;
}
In my folder I have two txt files and this appear in the $listSourceFolder variable, but when I check this files with file_exists, always return false.
First, I have put my code files in a bacth folder in /home/
In the second test, I move the files in ftp folder and put inside the bacth folder (same of my code).
In the third test, I moved all batch folder (with codes and txt files) to public_html folder.
Nothing work, always the same error, file not exists.
I tryed remove ths file_exists if, but occur erros on the next step of algoritm.
I have checked the file permissions, and all permissions are ok.
What is I can do???
You can try three things.
1 - chmod 777 (Give permission so php can read and write files)
2 - I know its practically impossible that your server has a lower version of php. Scandir only works php 5 above. So you might wanna check that.
3 - There's a module called "mod_speling", try put that on.
;)
It appears that you are using the incorrect path delimiter for *nix.
You might change your code to be the following instead:
$verifica = $this->sourceFilesFolder . "/" . $file;
Trying to add the ability to delete a Folder using FTP and all subfolders and files contained within that folder.
I have built a recursive function to do so, and I feel like the logic is right, but still doesnt work.
I did some testing, I am able to delete on first run if the path is just an empty folder or just a file, but can't delete if it is a folder containing one file or a folder containing one empty subfolder. So it seems to be a problem with traversing through the folder(s) and using the function to delete.
Any ideas?
function ftpDelete($directory)
{
if(empty($directory))//Validate that a directory was sent, otherwise will delete ALL files/folders
return json_encode(false);
else{
global $conn_id;
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($conn_id,$directory) || #ftp_delete($conn_id,$directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($conn_id, $directory);
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file)
ftpDelete($file);
#if the file list is empty, delete the DIRECTORY we passed
ftpDelete($directory);
}
else
return json_encode(true);
}
};
I took some time to write my own version of a recursive delete function over ftp, this one should be fully functional (I tested it myself).
Try it out and modify it to fit your needs, if it's still not working there are other problems. Have you checked the permissions on the files you are trying to delete?
function ftp_rdel ($handle, $path) {
if (#ftp_delete ($handle, $path) === false) {
if ($children = #ftp_nlist ($handle, $path)) {
foreach ($children as $p)
ftp_rdel ($handle, $p);
}
#ftp_rmdir ($handle, $path);
}
}
Ok found my problem. Since I wasn't moving into the exact directory I was trying to delete, the path for each recursive file being called wasn't absolute:
function ftpDeleteDirectory($directory)
{
global $conn_id;
if(empty($directory))//Validate that a directory was sent, otherwise will delete ALL files/folders
return json_encode(false);
else{
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($conn_id,$directory) || #ftp_delete($conn_id,$directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($conn_id, $directory);
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file)
{
// return json_encode($filelist);
ftpDeleteDirectory($directory.'/'.$file);/***THIS IS WHERE I MUST RESEND ABSOLUTE PATH TO FILE***/
}
#if the file list is empty, delete the DIRECTORY we passed
ftpDeleteDirectory($directory);
}
}
return json_encode(true);
};
function recursiveDelete($handle, $directory)
{ echo $handle;
# here we attempt to delete the file/directory
if( !(#ftp_rmdir($handle, $directory) || #ftp_delete($handle, $directory)) )
{
# if the attempt to delete fails, get the file listing
$filelist = #ftp_nlist($handle, $directory);
// var_dump($filelist);exit;
# loop through the file list and recursively delete the FILE in the list
foreach($filelist as $file) {
recursiveDelete($handle, $file);
}
recursiveDelete($handle, $directory);
}
}
You have to check (using ftp_chdir) for every "file" you get from ftp_nlist to check if it is a directory:
foreach($filelist as $file)
{
$inDir = #ftp_chdir($conn_id, $file);
ftpDelete($file)
if ($inDir) #ftp_cdup($conn_id);
}
This easy trick will work, because if ftp_chdir works, the current $file is actually a folder, and you've moved into it. Then you call ftpDelete recursively, to let it delete the files in that folder. Afterwards, you move back (ftp_cdup) to continue.