• Dear Events Manager team,

    recently we stumbled over a problem in combination with the latest version of WPML. WPML uses the action publish_future_post as well as you do. When saving a post the action is scheduled

    $time && wp_schedule_single_event( $time, 'publish_future_post', array( $translated_pid ) ); in /wp-content/plugins/sitepress-multilingual-cms/inc/post-translation/wpml-post-synchronization.class.php which will then trigger your function

    public static function publish_future_post($post_id){
    global $EM_Event;
    $post_type = get_post_type($post_id);
    $is_post_type = Archetypes::is_repeating( $post_type ) ? Archetypes::get_repeating_archetype( $post_type ) : $post_type;
    $saving_status = !in_array(get_post_status($post_id), array('trash','auto-draft')) && !defined('DOING_AUTOSAVE');
    if(!defined('UNTRASHING_'.$post_id) && $is_post_type && $saving_status ){
    $EM_Event = em_get_event($post_id, 'post_id');
    $EM_Event->set_status(1);
    }
    }

    The problem here is, that this function does not check if the post_type belongs to events_manager and sets the status of the post which then deletes the post_name of the previously saved post by executing

    $wpdb->update( $wpdb->posts, array( 'post_name' => $this->post_name ), array( 'ID' => $this->post_id ) );

    Would be great if you could apply a fix here.

    All the best
    Sunlime Web Innovations GmbH

