Home / Admin / Sugar Calendar Reset The Events Calendar Migration
Duplicate Snippet

Embed Snippet on Your Site

Sugar Calendar Reset The Events Calendar Migration

Adds a one-time button to the WordPress Dashboard that deletes the Sugar Calendar events, calendars, tags and venues that came from The Events Calendar, and lets the migration run again so newer events come over too. Items are matched by name, and tickets and orders are not removed. Back up the database first, and deactivate the snippet after the migration finishes.

<10
Code Preview
php
<?php
/**
 * Sugar Calendar: reset The Events Calendar migration so it can run again.
 *
 * Adds a "Reset TEC migration" notice on the WordPress Dashboard (Sugar Calendar hides
 * other plugins' notices on its own screens). Clicking it:
 * - permanently deletes the Sugar Calendar events, calendars, event tags and venues
 *   whose names match an event, category, tag or venue in The Events Calendar
 *   (that is, what the first migration created), and
 * - clears the "migration completed" flag, so Tools > Migrate shows again.
 *
 * Sugar Calendar items whose names don't match anything in TEC are kept.
 * Edits made in Sugar Calendar to migrated items are lost.
 * Back up the database first. Remove this snippet after the new migration finishes.
 * Works on Lite and Pro (venues exist on Pro only).
 */
add_action( 'admin_notices', function () {
	global $pagenow;
	if (
		! current_user_can( 'manage_options' ) ||
		$pagenow !== 'index.php' ||
		get_option( 'sugar_calendar_tec_migration' ) === false
	) {
		return;
	}
	$url = wp_nonce_url( admin_url( 'admin-post.php?action=sc_reset_tec_migration' ), 'sc_reset_tec_migration' );
	printf(
		'<div class="notice notice-warning"><p>%s</p><p><a class="button" href="%s" onclick="return confirm(\'%s\');">%s</a></p></div>',
		'This deletes the Sugar Calendar events, calendars, tags and venues that match items in The Events Calendar, then lets you run the migration again. Back up your database first.',
		esc_url( $url ),
		esc_js( 'Permanently delete the migrated items and reset the migration?' ),
		'Reset TEC migration'
	);
} );
add_action( 'admin_post_sc_reset_tec_migration', function () {
	if ( ! current_user_can( 'manage_options' ) ) {
		wp_die( 'Not allowed.' );
	}
	check_admin_referer( 'sc_reset_tec_migration' );
	global $wpdb;
	// Names of everything in TEC, read straight from the tables so TEC doesn't need to be active.
	$tec_titles = function ( $post_type ) use ( $wpdb ) {
		return $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_title FROM {$wpdb->posts} WHERE post_type = %s AND post_status NOT IN ( 'trash', 'auto-draft' )", $post_type ) );
	};
	$tec_terms  = function ( $taxonomy, $object_type ) use ( $wpdb ) {
		return $wpdb->get_col( $wpdb->prepare(
			"SELECT DISTINCT t.name FROM {$wpdb->terms} t
			INNER JOIN {$wpdb->term_taxonomy} tt ON tt.term_id = t.term_id
			INNER JOIN {$wpdb->term_relationships} tr ON tr.term_taxonomy_id = tt.term_taxonomy_id
			INNER JOIN {$wpdb->posts} p ON p.ID = tr.object_id
			WHERE tt.taxonomy = %s AND p.post_type = %s",
			$taxonomy,
			$object_type
		) );
	};
	// Sugar Calendar posts whose title matches a TEC title.
	$delete_posts = function ( $post_types, $titles ) use ( $wpdb ) {
		if ( empty( $titles ) ) {
			return 0;
		}
		$ids = $wpdb->get_col(
			"SELECT ID FROM {$wpdb->posts} WHERE post_type IN ( '" . implode( "','", array_map( 'esc_sql', $post_types ) ) . "' )
			AND post_title IN ( '" . implode( "','", array_map( 'esc_sql', $titles ) ) . "' )"
		);
		foreach ( $ids as $id ) {
			wp_delete_post( (int) $id, true );
		}
		return count( $ids );
	};
	// Sugar Calendar terms whose name matches a TEC term name.
	$delete_terms = function ( $taxonomy, $names ) {
		$count = 0;
		foreach ( $names as $name ) {
			$terms = get_terms( [ 'taxonomy' => $taxonomy, 'name' => $name, 'hide_empty' => false ] );
			foreach ( is_array( $terms ) ? $terms : [] as $term ) {
				$count += (int) ( wp_delete_term( $term->term_id, $taxonomy ) === true );
			}
		}
		return $count;
	};
	$deleted = [
		'events'    => $delete_posts( [ 'sc_event', 'sc_recurring_event' ], $tec_titles( 'tribe_events' ) ),
		'venues'    => $delete_posts( [ 'sugarcalendar_venue' ], $tec_titles( 'tribe_venue' ) ),
		'calendars' => $delete_terms( 'sc_event_category', $tec_terms( 'tribe_events_cat', 'tribe_events' ) ),
		'tags'      => $delete_terms( 'sc_event_tags', $tec_terms( 'post_tag', 'tribe_events' ) ),
	];
	// Leftover mapping tables from an unfinished run would make the new run skip events.
	foreach ( [ 'events', 'categories', 'tickets', 'attendees', 'orders', 'venues', 'tags' ] as $table ) {
		$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}sc_migrate_tec_{$table}" ); // phpcs:ignore WordPress.DB
	}
	delete_option( 'sugar_calendar_tec_migration' );
	delete_option( 'sugar_calendar_tec_migration_process' );
	wp_die(
		sprintf(
			'Reset done. Deleted %d events, %d venues, %d calendars and %d tags. <a href="%s">Run the migration again</a>, then remove this snippet.',
			$deleted['events'],
			$deleted['venues'],
			$deleted['calendars'],
			$deleted['tags'],
			esc_url( admin_url( 'admin.php?page=sc-tools&section=migrate&importer=the-events-calendar' ) )
		),
		'TEC migration reset',
		[ 'response' => 200 ]
	);
} );

Comments

Add a Comment