| @@ -38,23 +38,32 @@ | ||
| 38 | 38 | // Per-user OAuth state transients (prefix match). A direct query is the |
| 39 | 39 | // only way to bulk-delete prefix-matched transients; caching and the |
| 40 | 40 | // standard API are not applicable during uninstall. |
| 41 | 41 | global $wpdb; |
| 42 | -// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching | |
| 43 | -$wpdb->query( | |
| 44 | - $wpdb->prepare( | |
| 45 | - "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s OR option_name LIKE %s", | |
| 46 | - $wpdb->esc_like( '_transient_zip_ai_oauth_state_' ) . '%', | |
| 47 | - $wpdb->esc_like( '_transient_timeout_zip_ai_oauth_state_' ) . '%' | |
| 48 | - ) | |
| 42 | +/** | |
| 43 | + * Narrowed type for `$wpdb`. | |
| 44 | + * | |
| 45 | + * @var \wpdb $wpdb | |
| 46 | + */ | |
| 47 | +$zip_ai_delete_transients_query = $wpdb->prepare( | |
| 48 | + 'DELETE FROM %i WHERE option_name LIKE %s OR option_name LIKE %s', | |
| 49 | + $wpdb->options, | |
| 50 | + $wpdb->esc_like( '_transient_zip_ai_oauth_state_' ) . '%', | |
| 51 | + $wpdb->esc_like( '_transient_timeout_zip_ai_oauth_state_' ) . '%' | |
| 49 | 52 | ); |
| 53 | +if ( is_string( $zip_ai_delete_transients_query ) ) { | |
| 54 | + // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared -- built via $wpdb->prepare() with a %i table placeholder above; guarded is_string. | |
| 55 | + $wpdb->query( $zip_ai_delete_transients_query ); | |
| 56 | +} | |
| 50 | 57 | |
| 51 | 58 | // Capability removal from every role. |
| 59 | +// `manage_zip_mcp_assistant` is the capability the plugin adds today; | |
| 60 | +// `manage_zip_ai_assistant` may linger from older releases. | |
| 52 | 61 | $zip_ai_roles = wp_roles(); |
| 53 | -if ( isset( $zip_ai_roles->role_objects ) && is_array( $zip_ai_roles->role_objects ) ) { | |
| 54 | - foreach ( $zip_ai_roles->role_objects as $zip_ai_role ) { | |
| 55 | - if ( $zip_ai_role->has_cap( 'manage_zip_ai_assistant' ) ) { | |
| 56 | - $zip_ai_role->remove_cap( 'manage_zip_ai_assistant' ); | |
| 62 | +foreach ( $zip_ai_roles->role_objects as $zip_ai_role ) { | |
| 63 | + foreach ( array( 'manage_zip_mcp_assistant', 'manage_zip_ai_assistant' ) as $zip_ai_cap ) { | |
| 64 | + if ( $zip_ai_role->has_cap( $zip_ai_cap ) ) { | |
| 65 | + $zip_ai_role->remove_cap( $zip_ai_cap ); | |
| 57 | 66 | } |
| 58 | 67 | } |
| 59 | 68 | } |
| 60 | 69 | |