Viewing 11 replies - 1 through 11 (of 11 total)
  • I reported this problem to the plugin owner so hopefully it will be fixed soon. I think the following change will fix the problem.

    Change line 49 of wp-content/plugins/events-manager/classes/em-event-post.php from this:

            $is_post_type = Archetypes::is_repeating( $post_type ) ? Archetypes::get_repeating_archetype( $post_type ) : $post_type;

    To this:

            $is_post_type = (Archetypes::is_repeating( $post_type ) ? Archetypes::get_repeating_archetype( $post_type ) : ($post_type == "event")) ? $post_type : false;

    @joneiseman thank you for your reply and reporting the problem – yes, checking for the type will fix the problem. So hope, that the owner will fix it asap.

    All the best
    Sunlime Web Innovations GmbH

    James Maiden

    (@reallygreenjames)

    Thanks both for the detail here. For me, the impact is that the slug gets cleared for any new content published in the second language, leading to them all effectively being directed to the home page.

    We’re seeing the same issue and the fix does work across our platform. Has anyone heard back from the developer confirming that the issue is going to be fixed? I had an issue with caching that took a year of bugging to get it addressed so I do have a contact at the company now if needed.

    James Maiden

    (@reallygreenjames)

    I reported it in the pro forums and the person there told me yesterday that he was “escalating it with the developers”.

    The problem isn’t the if check, it’s that $is_post_type isn’t a boolean. Since it usually holds a non-empty string, the condition runs for post types outside Events Manager. The code suggested earlier “works” but it edits plugin files directly and makes $is_post_type pull double duty.

    A safer fix is to unhook EM’s handler and replace it with a wrapper that sets $is_post_type as a true/false value. This way the condition works exactly as intended — only for repeating archetypes — and you don’t have to edit plugin files (so the fix survives updates).

    Drop this into your theme’s functions.php or, better, a small MU-plugin:

    /**
    * Remove EM's default handler and reattach our own.
    *
    * @return void
    */
    function em_fix_future_publish_scope() {
    remove_action(
    'publish_future_post',
    array( 'EM_Event_Post', 'publish_future_post' ),
    10
    );
    add_action( 'publish_future_post', 'em_future_publish_handler', 10, 1 );
    }
    add_action( 'plugins_loaded', 'em_fix_future_publish_scope', 20 );

    /**
    * Replacement handler for scheduled publish.
    *
    * @param int $post_id Post ID being published by WP-Cron.
    * @return void
    */
    function em_future_publish_handler( $post_id ) {
    global $EM_Event;
    $post_type = get_post_type( $post_id );

    // Corrected boolean check: true if this post type is a repeating archetype managed by EM.
    $is_post_type = (bool) Archetypes::is_repeating( $post_type ) && Archetypes::get_repeating_archetype( $post_type );

    $saving_status = ! in_array( get_post_status( $post_id ), array( 'trash', 'auto-draft' ), true )
    && ! defined( 'DOING_AUTOSAVE' );

    if ( ! defined( 'UNTRASHING_' . $post_id ) && $is_post_type && $saving_status ) {
    $EM_Event = em_get_event( $post_id, 'post_id' );
    if ( $EM_Event instanceof \EM_Event ) {
    $EM_Event->set_status( 1 );
    }
    }
    }

    Why this is better

    • $is_post_type is now a proper boolean, not a string.
    • The if guard works as intended: only runs for EM repeating archetypes.
    • No need to edit plugin files — this survives plugin updates.
    • Clearer, easier to maintain, and future-proof against Archetypes changes.
    curtismchale

    (@curtismchale)

    This is still happening with 7.2.2.1 and the latest fix for bad UI rendering killing everything so we’re still hacking around it with the code above.

    Hey @misfist , thanks for sharing your original approach!

    We’ve confirmed that the issue still occurs in Events Manager 7.2.2.1: the plugin’s publish_future_post handler is applied globally, which can affect scheduled posts outside Events Manager (like standard posts) and sometimes clear their slugs.

    We built on your idea — unhooking EM’s handler and reattaching it only for EM post types — and added a few safeguards to make it safer and more maintainable. The improved version is below.

    <?php
    /*
    Plugin Name: Events Manager – Scoped publish_future_post Hook
    Description: Restricts Events Manager's publish_future_post handler to its own custom post types only, preventing interference with standard posts.
    Version: 1.0.1
    Author: (anonymous community patch)
    */

    /**
    * Optional debug flag:
    * You can enable verbose logging by defining this constant in wp-config.php:
    * define('EM_SCOPE_DEBUG', true);
    */
    if ( ! function_exists('em_scope_log') ) {
    function em_scope_log($msg) {
    if (defined('EM_SCOPE_DEBUG') && EM_SCOPE_DEBUG) {
    error_log('[' . gmdate('Y-m-d H:i:s') . "Z] " . $msg . "\n", 3, WP_CONTENT_DIR . '/debug-em-scope.log');
    }
    }
    }

    /**
    * Ensures the publish_future_post hook from Events Manager
    * only runs for its own CPTs (event, event-recurring, location).
    *
    * This prevents EM from touching regular WordPress posts
    * or other custom post types during scheduled publishing.
    */
    add_action('plugins_loaded', function () {
    static $wired = false;
    if ($wired) {
    return; // Avoid reattaching multiple times per process.
    }

    // Skip if Events Manager is not active.
    if ( ! class_exists('EM_Event_Post') ) {
    return;
    }

    // Remove EM's default hook safely.
    $priority = has_action('publish_future_post', ['EM_Event_Post', 'publish_future_post']);
    if (false !== $priority) {
    remove_action('publish_future_post', ['EM_Event_Post', 'publish_future_post'], $priority);
    }

    // Define Events Manager post types (with fallbacks).
    $allowed = array_unique(array_filter([
    defined('EM_POST_TYPE_EVENT') ? EM_POST_TYPE_EVENT : 'event',
    defined('EM_POST_TYPE_EVENT_RECURRENCE') ? EM_POST_TYPE_EVENT_RECURRENCE : 'event-recurring',
    defined('EM_POST_TYPE_LOCATION') ? EM_POST_TYPE_LOCATION : 'location',
    ]));

    // Reattach a scoped handler for publish_future_post.
    add_action('publish_future_post', function ($post_id) use ($allowed) {
    $type = get_post_type($post_id);

    // Ignore non-EM post types.
    if ( ! $type || ! in_array($type, $allowed, true) ) {
    em_scope_log("EM scope: ignored publish_future_post for ID={$post_id} type={$type}");
    return;
    }

    // Delegate to EM only for its own post types.
    if (is_callable(['EM_Event_Post', 'publish_future_post'])) {
    \EM_Event_Post::publish_future_post($post_id);
    em_scope_log("EM scope: delegated to EM_Event_Post::publish_future_post for ID={$post_id} type={$type}");
    }
    }, 10, 1);

    $wired = true;
    em_scope_log('EM scope: handler restricted to CPTs: ' . implode(',', $allowed));
    }, 20);

    Why this version is safer:
    – Runs only for EM post types (event, event-recurring, location)
    – Checks if EM_Event_Post exists before modifying hooks
    – Prevents multiple re-hooks in the same process
    – Avoids dependency on Archetypes, preventing fatals if EM changes internally
    – Supports optional debug logging via define(‘EM_SCOPE_DEBUG’, true);

    This fix works as a small MU-plugin, requires no edits to plugin files, and fully resolves the missing-slug issue on scheduled posts.

    Thanks again for your clear explanation.

    code222

    (@code222)

    the dev version 7.2.2.3 ha fixed this issue or we need to install this plugin anyway ?

    Wondering the same. When is it applied to the stable version?

    Plugin Author Marcus

    (@msykes)

    Hello, sorry for the delay on this.

    The bug cropped up when we added Archetypes as our code triggered ‘true’ for all post types. The latest update 7.2.3 should solve this, it should also account for any archetypes you add via the settings page.

    Will mark resolved.

Viewing 11 replies - 1 through 11 (of 11 total)

You must be logged in to reply to this topic.