Skip Navigation

[Resolved] Delete child posts when parent post is deleted

This support ticket is created 3 years, 4 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.

Sun Mon Tue Wed Thu Fri Sat
9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 - - 9:00 – 13:00
14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 - - 14:00 – 18:00

Supporter timezone: Africa/Casablanca (GMT+00:00)

This topic contains 10 replies, has 4 voices.

Last updated by ianH-12 3 years, 3 months ago.

Assisted by: Jamal.

Author
Posts
#1867689

Hi - We've tried following this thread - https://toolset.com/forums/topic/delete-related-posts-and-their-attachments-when-deleting-parent-post/

But we are still unable to get the child offers to delete when the parent is deleted

#1867737
#1870353

Minesh
Supporter

Languages: English (English )

Timezone: Asia/Kolkata (GMT+05:30)

Jamal is off. This is Minesh here.

I see Jamal shared some custom code and he will be get in touch with you as soon as he back to work on Friday.

#1873187

Jamal
Supporter

Languages: English (English ) French (Français )

Timezone: Africa/Casablanca (GMT+00:00)

Hello,

I run a small test on my local test installation with the same slugs for custom post types and the relationship and I was able to delete the children posts and the media files with the following code:

function delete_post_children($post_id) {
	global $wpdb;

	$post_type = get_post_type( $post_id );
	if ( $post_type == 'offer' || $post_type == 'opportunity') {
		error_log('Handling attachments');
		$ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_parent = $post_id AND post_type = 'attachment'");
		foreach ( $ids as $id ) {
			wp_delete_attachment($id, true);
		}
		error_log('Handling attachments completed');

		error_log('Handling featured image');
		if(has_post_thumbnail( $post_id )) {
			$tn_id = get_post_thumbnail_id( $post_id );
			wp_delete_attachment($tn_id, true);
		}
		error_log('Handling featured image completed');

		if( $post_type == 'opportunity' ) {
			error_log('Handling Toolset relationship children');
			// in this case, we want to force-delete the child product posts as well
			$opportunities = toolset_get_related_posts(
				$post_id,
				'opportunity-offer',
				[
					'query_by_role' => 'parent',
					'role_to_return' => 'child',
					'limit' => 10000,
					'orderby' => null,
				]
			);

			error_log('Children: ' . print_r($opportunities, true));

			foreach($opportunities as $opportunity ) {
				wp_delete_post( $opportunity, true );
			}
			error_log('Handling Toolset relationship children completed');
		}
	}
}

add_action('before_delete_post', 'delete_post_children');

I copied it to your site but I can't make sure the code is running because it does not generate any entries in the log file(error_log calls). So, I am taking a copy of your website to further investigate this locally. I'll get back to you as soon as possible.

#1873347

Jamal
Supporter

Languages: English (English ) French (Français )

Timezone: Africa/Casablanca (GMT+00:00)

I built a copy of your website locally and I was not able to make it work. For some reason, the toolset_get_related_posts does not return any children inside the hook. I used the exact same call on a shortcode and it returns the children, but not inside the hook. For example:

add_shortcode('get-children-offers', function(){
	global $post;
	$ret = "";

	$children = toolset_get_related_posts(
		$post->ID,
		'opportunity-offer',
		[
			'query_by_role' => 'parent',
			'role_to_return' => 'child',
			'limit' => 10000,
			'orderby' => null,
		]
	);

	$ret .= '<pre>';
	$ret .= print_r(array(
		'post_id' => $post->ID,
		'title' => $post->post_title,
		'children' => $children
	), true);

	$ret .= '</pre>';
	return $ret;
});

I am asking for assistance from our 2nd Tier on this and I'll get back to you as soon as possible.

#1876769

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

Hi Ian

Jamal is on vacation for a few days, but before leaving he asked me to look into why the code being used on your site may not be working.

But first, I need some clarity on your workflow.

The before_delete_post action specifically fires when a post has been trashed and then is deleted from the trash.

I'd be inclined to use the delete_post hook, which fires immediately prior to the post being deleted, but after WordPress has done some housekeeping of its own, including deleting comments on the post, for example.

So can you please confirm the workflow involved in deleting the parent posts that should then trigger deleting the child posts. Once I know that, I'll set up something similar on my own test site, and then try to apply it to a copy of your site.

The code shared also deletes attachments and featured images, that's part of the requirement?

#1880387

Hi,

We are using Toolset to offer volunteering opportunities for events. With everything that is going on at the moment a lot of events are being cancelled so they are no longer needed on the system so we are deleting them but volunteers who have already signed up to attend the event are still receiving the email due to hit their inbox 36 hours before the event - See E-mail Notifications, Volunteer Reminder on the Add offer Post Form - Stopping these emails when a opportunity has been deleted or drafted is ultimately our goal.

The code we have been using was just what we found from your support forum that seemed to be the best way to stop these emails being sent to the volunteers as it should remove all offers attached to the deleted opportunity. If you have any better solutions we are happy to try.

Hope that helps shed some light.

#1883945

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

There are several hooks available where we might intervene to remove the child offer posts when you delete or trash a parent opportunity.

I've just been testing them now to be sure what fires when to know which can be used for this.

The delete_post hook fires when a post is actually deleted (rather than trashed).

The before_delete_post hook only fires when a trashed post is deleted (not if a post is deleted directly without travelling through the trash first).

The trash_post hook fires when a post is sent to the trash, but in my testing I found it only works when the post is trashed via the WordPress admin pages, it isn't fired if you send a post to the trash programmatically.

I'm sure we can produce a solution, but I need clarification from you about the workflow.

Is it true that whenever an opportunity post is either trashed or deleted that all child offer posts should be deleted? (Specifically, it is okay to delete them when the opportunity post is just sent to the trash?)

If an opportunity post is trashed, where does that happen? From the WordPress backend? (Anywhere else, this may not be possible.)

Do opportunity posts also get deleted directly without first being trashed? How?

#1883975

Hi

At the moment. Shows are generally deleted on the front end, which is setup on the Opportunities Template and deleted using Form "Delete Opportunity" (ID:57)

We are happy for Opportunities to be fully deleted rather than trashed if that makes anything easier.

When the show is deleted, we would want all associated child posts (Offers) to be fully deleted too.

#1885083

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+01:00)

Hi Ian

Please try the following code in place of what you were using previously.

I've tested it on my local copy of your site, and it is working, so hopefully you'll find the same.

add_action( 'before_delete_post', 'ts_before_delete_post', 1, 2 );
function ts_before_delete_post( $post_id, $post ){

	if ( $post->post_type == 'opportunity' && $post->post_status == 'publish' )
	{		
		$children = toolset_get_related_posts( $post_id,'opportunity-offer',array('query_by_role' => 'parent','role_to_return' => 'child'));

		if ( is_array( $children ) )
		{
			foreach ($children as $key => $child) {
				wp_delete_post( $child, true );
			}
		}
	}
}
#1887889

Jamal
Supporter

Languages: English (English ) French (Français )

Timezone: Africa/Casablanca (GMT+00:00)

Hello,

I tested this code from Nigel on my local copy and it worked. Please test it on your website and let us know what you will get.

Best regards,
Jamal

#1893927

Seems to be working now, thank you for all your hard work and happy new year!

This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.