Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions data-machine.php
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,9 @@ function datamachine_activate_for_site() {
// Migrate per-site agents to network-scoped tables (idempotent).
datamachine_migrate_agents_to_network_scope();

// Drop orphaned per-site agent tables left behind by the migration (idempotent).
datamachine_drop_orphaned_agent_tables();

// Regenerate SITE.md with enriched content and clean up legacy SiteContext transient.
datamachine_regenerate_site_md();
delete_transient( 'datamachine_site_context_data' );
Expand Down
74 changes: 74 additions & 0 deletions inc/migrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -2224,3 +2224,77 @@ function datamachine_migrate_agents_to_network_scope() {
);
}
}

/**
* Drop orphaned per-site agent tables after network migration.
*
* After datamachine_migrate_agents_to_network_scope() has consolidated
* all agent data into the network-scoped tables (base_prefix), the
* per-site copies (e.g. c8c_7_datamachine_agents) serve no purpose.
* They can't be queried (all repositories use base_prefix) and their
* presence is confusing.
*
* This function drops the orphaned per-site agent, access, and token
* tables for every subsite. Idempotent — safe to call multiple times.
* Only runs on multisite after the network migration flag is set.
*
* @since 0.43.0
*/
function datamachine_drop_orphaned_agent_tables() {
if ( ! is_multisite() ) {
return;
}

if ( ! get_site_option( 'datamachine_agents_network_migrated' ) ) {
return;
}

if ( get_site_option( 'datamachine_orphaned_agent_tables_dropped' ) ) {
return;
}

global $wpdb;

$table_suffixes = array(
'datamachine_agents',
'datamachine_agent_access',
'datamachine_agent_tokens',
);

$sites = get_sites( array( 'fields' => 'ids' ) );
$dropped = 0;

foreach ( $sites as $blog_id ) {
$site_prefix = $wpdb->get_blog_prefix( $blog_id );

// Skip the main site — its prefix IS the base_prefix,
// so these are the canonical network tables.
if ( $site_prefix === $wpdb->base_prefix ) {
continue;
}

foreach ( $table_suffixes as $suffix ) {
$table_name = $site_prefix . $suffix;

// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) );

if ( $exists ) {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$wpdb->query( "DROP TABLE `{$table_name}`" );
++$dropped;
}
}
}

update_site_option( 'datamachine_orphaned_agent_tables_dropped', true );

if ( $dropped > 0 ) {
do_action(
'datamachine_log',
'info',
'Dropped orphaned per-site agent tables after network migration',
array( 'tables_dropped' => $dropped )
);
}
}
Loading