Removing Comments in Branches
I propose a hook for deleting all child comments when a comment is deleted, i.e. we delete the comment and all its child comments are also deleted, as well as their child comments, and so on. In other words, when a comment is deleted, the entire branch of replies to it is also deleted.
To make "branch deletion" work, insert the code into the functions.php theme file.
/** * Deleting all child comments (entire tree) when a comment is deleted */ add_action( 'delete_comment', 'del_child_comments_on_del_comment' ); function del_child_comments_on_del_comment( $comment_id ) { global $wpdb; $child_comments = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'" ); // if there are no children, return if( ! $child_comments ){ return; } foreach( $child_comments as $val ){ wp_delete_comment( $val ); } }
Key points of the hook: filter - delete_comment and function - wp_delete_comment():
I spent quite a bit of time on the code because it uses recursion, and recursion can often be tricky and not my favorite...
In programming, recursion is the process of a function calling itself (simple recursion) or through other functions (complex or indirect recursion). For example, function A calls function B, and function B calls function A. The number of nested function or procedure calls is called the depth of recursion.
At first, I tried to use recursion naturally (wrote a function, hooked it to a hook, and called it from within itself) - but it didn't work out, and the code just kept growing. At one point, as I went to make myself a cup of tea, the Eureka moment came, and I understood everything: the closure will occur when the delete_comment hook is triggered during the successive calls of the wp_delete_comment() function, and there's no need to call the function from within the function in its pure form, i.e. there will be indirect recursion.
Honestly, I can't imagine a real situation on a regular blog where such comment deletion would be particularly necessary. However, it is logical and may be needed by someone. On this blog, I did it this way because if you delete a comment that has child comments, the meaning of the child comments will often be lost: there will be comments that are unclear. Using an allegory - these are comments on a post without the post itself. I think I don't need that here.
Moving to Trash
After the deletion task was solved, following the beaten path, I wrote the same moving comments to trash and restoring them from trash by branches.
The principle is the same, only now filters are used: trash_comment, untrash_comment and functions: wp_trash_comment(), wp_untrash_comment():
/** * Moving all child comments to trash (entire tree) when a comment is deleted */ add_action( 'trash_comment', 'trash_child_comments_on_trash_comment' ); function trash_child_comments_on_trash_comment( $comment_id ) { global $wpdb; // if there are no children, return $child_comments = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'" ); if( ! $child_comments ){ return; } foreach( $child_comments as $val ){ wp_trash_comment( $val ); } } add_action( 'untrash_comment', 'untrash_child_comments_on_untrash_comment' ); function untrash_child_comments_on_untrash_comment( $comment_id ) { global $wpdb; // if there are no children, return $child_comments = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'" ); if( ! $child_comments ){ return; } foreach( $child_comments as $val ){ wp_untrash_comment( $val ); } }
Simplified Code for Moving to Trash
Here's a very interesting code for those who understand PHP: a simplified version of the above code (for the trash). Here, it's interesting to see how the current_filter() function can be used and an unusual dynamic function call in PHP using a variable ($use_function( $val )
). In general, take a look for yourself:
/** * Moving all child comments to trash (entire tree) when a comment is deleted */ add_action( 'trash_comment', 'trash_untrash_child_comments_with_parent' ); add_action( 'untrash_comment', 'trash_untrash_child_comments_with_parent' ); function trash_untrash_child_comments_with_parent( $comment_id ) { global $wpdb; // if there are no children, return $child_comments = $wpdb->get_col( "SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'" ); if( ! $child_comments ){ return; } foreach( $child_comments as $val ){ // get wp_trash_comment or wp_untrash_comment $use_function = 'wp_' . current_filter(); $use_function( $val ); } }