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
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;
}
}
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.
Tried this also but did not work either... I'm missing something else here.
$path = $upload_dir['baseurl'] . '/' . $post_id;
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:
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.
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?
Again, you have defined a function but not called it. The definition is here:
function deleteDirectory( $dir ) {
...
After the definition, you must call it:
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);
}
}
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.
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.
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
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.
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/).
OK thanks for sharing your solution!