Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save chikaibeneme/42f78ed4be05bfbc7e2404e327a3a2e2 to your computer and use it in GitHub Desktop.

Select an option

Save chikaibeneme/42f78ed4be05bfbc7e2404e327a3a2e2 to your computer and use it in GitHub Desktop.
Temporary WordPress admin-only functions.php snippet to rebuild The Events Calendar Custom Tables v1 data after missing wp_tec_events / wp_tec_occurrences tables or stale migration state.
/**
* Temporary repair snippet for The Events Calendar Custom Tables v1.
*
* Use when TEC events exist as `tribe_events` posts but do not appear on the
* frontend because the `wp_tec_events` / `wp_tec_occurrences` custom tables
* are missing, empty, or out of sync after manual database cleanup.
*
* This rebuilds the TEC custom tables from existing event posts. It does not
* delete event posts. Remove this snippet immediately after a successful run.
and how to run it
Confirm there is a fresh database backup.
Add the snippet temporarily to the active theme’s functions.php.
Log in to WordPress as an admin.
Visit this URL, replacing the domain if needed:
https://domain.com/wp-admin/?tec_ct1_repair=run
Wait for the plain-text output to finish. A successful run should end with something like:
Done.
Phase: migration-complete
Remaining: 0
Failures: 0
wp_tec_events rows: 146
wp_tec_occurrences rows: 146
Confirm the events show on the frontend calendar.
Remove the snippet from functions.php immediately after the successful run.
*/
add_action( 'admin_init', function () {
if ( empty( $_GET['tec_ct1_repair'] ) || $_GET['tec_ct1_repair'] !== 'run' ) {
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( 'Not allowed.' );
}
header( 'Content-Type: text/plain; charset=utf-8' );
@set_time_limit( 0 );
$required = [
'TEC\\Events\\Custom_Tables\\V1\\Schema_Builder\\Schema_Builder',
'TEC\\Events\\Custom_Tables\\V1\\Migration\\State',
'TEC\\Events\\Custom_Tables\\V1\\Migration\\Events',
'TEC\\Events\\Custom_Tables\\V1\\Migration\\Process',
'TEC\\Events\\Custom_Tables\\V1\\Migration\\Process_Worker',
'TEC\\Events\\Custom_Tables\\V1\\Migration\\Reports\\Event_Report',
'TEC\\Events\\Custom_Tables\\V1\\Tables\\Events',
'TEC\\Events\\Custom_Tables\\V1\\Tables\\Occurrences',
];
foreach ( $required as $class ) {
if ( ! class_exists( $class ) ) {
wp_die( "Missing required TEC class: {$class}" );
}
}
global $wpdb;
$schema_class = 'TEC\\Events\\Custom_Tables\\V1\\Schema_Builder\\Schema_Builder';
$state_class = 'TEC\\Events\\Custom_Tables\\V1\\Migration\\State';
$events_class = 'TEC\\Events\\Custom_Tables\\V1\\Migration\\Events';
$process_class = 'TEC\\Events\\Custom_Tables\\V1\\Migration\\Process';
$worker_class = 'TEC\\Events\\Custom_Tables\\V1\\Migration\\Process_Worker';
$report_class = 'TEC\\Events\\Custom_Tables\\V1\\Migration\\Reports\\Event_Report';
$events_table_class = 'TEC\\Events\\Custom_Tables\\V1\\Tables\\Events';
$occurrences_table_class = 'TEC\\Events\\Custom_Tables\\V1\\Tables\\Occurrences';
$schema = tribe( $schema_class );
$state = tribe( $state_class );
$events = tribe( $events_class );
$process = tribe( $process_class );
$worker = tribe( $worker_class );
echo "Starting TEC Custom Tables repair...\n";
update_option( 'tec_custom_tables_v1_active', true );
echo "Clearing queued migration actions...\n";
$process->empty_process_queue();
echo "Creating/updating custom tables...\n";
$schema->up( true );
echo "Emptying TEC custom tables only. Event posts are not deleted.\n";
$schema->empty_custom_tables();
echo "Clearing TEC migration bookkeeping meta...\n";
delete_metadata( 'post', 0, $report_class::META_KEY_MIGRATION_LOCK_HASH, '', true );
delete_metadata( 'post', 0, $report_class::META_KEY_REPORT_DATA, '', true );
delete_metadata( 'post', 0, $report_class::META_KEY_MIGRATION_PHASE, '', true );
delete_metadata( 'post', 0, $report_class::META_KEY_MIGRATION_CATEGORY, '', true );
$state->set( 'phase', $state_class::PHASE_MIGRATION_IN_PROGRESS );
$state->set( 'started_timestamp', time() );
$state->set( 'complete_timestamp', null );
$state->save();
$batch = 25;
$max_passes = 1000;
$pass = 0;
while ( $events->get_total_events_remaining() > 0 && $pass < $max_passes ) {
$pass++;
$before = $events->get_total_events_remaining();
$migrated = $worker->migrate_many_events( $batch );
$after = $events->get_total_events_remaining();
$failures = $events->get_total_events_with_failure();
echo "Pass {$pass}: migrated {$migrated}; remaining {$before} -> {$after}; failures {$failures}\n";
@flush();
if ( $failures > 0 || $migrated === 0 ) {
break;
}
}
$worker->check_phase();
$remaining = $events->get_total_events_remaining();
$in_progress = $events->get_total_events_in_progress();
$failures = $events->get_total_events_with_failure();
if ( $remaining === 0 && $in_progress === 0 && $failures === 0 ) {
$state->set( 'phase', $state_class::PHASE_MIGRATION_COMPLETE );
$state->set( 'complete_timestamp', time() );
$state->save();
}
wp_cache_flush();
if ( function_exists( 'rocket_clean_domain' ) ) {
rocket_clean_domain();
}
$tec_events = $events_table_class::table_name( true );
$tec_occurrences = $occurrences_table_class::table_name( true );
$event_rows = $wpdb->get_var( "SELECT COUNT(*) FROM `{$tec_events}`" );
$occurrence_rows = $wpdb->get_var( "SELECT COUNT(*) FROM `{$tec_occurrences}`" );
echo "\nDone.\n";
echo "Phase: " . $state->get_phase() . "\n";
echo "Total eligible events: " . $events->get_total_events() . "\n";
echo "Remaining: {$remaining}\n";
echo "Failures: {$failures}\n";
echo "{$tec_events} rows: {$event_rows}\n";
echo "{$tec_occurrences} rows: {$occurrence_rows}\n";
if ( $failures > 0 ) {
echo "\nSome events failed migration. Check Events > Settings > Upgrade for the report, or review the failed event data.\n";
}
exit;
} );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment