Skip Navigation

[Resolved] Trying to Modify Post after Initial Publish

This support ticket is created 2 years, 6 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: Asia/Karachi (GMT+05:00)

This topic contains 5 replies, has 2 voices.

Last updated by aaronM-9 2 years, 6 months ago.

Assisted by: Waqar.

Author
Posts
#2189993

I'm trying to modify the content of a post when it is FIRST published (i.e. I don't want it to run if the post is updated later). However, whenever my code runs, the meta created by Toolset custom fields has not yet been created. I'm assuming Toolset must add the custom field values after the post is published, and therefore it hasn't been added yet using the hook below. Can you suggest a better alternative? Relevant code below:

add_action('transition_post_status', 'pp_digest_fetch_tags', 10, 3);
function pp_digest_fetch_tags($new_status, $old_status, $post) {
    if (get_post_type($post) == 'digest' && $new_status == 'publish' && $old_status != 'publish') {
		$post_id = $post->ID;
		$url = get_post_meta($post_id, 'wpcf-digest-source-url');
.......

Thanks!

#2190505

Waqar
Supporter

Languages: English (English )

Timezone: Asia/Karachi (GMT+05:00)

Hi,

Thank you for contacting us and I'd be happy to assist.

Your observation is correct and the hook "transition_post_status" seems to trigger before the Toolset custom field data has been saved.

In my tests, it is possible to use the "save_post" hook for this, for example:
( ref: https://developer.wordpress.org/reference/hooks/save_post/ )


function wpdocs_run_on_publish_only( $post_id, $post ){
	if ( 'digest' == $post->post_type ) {
		if ( (isset($_POST['original_post_status'])) && ($_POST['original_post_status'] == 'auto-draft' ) ) {
			$url = get_post_meta($post_id, 'wpcf-digest-source-url');
		}
	}  
}
add_action( 'save_post', 'wpdocs_run_on_publish_only', 30, 2 );

Note: The check for the post's "auto-draft" status ( i.e. $_POST['original_post_status'] == 'auto-draft' ), will make sure that the code is executed only the first time the post is published from the post edit screen and not for any subsequent updates.

I hope this helps and please let me know if you need any further assistance around this.

regards,
Waqar

#2190985

Thanks. I've made progress based on your code, but unfortunately I think it's getting stuck in an infinite loop because it invokes the wp_update_post() function later in the code. Do you know a way to prevent this from happening?

add_action( 'save_post', 'pp_digest_fetch_tags', 30, 2 );
function pp_digest_fetch_tags( $post_id, $post ){
    if (get_post_type($post) == 'digest') {
        if ( (isset($_POST['original_post_status'])) && ($_POST['original_post_status'] != 'publish' ) ) {

			// get URL of source content
			$url = get_post_meta($post_id, 'wpcf-digest-source-url', true);

			// get title
			$url_contents = file_get_contents($url);
			$new_title = preg_match('/<title[^>]*>(.*?)<\/title>/ims', $url_contents, $match) ? $match[1] : null;

			// set new slug based on title
			$new_slug = wp_unique_post_slug(
				sanitize_title($new_title),
				$post->ID,
				$post->status,
				$post->post_type,
				$post->post_parent
			);

			// get meta
			$tags = get_meta_tags($url);
			$new_content = $tags['description'];
			if (isset($tags['og:image'])) {
				$new_image = $tags['og:image'];
			} elseif (isset($tags['twitter:image'])) {
				$new_image = $tags['twitter:image'];
			} elseif (isset($tags['thumbnail'])) {
				$new_image == $tags['thumbnail'];
			} else {
				$new_image == '';
			}

			// update post
			$post_update = array(
				'ID' => $post_id,
				'post_title' => $new_title,
				'post_content' => $new_content,
				'post_name' => $new_slug
			);
			wp_update_post($post_update);
			exit();
...
#2191007

PS: I confirmed it is retaining "auto-draft" as the original status so that's why it's getting stuck in a loop.

#2192877

Waqar
Supporter

Languages: English (English )

Timezone: Asia/Karachi (GMT+05:00)

Thanks for writing back.

To avoid going into the infinite loop, you can use a static variable, before the "wp_update_post" function, so that it can only execute, once.

For example:


....

// set a static variable to false, initially
static $updated = false;

// if wp_update_post has already run once, exit.
if ( $updated ) {
	return;
}

// set the static variable to true, so the wp_update_post can run once
$updated = true;

// update post
$post_update = array(
	'ID' => $post_id,
	'post_title' => $new_title,
	'post_content' => $new_content,
	'post_name' => $new_slug
);
wp_update_post($post_update);

....

#2192931

My issue is resolved now. Thank you!

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