Skip Navigation

[Resolved] Delete custom upload folder when Form is submitted successfully

This thread is resolved. Here is a description of the problem and solution.

Problem: I have a Form that should delete Users. Each User has a custom upload directory. I would like to also delete that custom upload directory.

Solution: Use the cred_submit_complete hook to tap into that deletion event and trigger your own directory removal code.

add_action('cred_submit_complete', 'my_success_action',10,2);
function my_success_action($post_id, $form_data)
{
    // if a specific form
    if ($form_data['id']==12)
    {
        // user id = $post_id;
    }
}

Relevant Documentation:
https://toolset.com/documentation/programmer-reference/cred-api/#cred_submit_complete

This support ticket is created 5 years, 7 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

No supporters are available to work today on Toolset forum. Feel free to create tickets and we will handle it as soon as we are online. Thank you for your understanding.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 13 replies, has 2 voices.

Last updated by Christian Cox 5 years, 7 months ago.

Assisted by: Christian Cox.

Author
Posts
#1223580

Hi team,

I'm trying to create fully functional delete (self) account feature on my project and I need a little help.

I started with the guide from this ticket:
https://toolset.com/forums/topic/add-the-link-delete-account/#post-1223439

The method works and deletes the custom user and his custom posts. Also I would like to clean up the uploads folder by deleting the dedicated user folder. Right now every user has his own folder named after his ID with the following function:

/* #2 Per user upload dir function */
function per_user_upload_dir( $original ){
    // use the original array for initial setup
    $modified = $original;
    // set our own replacements
    if ( is_user_logged_in() ) {
        $current_user = wp_get_current_user();
        $subdir = $current_user->ID;
        $modified['subdir'] = $subdir;
        $modified['url'] = $original['baseurl'] . '/' . $subdir;
        $modified['path'] = $original['basedir'] . DIRECTORY_SEPARATOR . $subdir;
    }
    return $modified;
}
add_filter( 'upload_dir', 'per_user_upload_dir'); 

How can I trigger a an action that would delete the folder named after the user's ID on form submission?

Thanks in advance!
Diyan

#1223600

You can use the cred_submit_complete hook to trigger any action that will delete the folder. In the hook, you'll have access to the User's ID in the first callback parameter:

add_action('cred_submit_complete', 'my_success_action',10,2);
function my_success_action($post_id, $form_data)
{
    // if a specific form
    if ($form_data['id']==12)
    {
        // user id = $post_id;
    }
}
#1223629

OKay just a little more help needed on this one!

I have the pieces but not sure how I can make them work together:

This should delete a folder:

	public function rmdir( $path, $recursive = false ) { 
		return false;
	}

However I need a path here, and I can start building my path with this which should return hidden link

echo $upload_dir['baseurl'] 

..and here is where I get lost with line 7

Since I'm not a developer this is how far I could go:

add_action('cred_submit_complete', 'my_success_action',10,2);
function my_success_action($post_id, $form_data)
{
    // if a specific form
    if ($form_data['id']==198)
    {
        // user id = $post_id;
        $path = $upload_dir['baseurl'] . $post_id;
        function rmdir( $path, $recursive = false ) {
			return false;
			}
    }
}

..but without success.

#1223651

Tried this also but did not work either... I'm missing something else here.

$path = $upload_dir['baseurl'] . '/' . $post_id;
#1223954

Looks like you have defined a custom rmdir function:

function rmdir( $path, $recursive = false ) {
            return false;
            }

You don't want to define the rmdir function. The function already exists in PHP:
https://www.php.net/manual/en/function.rmdir.php
You want to invoke the function with your path variable:

rmdir( $path, true );

However in the PHP docs you can see "The directory must be empty" for rmdir to work. So first, you would have to recursively delete all the files in the directory. Check the User comments in the documentation for some examples.

#1224089

Huh, I tried many different examples found on the internet but nothing seems to work.

I even tried one that handles permissions issues - still no go.

/* Delete user folder */
add_action('cred_submit_complete', 'my_success_action',10,2);
function my_success_action($post_id, $form_data)
{
    // if a specific form
    if ($form_data['id']==198)
    {
        // user id = $post_id;
        $dir = $upload_dir['baseurl'] . '/' . $post_id;        

		//Delete folder function 
		function deleteDirectory($dir) { 
		    if (!file_exists($dir)) return true; 
		    if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
		        foreach (scandir($dir) as $item) { 
		            if ($item == '.' || $item == '..') continue; 
		            if (!deleteDirectory($dir . "/" . $item)) { 
		                chmod($dir . "/" . $item, 0777); 
		                if (!deleteDirectory($dir . "/" . $item)) return false; 
		            }; 
		        } 
		        return rmdir($dir); 
		    } 
      
    }
}

The problem is that I do not get any error message so I can't really troubleshoot either..

Also since the folder gets emptied when the user submits the CRED form, how about just using the rmdir function with a little delay, would this be possible?

#1224092

Again, you have defined a function but not called it. The definition is here:

