5

I'm using D8, and am writing a cron task to remove old backups from my private files directory. The backups are generated in private://db_backups/date-of-backups/backup.gz. The following code is properly deleting the actual backup files, but it is not removing the parent date directory. I am not receiving any errors in the drupal or server logs, so I'm a bit lost as to what's causing the failure.

function custom_changes_cron() {
    drupal_set_message(t('Custom cron function has run.'), 'status');
    $private_path = PrivateStream::basePath();
    $interval = strtotime('-430 hours');
    foreach(glob($private_path . '/backup_db/*' , GLOB_ONLYDIR) as $folder) {
        if (filemtime($folder) <= $interval ) {
            $files = glob("$folder/*"); // get all file names
            foreach($files as $file){ // iterate files
              if(is_file($file))
              unlink($file); // delete file
            }

            // Have tried both of the following
            rm_dir($folder);
            drupal_rmdir($folder);  
        }
    }
}
2
  • Why not kill the whole tree? stackoverflow.com/questions/3349753/… – iLLin Feb 14 '17 at 18:49
  • I'm thinking there is some other file in there (hidden) or directory that is preventing the main directory from being removed. – iLLin Feb 14 '17 at 18:51
3
+50

Note that glob('*') ignores all hidden files by default. This means it does not return files that start with a dot (e.g. .file). If you want to match those files too, you can use {,.}* as the pattern with the GLOB_BRACE flag. This will include the special cases . and .. so you need to exclude those by using {,.}[!.,!..]*.

So in summary, try the following:

$files = glob("$folder/" . '{,.}[!.,!..]*',GLOB_MARK|GLOB_BRACE);

As a sidenote: you mention you tried using rm_dir. I assume you mean rmdir?

1
  • Thanks, that did indeed do the trick. I didn't see any hidden files in there when I checked manually, but I also had the feeling that this may have been the culprit. I also did mean rmdir and not rm_dir. Using file_unmanaged_delete_recursive as suggested by Jigar also worked without the need for manually deleting the files, but I wanted to award you the bounty since your answer may be more widely applicable to people who come across it. – Mrweiner Feb 21 '17 at 21:12
3

Interesting. Did you try using the following functions? I think one of them should work:

Make sure that PHP has permission to delete the directories. To test this, delete the contents of one of the backup directories manually and then try one of the above functions on it - this will help you understand whether the directory deletion is causing the problem or something else inside the directory.

Alternatively, you can set up a server-side cron in a shell script if you are considering that.

BTW, I notice you are using drupal_set_message() - it will not work from within a cron due to some session-specific reasons. Use \Drupal::logger('custom')->debug('Description'); - the message will appear in the Reports > Recent log messages menu.

Hope it helps!

1
  • 1
    Thanks for the input! PHP did have the proper permissions, and drupal_rmdir was not working for me, probably because of some hidden files that I was missing. file_unmanaged_delete_recursive worked without needing to manually iterate through the files in the folders. That being said, I awarded the bounty to the other answer since they addressed the issue with my specific code. Your suggestion would probably be the way to go in general, though. – Mrweiner Feb 21 '17 at 21:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.