1

Short:

I want to change the post's slug (for permalink purposes) upon saving, and use data I just entered in the post editor to modify it.

Long:

I am currently using the Tribe Events Calendar plug-in, and want to create multiple events with the same title, so to make sure the permalinks are unique, I add the event date (which is stored alongside the post) to the end of the slug on saving the event (post).

What I have done so far

I have the permalink update working by using the save_post hook:

function change_event_slug_on_save( $post_id ) {
    if ( ! wp_is_post_revision( $post_id ) && tribe_is_event($post_id) ) {
        // verify post is not a revision, and an event
        $post = get_post($post_id);
        $slug = sanitize_title($post->post_title);
        $newslug = $slug . '-' . tribe_get_start_date( $post_id, false, 'j F Y' );
        if ($post->post_name !== $newslug) {
            // unhook this function to prevent infinite looping
            remove_action( 'save_post', 'change_event_slug_on_save' );
            // update the post slug
            wp_update_post( array(
                'ID' => $post_id,
                'post_name' => $newslug
            ));
            // re-hook this function
            add_action( 'save_post', 'change_event_slug_on_save', 10, 1 );
        }
    }
}

add_action( 'save_post', 'change_event_slug_on_save', 10, 1 );

The problem

When I change the event's date, I of course want to update the permalink as well. The trouble is: the event date that I just changed, has not yet been changed in the database, so when updating the permalink on save_post, it still uses the last stored (old) event date. This means I need to save an event (post) twice to update the link.

I have tried hooking to pre_update_post, but that gives me the same problem. I have also looked into all the hooks Tribe plug-in offers, but found none that offers to hook into an update event.

Bottom line: I need to find a way to update the permalink when the post editor's fields are updated (before actually publishing or updating a post), using the fields as they are at the time (and not coming from the database). Any help would be very much appreciated.


UPDATE

Thanks to ahendwh2's answer I fixed it, by hooking into Tribe's tribe_events_update_meta hook, the updated code:

function change_event_slug_on_save( $post_id, $event_data, $event ) {
    //$event_data holds the changed event data, $event is the actual event (post)
    if ( ! wp_is_post_revision( $post_id ) && tribe_is_event($post_id) ) {
        // verify post is not a revision, and an event
        $slug = sanitize_title($event->post_title);
        $newslug = $slug . '-' . tribe_format_date($event_data['EventStartDate'], false, 'j-F-Y');
        if ($event->post_name !== $newslug) {
            // unhook this function to prevent infinite looping
            remove_action( 'tribe_events_update_meta', 'change_event_slug_on_save' );
            // update the post slug
            wp_update_post( array(
                'ID' => $post_id,
                'post_name' => $newslug
            ));
            // re-hook this function
            add_action( 'tribe_events_update_meta', 'change_event_slug_on_save', 10, 3 );
        }
    }
}
add_action( 'tribe_events_update_meta', 'change_event_slug_on_save', 10, 3);

1 Answer 1

1

Try to use the post object provided by the action as the second parameter instead of getting it from database:

function change_event_slug_on_save( $post_id, $post ) {
    ...
}

add_action( 'save_post', 'change_event_slug_on_save', 10, 2 );

With this you can remove the line $post = get_post($post_id);


EDIT: Tribe Events Calendar has it's own actions for saving an event: tribe_events_event_save and tribe_events_update_meta. Since the event date is saved in post_meta you should use the second action:

/**
 * @param int     $event_id The event ID (alias post ID).
 * @param array   $data     The saved meta fields. The new date should be somewhere in this array
 * @param WP_Post $event    The event itself (alias $post).
 */
function change_event_slug_on_save($event_id, $data, $event) {
    ...
}

add_action('tribe_events_update_meta', 'change_event_slug_on_save', 10, 3);
2
  • Good tip, thanks. Unfortunately, that doesn't provide me with a way to access the updated event date, as it is not stored inside the post object. Commented Feb 23, 2018 at 8:21
  • Yes, this is exactly what I needed, thanks! I'll accept your answer and add my updated code to the original question. Commented Feb 23, 2018 at 9:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.