function deleteDirectory( $dir ) {
...

After the definition, you must call it:

deleteDirectory($dir);
#1224102

You must be laughing at my php skills, but unfortunately I still cannot get the expected results and the directories in my uploads folder just keep piling up..

/* Delete user folder */
add_action('cred_submit_complete', 'my_success_action',10,2);
function my_success_action($post_id, $form_data)
{
    // if a specific form
    if ($form_data['id']==198)
    {
        // user id = $post_id;    
         $dir = $upload_dir['baseurl'] . '/' . $post_id;
		//Delete folder function 
		function deleteDirectory($dir) { 
		    if (!file_exists($dir)) return true; 
		    if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
		        foreach (scandir($dir) as $item) { 
		            if ($item == '.' || $item == '..') continue; 
		            if (!deleteDirectory($dir . "/" . $item)) { 
		                chmod($dir . "/" . $item, 0777); 
		                if (!deleteDirectory($dir . "/" . $item)) return false; 
		            }; 
		        } 
		        return rmdir($dir); 
		    } 
        deleteDirectory($dir);      
    }
}
#1224126

I can help you troubleshoot as far as the event hook being triggered, and the proper user ID being set. Turn on server logs and add some error log statements to verify the event is being triggered as expected. If you're not familiar with server logs I can show you how to activate them temporarily. Go in your wp-config.php file and look for

define('WP_DEBUG', false);

Change it to:

define('WP_DEBUG', true);

Then add these lines, just before it says 'stop editing here':

ini_set('log_errors',TRUE);
ini_set('error_reporting', E_ALL);
ini_set('error_log', dirname(__FILE__) . '/error_log.txt');

Now in your PHP code, add error_log statements to write to the logs.

/* Delete user folder */
add_action('cred_submit_complete', 'my_success_action',10,2);
function my_success_action($post_id, $form_data)
{
    // if a specific form
    if ($form_data['id']==198)
    {
error_log('form 198 submitted');
        // user id = $post_id;
error_log('user id: ' . $post_id);    
         $dir = $upload_dir['baseurl'] . '/' . $post_id;
error_log('dir: ' . $dir);    
        //Delete folder function 
        function deleteDirectory($dir) { 
            if (!file_exists($dir)) return true; 
            if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
                foreach (scandir($dir) as $item) { 
                    if ($item == '.' || $item == '..') continue; 
                    if (!deleteDirectory($dir . "/" . $item)) { 
                        chmod($dir . "/" . $item, 0777); 
                        if (!deleteDirectory($dir . "/" . $item)) return false; 
                    }; 
                } 
                return rmdir($dir); 
            } 
        deleteDirectory($dir);      
    }
}

You can add more error_logging if you'd like.
Submit the form and then check your site's root directory for a new file called error_log.txt. Copy and paste its contents here for me to review. You can then revert the changes you made to wp-config.php.

#1224176

This is good! The ID being called is the right one.

[01-Apr-2019 20:11:10 UTC] form 198 submitted
[01-Apr-2019 20:11:10 UTC] user id: 37
[01-Apr-2019 20:11:10 UTC] PHP Notice:  Undefined variable: upload_dir in /home/greenbga/dev.green.bg/wp-content/themes/pro-child/functions.php on line 202
[01-Apr-2019 20:11:10 UTC] dir: /37

line 202 goes as follows:

         $dir = $upload_dir['baseurl'] . '/' . $post_id;

Looks like the dir value is not being properly built..

I know I need to be careful with this one because it might delete my website folder if not being set properly, correct me if I'm wrong.

#1224196

I know I need to be careful with this one because it might delete my website folder if not being set properly, correct me if I'm wrong.
Yes, that's correct. If you're not sure what you're doing, you could delete your site's contents by removing the wrong directories. Now we're outside the scope of the support provided here in the forums. I have shown you that the API hook is being triggered, and the User ID is set correctly. Now you must take it from here, because everything else is custom code that has nothing to do with Toolset. If you need help, we have a contractors portal available here: https://toolset.com/contractors

#1224229

Yes that is right, I need to go on my own from here!
I am closing the ticket but will add later to it when I get the thing working.

#1224237

Finally got it working. It was quite easy from here!

I just used the proper way to get the base directory and not url, because the url can not tell the server what folder to delete.
So basedir vs baseurl.

/* Delete user folder */
add_action('cred_submit_complete', 'my_success_action',10,2);
function my_success_action($post_id, $form_data)
{
    // if a specific form
    if ($form_data['id']==198)
    {
        // user id = $post_id;
	$myuploadpath = wp_upload_dir();
	$myuploadbase = $myuploadpath['basedir'];
         $dir = $myuploadbase . '/' . $post_id;
        //Delete folder function 
        function deleteDirectory($dir) { 
            if (!file_exists($dir)) return true; 
            if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
                foreach (scandir($dir) as $item) { 
                    if ($item == '.' || $item == '..') continue; 
                    if (!deleteDirectory($dir . "/" . $item)) { 
                        chmod($dir . "/" . $item, 0777); 
                        if (!deleteDirectory($dir . "/" . $item)) return false; 
                    }; 
                } 
                return rmdir($dir); 
            } 
        deleteDirectory($dir);      
    }
}

I am very satisfied with the final result. Now I am sure that once the user gets deleted from the platform there will be no traces left on the server.

This is very helpful for someone developing a GDPR compliant project that stores files in directories named after the names of the users too (For example: mywebsite.com/archive/userfirstnamelastname/).

#1224566

OK thanks for sharing your solution!