Skip to content

Commit ea96013

Browse files
Copilotswissspidy
andauthored
Add opt-in site delete table-prefix cleanup flag
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
1 parent 1f48ff9 commit ea96013

2 files changed

Lines changed: 72 additions & 0 deletions

File tree

‎features/site.feature‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,41 @@ Feature: Manage sites in a multisite installation
7878
When I try the previous command again
7979
Then the return code should be 1
8080

81+
@skip-windows
82+
Scenario: Delete a site by id and remove all prefixed tables
83+
Given a WP multisite subdirectory install
84+
85+
When I run `wp site create --slug=first --porcelain`
86+
Then STDOUT should be a number
87+
And save STDOUT as {SITE_ID}
88+
And I run `wp db query "CREATE TABLE wp_{SITE_ID}_custom_data (id INTEGER PRIMARY KEY);"`
89+
And I run `wp site delete {SITE_ID} --yes --delete-tables-with-prefix`
90+
Then STDOUT should contain:
91+
"""
92+
Success: The site at '
93+
"""
94+
95+
When I run `wp db query "CREATE TABLE wp_{SITE_ID}_custom_data (id INTEGER PRIMARY KEY);"`
96+
Then STDOUT should be empty
97+
And the return code should be 0
98+
And I run `wp db query "DROP TABLE wp_{SITE_ID}_custom_data;"`
99+
100+
@skip-windows
101+
Scenario: Deleting a site cannot combine keep-tables with delete-tables-with-prefix
102+
Given a WP multisite subdirectory install
103+
104+
When I run `wp site create --slug=first --porcelain`
105+
Then STDOUT should be a number
106+
And save STDOUT as {SITE_ID}
107+
108+
When I try `wp site delete {SITE_ID} --yes --keep-tables --delete-tables-with-prefix`
109+
Then STDERR should be:
110+
"""
111+
Error: The '--keep-tables' and '--delete-tables-with-prefix' flags cannot be used together.
112+
"""
113+
And STDOUT should be empty
114+
And the return code should be 1
115+
81116
@skip-windows
82117
Scenario: Filter site list
83118
Given a WP multisite install

‎src/Site_Command.php‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,9 @@ public function empty_( $args, $assoc_args ) {
288288
* [--keep-tables]
289289
* : Delete the blog from the list, but don't drop its tables.
290290
*
291+
* [--delete-tables-with-prefix]
292+
* : Delete all tables with the site's database table prefix after deleting the site.
293+
*
291294
* ## EXAMPLES
292295
*
293296
* $ wp site delete 123
@@ -299,6 +302,10 @@ public function delete( $args, $assoc_args ) {
299302
WP_CLI::error( 'This is not a multisite installation.' );
300303
}
301304

305+
if ( Utils\get_flag_value( $assoc_args, 'keep-tables' ) && Utils\get_flag_value( $assoc_args, 'delete-tables-with-prefix' ) ) {
306+
WP_CLI::error( "The '--keep-tables' and '--delete-tables-with-prefix' flags cannot be used together." );
307+
}
308+
302309
if ( isset( $assoc_args['slug'] ) ) {
303310
$blog_id = get_id_from_blogname( $assoc_args['slug'] );
304311
if ( null === $blog_id ) {
@@ -329,9 +336,39 @@ public function delete( $args, $assoc_args ) {
329336

330337
wpmu_delete_blog( (int) $blog->blog_id, ! Utils\get_flag_value( $assoc_args, 'keep-tables' ) );
331338

339+
if ( Utils\get_flag_value( $assoc_args, 'delete-tables-with-prefix' ) ) {
340+
$this->drop_tables_with_prefix( (int) $blog->blog_id );
341+
}
342+
332343
WP_CLI::success( "The site at '{$site_url}' was deleted." );
333344
}
334345

346+
/**
347+
* Drops all database tables for a site prefix.
348+
*
349+
* @param int $blog_id Site ID.
350+
*/
351+
private function drop_tables_with_prefix( $blog_id ) {
352+
global $wpdb;
353+
354+
$prefix_like = $wpdb->esc_like( $wpdb->get_blog_prefix( $blog_id ) ) . '%';
355+
$tables = $wpdb->get_col( $wpdb->prepare( 'SHOW TABLES LIKE %s', $prefix_like ) );
356+
357+
if ( empty( $tables ) ) {
358+
return;
359+
}
360+
361+
$tables = array_map(
362+
static function ( $table ) {
363+
return '`' . str_replace( '`', '``', $table ) . '`';
364+
},
365+
$tables
366+
);
367+
368+
// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Table identifiers are escaped and cannot be passed as placeholders.
369+
$wpdb->query( 'DROP TABLE IF EXISTS ' . implode( ', ', $tables ) );
370+
}
371+
335372
/**
336373
* Gets details about a site in a multisite installation.
337374
*

0 commit comments

Comments
 (0)