PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.13
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.13
1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 All 211 releases
← All changes | includes/plugin/class-charitable-uninstall.php +50 -0 1.8.12.1 → 1.8.13 View file →
@@ -38,8 +38,9 @@
38 38 $this->remove_caps();
39 39 $this->remove_post_data();
40 40 $this->remove_tables();
41 41 $this->remove_settings();
42 + $this->remove_abilities_data();
42 43
43 44 do_action( 'charitable_uninstall' );
44 45 }
45 46 }
@@ -122,8 +123,57 @@
122 123
123 124 /* Stop Charitable from re-adding the notices transient. */
124 125 if ( function_exists( 'charitable_get_admin_notices' ) ) {
125 126 remove_action( 'shutdown', array( charitable_get_admin_notices(), 'shutdown' ) );
127 + }
128 +
129 + /*
130 + * The `ai_mcp_write_enabled` setting (Charitable_Tools_Ai_Mcp::WRITE_SETTING_KEY)
131 + * needs NO separate delete_option() call. It is not its own option -
132 + * it is a key nested inside the `charitable_settings` array, written by
133 + * ajax_toggle_write() as $settings['ai_mcp_write_enabled'], and the
134 + * blanket delete_option( 'charitable_settings' ) above already removes
135 + * it. Any future AI setting nested the same way needs no change here
136 + * either. (1.8.13 briefly also stored `ai_mcp_write_scopes` in that
137 + * array; it was removed before release, and the blanket delete covered
138 + * it while it existed.)
139 + *
140 + * @since 1.8.13
141 + */
142 + }
143 +
144 + /**
145 + * Remove data added by the Abilities API integration (1.8.13).
146 + *
147 + * Scoped to what THIS feature added, not a blanket log wipe.
148 + *
149 + * `charitable_abilities_usage` (Charitable_Abilities_Usage::OPTION) is a
150 + * dedicated top-level option, never nested inside `charitable_settings`,
151 + * so remove_settings() above cannot reach it - it needs its own line.
152 + *
153 + * Log rows are pruned by TYPE rather than the whole table being
154 + * dropped: `charitable_logs` holds every log type Charitable writes,
155 + * most of them unrelated to this feature, and remove_tables() above
156 + * never drops that table at all (logs are not otherwise touched on
157 + * uninstall). Guarded on the table existing, since a site that never
158 + * triggered log_create_table() (Charitable_Log_DB::create_table()) has
159 + * no table for a bare DELETE to run against.
160 + *
161 + * @since 1.8.13
162 + *
163 + * @global WPDB $wpdb
164 + * @return void
165 + */
166 + private function remove_abilities_data() {
167 + global $wpdb;
168 +
169 + delete_option( 'charitable_abilities_usage' );
170 +
171 + $table = $wpdb->prefix . 'charitable_logs';
172 +
173 + if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) === $table ) { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
174 + // $table is $wpdb->prefix . 'charitable_logs' and carries no user input; MySQL cannot bind a table identifier as a prepared parameter, so interpolation is the only option.
175 + $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE types = %s", 'abilities' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter
126 176 }
127 177 }
128 178 }
129 179