Reputation: 23
Dears,
I want to delete the old post automatically without using a plugin and the Snippets will be the choice, I want to delete any post older than one day from a special category an using this Snippet but nothing deleted:
// Automatically delete posts older than x days
function delete_old_posts($category_id = 62) {
$days = 1; // Change this value to the desired number of days
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'date_query' => array(
array(
'before' => $days . ' days ago',
'inclusive' => true,
),
),
'tax_query' => array(
array(
'taxonomy' => 'slug', // Replace 'category' with your actual taxonomy slug if different
'field' => 'id',
'terms' => array($category_id), // Array of category IDs to target
),
),
);
$old_posts = new WP_Query($args);
if ($old_posts->have_posts()) :
while ($old_posts->have_posts()) : $old_posts->the_post();
wp_delete_post(get_the_ID(), true);
endwhile;
endif;
wp_reset_postdata();
}
add_action('wp', 'delete_old_posts');
Upvotes: 2
Views: 189
Reputation: 301
Grab the te_delete_old_posts() function if using independently and no need for the cron parts if that is not required.
// Function to set up a daily custom event.
function te_setup_daily_post_deletion_event() {
if (!wp_next_scheduled('te_daily_post_deletion_hook')) {
wp_schedule_event(time(), 'daily', 'te_daily_post_deletion_hook');
}
}
add_action('wp', 'te_setup_daily_post_deletion_event');
// Function to delete old posts.
function te_delete_old_posts() {
$category_id = 62; // Set your category ID.
$days = 1; // Posts older than this number of days will be deleted.
$query_date = date('Y-m-d', strtotime("-$days days"));
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'fields' => 'ids', // Retrieve only the IDs for efficiency.
'date_query' => array(
array(
'before' => $query_date,
'inclusive' => false, // set to true if previous day is considered a day old
),
),
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => array($category_id),
),
),
);
$old_posts = get_posts($args); // Get a nice lean memory efficient list of post ID's
if (!empty($old_posts)) {
foreach ($old_posts as $post_id) {
wp_delete_post($post_id, true);
}
}
}
// Used for the cronjob method
add_action('te_daily_post_deletion_hook', 'te_delete_old_posts');
In the example below I extracted the main query component so you can add to a function and run it.
The date initially passed does not come out as expected. $query_date is used to get the correct date using PHP date/strtotime functions with no time residue.
Also I am telling the query to provide only ID's of the results so that it will be efficient than getting entire post objects.
Finally I am using get_posts() so that we can get an clean array of Post ID's to loop thru, and not have to deal with WP_Query().
$category_id = 62; // Set your category ID.
$days = 1; // Posts older than this number of days will be deleted.
$query_date = date('Y-m-d', strtotime("-$days days"));
$args = array(
'post_type' => 'post',
'posts_per_page' => -1,
'fields' => 'ids', // Retrieve only the IDs for efficiency.
'date_query' => array(
array(
'before' => $query_date,
'inclusive' => false, // set to true if previous day is considered a day old
),
),
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'term_id',
'terms' => array($category_id),
),
),
);
$old_posts = get_posts($args); // Get array of post ID's
if (!empty($old_posts)) {
foreach ($old_posts as $post_id) {
echo $post_id . " " get_the_title($post_id);
}
}
Running just this code you can verify that you are getting the expected results, and tweak the query if not.
If this process is a recurring event which it sounded like from the description. It should go in WP cronjob so that the process does not keep running each time a page loads as you had in the 'wp' hook. I am guessing that must have been for testing or you were planning on doing this manually.
function te_setup_daily_post_deletion_event() {
if (!wp_next_scheduled('te_daily_post_deletion_hook')) {
wp_schedule_event(time(), 'daily', 'te_daily_post_deletion_hook');
}
}
add_action('wp', 'te_setup_daily_post_deletion_event');
If you do not wish to use a cronjob and want to run this manually, add the function te_delete_old_posts() in your themes function.php or in a custom plugin and you can use one of the two methods bellow to run the function.
wp eval "te_delete_old_posts();"
Hit enter after typing the function name inside the shell
wp shell
wp> te_delete_old_posts()
Your script is a pretty good start, and you seemed to be on the right track. WordPress creates data in a few tables when you create a posts and it is important that proper cleanup happens when you delete a post. wp_delete_post() does just that.
And as mentioned use the code I provided for testing and make sure you are getting results first, if something is not working.
Upvotes: 0
Reputation: 142
You can use this:
<?php
function delete_posts_by_category_and_age_atakanau() {
// Set the category ID of the posts to be deleted
$category_id=11;
// Calculate the date 1 day ago
$one_day_ago = date('Y-m-d H:i:s', strtotime('-1 day'));
global $wpdb;
// Get posts ID older than 1 day with the given category ID
$query = $wpdb->prepare(
"SELECT posts.ID
FROM {$wpdb->posts} posts
INNER JOIN {$wpdb->term_relationships} term_relationships ON (posts.ID = term_relationships.object_id)
WHERE posts.post_type = 'post'
AND posts.post_status = 'publish'
AND term_relationships.term_taxonomy_id = %d
AND posts.post_date < %s",
$category_id,
$one_day_ago
);
$posts_to_delete = $wpdb->get_results($query);
// Loop through the posts to delete
foreach ($posts_to_delete as $post) {
// Use wp_delete_post to delete each post
wp_delete_post($post->ID, true); // Set second parameter to true to bypass the trash
}
}
add_action('plugins_loaded', 'delete_posts_by_category_and_age_atakanau');
I recommend using it in a child theme instead of a snippet. The hook may not be triggered with the snippet. Or you can call the function directly.
Upvotes: 0
Reputation: 2506
There is no straightforward solution in WP, you have to use custom SQL.
wp_terms
stores term names with Primary Key (PK) associated IDwp_term_relationships
is a relationship table between posts & their taxonomy/termswp_term_taxonomy
is a relationship table between term and their associated taxonomiesCaution always first check the SQL through SELECT
statement before using non-revokable action like deleting records.
SELECT
*
FROM
wp_posts wp
WHERE
post_date <= DATE_SUB(NOW(), INTERVAL 6 HOUR)
AND
post_type = 'post'
AND
ID IN (
SELECT
wtr.object_id
FROM
wp_term_taxonomy wtt
JOIN wp_terms wt ON
wtt.term_id = wt.term_id
JOIN wp_term_relationships wtr ON
wt.term_id = wtr.term_taxonomy_id
WHERE
wtt.taxonomy = 'category'
AND wt.slug = 'temp');
WHERE
clause change the value of wt.slug
from temp
to your desired category slug.post_date <= DATE_SUB(NOW(), INTERVAL 6 HOUR)
change the interval to your desired time unit like Week, Day, Hour, etc. (Reference for unit: https://dev.mysql.com/doc/refman/8.0/en/expressions.html#temporal-intervals)If you're satisfied with the output of SELECT
statement, then change it to DELETE
statement like below.
DELETE
FROM
wp_posts wp
WHERE
post_date <= DATE_SUB(NOW(), INTERVAL 6 HOUR)
AND
post_type = 'post'
AND
ID IN (
SELECT
wtr.object_id
FROM
wp_term_taxonomy wtt
JOIN wp_terms wt ON
wtt.term_id = wt.term_id
JOIN wp_term_relationships wtr ON
wt.term_id = wtr.term_taxonomy_id
WHERE
wtt.taxonomy = 'category'
AND wt.slug = 'temp');
Upvotes: 0