-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuninstall.php
More file actions
105 lines (94 loc) · 3.32 KB
/
Copy pathuninstall.php
File metadata and controls
105 lines (94 loc) · 3.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
/**
* Plugin uninstall handler.
*
* Fired by WordPress when the plugin is deleted (not just deactivated).
* On a multisite network, walks every subsite in every network and drops
* AbilityGuard's four tables, options, and approval capability on each.
* On a single site, runs the same teardown in place.
*
* `register_uninstall_hook()` runs WITHOUT a `$network_wide` argument -
* by the time uninstall fires the plugin's main file may have already been
* deleted, so we rediscover the multisite topology via `is_multisite()` +
* `get_sites()` and require CapabilityManager directly.
*
* @package AbilityGuard
*/
declare( strict_types=1 );
defined( 'WP_UNINSTALL_PLUGIN' ) || exit;
require_once __DIR__ . '/src/Approval/CapabilityManager.php';
/**
* Drop tables, clear cron, remove the approval capability for the
* currently-switched-to subsite.
*/
function abilityguard_uninstall_single_site(): void {
global $wpdb;
wp_clear_scheduled_hook( 'abilityguard_retention_prune' );
AbilityGuard\Approval\CapabilityManager::remove_from_all_roles();
$tables = array(
$wpdb->prefix . 'abilityguard_log',
$wpdb->prefix . 'abilityguard_log_meta',
$wpdb->prefix . 'abilityguard_snapshots',
$wpdb->prefix . 'abilityguard_approvals',
$wpdb->prefix . 'abilityguard_approval_stages',
);
foreach ( $tables as $table ) {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
$wpdb->query( "DROP TABLE IF EXISTS {$table}" );
}
delete_option( 'abilityguard_db_version' );
delete_option( 'abilityguard_last_pruned' );
delete_option( 'abilityguard_last_pruned_count' );
}
/**
* Best-effort purge of the FileBlobStore staging directory under
* uploads/. Shared across the whole install - purge once, not per
* subsite. Failures here are non-fatal.
*/
function abilityguard_uninstall_purge_staging(): void {
$uploads = wp_upload_dir( null, false );
$basedir = is_array( $uploads ) && ! empty( $uploads['basedir'] ) && is_string( $uploads['basedir'] )
? $uploads['basedir']
: '';
if ( '' === $basedir ) {
return;
}
$dir = trailingslashit( $basedir ) . 'abilityguard-mcp';
if ( ! is_dir( $dir ) ) {
return;
}
$entries = scandir( $dir );
if ( false === $entries ) {
return;
}
foreach ( $entries as $entry ) {
if ( '.' === $entry || '..' === $entry ) {
continue;
}
// phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink, WordPress.PHP.NoSilencedErrors.Discouraged
@unlink( trailingslashit( $dir ) . $entry );
}
// phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged, WordPress.WP.AlternativeFunctions.file_system_operations_rmdir -- best-effort uninstall, WP_Filesystem unavailable post-deactivation.
@rmdir( $dir );
}
if ( is_multisite() && function_exists( 'get_sites' ) ) {
// Walk every subsite in every network. Plugin deletion means uninstall;
// orphan tables on subsites the operator may not even remember about
// would just rot in the database.
$abilityguard_site_ids = get_sites(
array(
'fields' => 'ids',
'number' => 0,
)
);
if ( is_array( $abilityguard_site_ids ) ) {
foreach ( $abilityguard_site_ids as $abilityguard_site_id ) {
switch_to_blog( (int) $abilityguard_site_id );
abilityguard_uninstall_single_site();
restore_current_blog();
}
}
} else {
abilityguard_uninstall_single_site();
}
abilityguard_uninstall_purge_staging();