Skip to content

The plugin stores all scheduling data in the existing BuddyPress meta table. No custom tables are created.

{prefix}bp_activity - standard BuddyPress activity table

The date_recorded column stores the target publish datetime when an activity is scheduled. Like every BuddyPress activity date, the value is in UTC (bp_core_current_time()). The member picks a time in the site timezone and the plugin converts it to UTC when saving.

{prefix}bp_activity_meta - standard BuddyPress activity meta table

Meta Key Possible Values Description
_bp_activity_status 'scheduled' Activity is waiting to be published
_bp_activity_status 'publishing' Temporary state set atomically by cron to prevent duplicate processing
$status = bp_activity_get_meta( $activity_id, '_bp_activity_status', true );
// Returns 'scheduled', 'publishing', or '' (empty if not scheduled)

The plugin manages this meta internally. If you write to _bp_activity_status from external code, be aware:

  • Setting it to 'scheduled' on a past-dated activity will cause the cron to publish it on its next run.
  • Setting it to anything other than 'scheduled' or 'publishing' will cause the activity to appear in the feed immediately (because the WHERE condition only excludes meta_value = ‘scheduled’).
  • Setting date_recorded to a future date without also setting _bp_activity_status = 'scheduled' will not hide the activity from feeds.

Both changes must be made together:

global $wpdb;
// Schedule an existing activity for a future time.
$activity_id = 42;
$scheduled_time = get_gmt_from_date( '2026-07-15 14:30:00' ); // Site-local time converted to UTC
$wpdb->update(
"{$wpdb->prefix}bp_activity",
array( 'date_recorded' => $scheduled_time ),
array( 'id' => $activity_id ),
array( '%s' ),
array( '%d' )
);
bp_activity_update_meta( $activity_id, '_bp_activity_status', 'scheduled' );

Get all scheduled activities for a user:

global $wpdb;
$user_id = bp_displayed_user_id();
$activities = $wpdb->get_results(
$wpdb->prepare(
"SELECT a.id, a.date_recorded
FROM {$wpdb->prefix}bp_activity a
LEFT JOIN {$wpdb->prefix}bp_activity_meta am ON ( a.id = am.activity_id )
WHERE a.user_id = %d
AND am.meta_key = '_bp_activity_status'
AND am.meta_value = 'scheduled'
ORDER BY a.date_recorded ASC",
$user_id
)
);

Count scheduled activities for a user:

$count = $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT(a.id)
FROM {$wpdb->prefix}bp_activity a
LEFT JOIN {$wpdb->prefix}bp_activity_meta am ON ( a.id = am.activity_id )
WHERE a.user_id = %d
AND am.meta_key = '_bp_activity_status'
AND am.meta_value = 'scheduled'",
$user_id
)
);

Get activities due to publish right now:

$due = $wpdb->get_results(
$wpdb->prepare(
"SELECT a.id
FROM {$wpdb->prefix}bp_activity a
LEFT JOIN {$wpdb->prefix}bp_activity_meta am ON ( a.id = am.activity_id )
WHERE a.date_recorded <= %s
AND am.meta_key = '_bp_activity_status'
AND am.meta_value = 'scheduled'",
bp_core_current_time() // UTC, same as date_recorded
)
);

Scheduled activities are kept out of the activity feed by one of two mechanisms depending on whether RTMedia is active:

Without RTMedia (default):

A meta_query with NOT EXISTS on _bp_activity_status is injected via the bp_after_activity_get_parse_args filter. This tells BuddyPress’s BP_Activity_Activity::get() to exclude any activity that has the status meta key set, regardless of value.

With RTMedia privacy enabled:

A WHERE subquery condition is injected via bp_activity_get_where_conditions instead, because RTMedia’s own code interferes with meta_query. The condition checks NOT EXISTS (SELECT 1 FROM bp_activity_meta WHERE meta_key = '_bp_activity_status').

Both paths produce equivalent results: scheduled activities appear only in the member’s own “Scheduled Posts” tab, not in any public or group feed.

When an activity is deleted through BuddyPress’s normal path, the plugin clears its scheduling meta via bp_activity_before_delete at priority 10:

bp_activity_delete_meta( $activity_id, '_bp_activity_status' );
bp_activity_delete_meta( $activity_id, '_bp_schedule_activity_title_for_youzify' ); // Legacy meta written by 1.5.x and earlier.

If you delete activities by running direct SQL (bypassing BuddyPress), orphaned meta rows will remain in bp_activity_meta. Clean them up manually or use bp_activity_delete() instead.