Easily delete a large number of Flamingo (Contact Form 7) messages.
I recently began work on a website revamp for a client. While reviewing the current site I noticed that the CF7 Flamingo plugin was active and had a over 2000 stored submissions! I didn’t want to delete them manually through the Dashboard.
Incomplete Method
I did a web search and a number of sites recommended using a single SQL command in phpMyAdmin:
DELETE FROM `wp_posts` WHERE `post_status` LIKE 'flamingo_spam'
Unfortunately this leaves a number of records in the wp_postmeta table (8 rows for each message). Furthermore, it doesn’t delete the address book or non-spam entries.
I decided to write a standalone script to use the WordPress API to delete each post, knowing that it would also delete the corresponding postmeta records.
After writing the code I found a post in a Flamingo support thread that mentioned the post meta.
The query
The suggested SQL command was helpful in providing the post type to query for (‘flamingo_spam‘). Then I would call wp_delete_post() to completely delete the post (by passing trash).
The address book
Flamingo also stores the email addresses corresponding to contact form submissions. These are stored with a different post type – ‘flamingo_contact‘ – so this needed to be added to the query’s post type.
Then I browsed the Flamingo code and found the ‘flamingo_outbound‘ post type and included it too.
Now we’re all set.
The code
I decided to limit the number of records returned to 200, in case the deletion process timed out. I just had to reload the script to delete the next batch of records.
You will also see that I used the ‘fields‘ parameter so that I get all the post IDs without having to do a loop. It’s not really necessary here because I have to run a loop to call wp_delete_post() but it would simplify other scenarios where you didn’t need to access any other post info.
The time and memory stats are included just for fun.
Nice work! I wonder how difficult it would be to delete ALL (not just spam) messages in CF7 / Flamingo after a certain period (e.g. 30 days) for a certain contactform (e.g. registration-form-1). This would allow a proper process for GDPR purposes differentiated to certain information and would be very useful.
Does anybody here could adjust the code to that goal?
Thanks
@Elenora: The quickest solution is to change to use Ninja Forms :-) It has this feature built in. It is also lighter than CF7 which is a bit of a hog.
If you stick with CF7 you’d need a cron job that would run a query for all CF7 submissions older than 30 days and delete them. I don’t think that it would be particularly difficult. I might write such code if I get some time between projects (I’m very busy at the moment).
Lifesaver. Thank you!
Hi, I’m a not very knowledgeable on PHP, but need to clean-up our Flamingo DB. Can you explain what to do with your script?
@Wayne: Download the file and upload it to the root directory of your website. Then go to the page e.g. https://yoursite.com/delete-flamingo-data.php Keep reloading the page until there are no entries left.
Delete the file when you are finished.
Hey, how do I use the code? Just create a php file, upload it and run it?
@Rubb: Download the file and upload it to the root directory of your website. Then go to the page e.g. https://yoursite.com/delete-flamingo-data.php Keep reloading the page until there are no entries left.
Delete the file when you are finished.
In case it helps anyone – I had to tweak this to get it to delete the spam messages instead of the wanted ones (it did the reverse when I tried it).
I changed line 17 to this to get it to do what I wanted: ‘post_status’ => array( ‘flamingo-spam’ ),
Is this still solution still working in 2023? I uploaded the your coded file to the root directory and refreshed the page. It shows 200 records as deleted each time I refresh the page. However in the wp backend Flamingo Inbound messages page the records haven’t got deleted. The same numbers show. Has Flamingo plugin changed any code since you wrote this solutions?
@Aksam – I do not think that Flamingo has changed. I know (from the emails we exchanged) that you used SQL to delete the Flamingo entries. I am curious what data was left behind after you ran by script – if you used the ID listed in the script output to see if that record was still there or what bits were left.
For others that might have this issue, here is the SQL that Aksam used:
SELECT * FROM wp_postmeta INNER JOIN wp_posts WHERE (( wp_posts.post_type = 'flamingo_contact' ) AND ( wp_postmeta.post_id = wp_posts.ID ) );
DELETE wp_postmeta, wp_posts FROM wp_postmeta INNER JOIN wp_posts WHERE ( ( wp_posts.post_type = 'flamingo_contact' ) AND ( wp_postmeta.post_id = wp_posts.ID ) );
SELECT * FROM wp_postmeta INNER JOIN wp_posts WHERE (( wp_posts.post_type = 'flamingo_inbound' ) AND ( wp_postmeta.post_id = wp_posts.ID ) );
DELETE wp_postmeta, wp_posts FROM wp_postmeta INNER JOIN wp_posts WHERE ( ( wp_posts.post_type = 'flamingo_inbound' ) AND ( wp_postmeta.post_id = wp_posts.ID ) );
Obviously you may need to change the table prefix from ‘wp_’ for your installation.
I did some modifications on the code and it works fine to delete 2000 messeges per request you can use it if you want.
<?php define('WP_USE_THEMES', false); require( dirname( __FILE__ ) . '/wp-blog-header.php' );
$args = array('flamingo_inbound', 'flamingo_contact', 'flamingo_outbound'), 'fields' => 'ids', 'post_status' => array('publish', 'trash', 'flamingo-spam'), 'posts_per_page' => 2000, 'no_found_rows' => true, 'update_post_term_cache' => false, 'update_post_meta_cache' => false, 'orderby' => 'ID', 'order' => 'ASC' );
$flamingo_msgs = new WP_Query($args); $total_deleted = 0;
while ($flamingo_msgs->have_posts()) { $msgs_ids = $flamingo_msgs->posts; foreach ($msgs_ids as $msg_id) { if (null == wp_delete_post($msg_id, true)) { echo "Error deleting item ID: $msg_id"; } else { $total_deleted++; } } // Check if there are more pages to process if ($flamingo_msgs->max_num_pages > $flamingo_msgs->query['paged']) { $flamingo_msgs->query['paged']++; $flamingo_msgs->query_vars['paged']++; $flamingo_msgs->get_posts(); } else { break; } }
echo "Deleted $total_deleted messages."; wp_reset_postdata();
// Display some stats - for fun. echo 'Memory usage: ', intval(memory_get_usage() / (1024 * 1024)), "MB\n"; echo 'Peak memory usage: ', intval(memory_get_peak_usage() / (1024 * 1024)), "MB\n";
$time_end = microtime(true); $time = $time_end - $time_start; echo "Process Time: {$time} seconds.";