prefix . 'groupentry_control'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Native uninstall must remove the opted-in plugin data and permissions from storage. $found = $wpdb->get_var($wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($control))); if ($wpdb->last_error) { wp_die(esc_html__('GroupEntry uninstall could not read the database. Retry after checking database availability.', 'groupentry')); } if ($found !== $control) { return; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Native uninstall must remove the opted-in plugin data and permissions from storage. $raw = $wpdb->get_var($wpdb->prepare('SELECT settings FROM %i WHERE id=1',$control)); if ($wpdb->last_error) { wp_die(esc_html__('GroupEntry uninstall could not read the database. Retry after checking database availability.', 'groupentry')); } $settings = is_string($raw) ? json_decode($raw, true) : null; // Require an explicit saved boolean. Missing, legacy or malformed settings keep data. if (!is_array($settings) || ($settings['delete_on_uninstall'] ?? null) !== true) { return; } // Remove only this plugin's role and capability; keep accounts and unrelated access. $cursor = 0; do { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Native uninstall must remove the opted-in plugin data and permissions from storage. $users = $wpdb->get_col($wpdb->prepare('SELECT user_id FROM %i WHERE meta_key=%s AND meta_value LIKE %s AND user_id>%d ORDER BY user_id LIMIT 100', $wpdb->usermeta, $wpdb->prefix . 'capabilities', '%' . $wpdb->esc_like('groupentry_checkin') . '%', $cursor)); if ($wpdb->last_error) { wp_die(esc_html__('GroupEntry uninstall could not remove staff access. Retry after checking database availability.', 'groupentry')); } foreach ($users as $id) { $cursor = (int)$id; $user = get_user_by('id', $cursor); if ($user) { $user->remove_role('groupentry_checkin_staff'); $user->remove_cap('groupentry_checkin'); } } } while (count($users) === 100); foreach (array_keys(wp_roles()->roles) as $name) { $role = get_role($name); if ($role) { $role->remove_cap('groupentry_checkin'); } } remove_role('groupentry_checkin_staff'); // Database-backed staff sessions can be enumerated; cache-only sessions expire naturally. // Deleting their access-code option below invalidates both kinds immediately. $cursor = 0; do { // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Native uninstall must remove the opted-in plugin data and permissions from storage. $options = $wpdb->get_results($wpdb->prepare('SELECT option_id,option_name FROM %i WHERE option_id>%d AND (option_name LIKE %s OR option_name LIKE %s) ORDER BY option_id LIMIT 100', $wpdb->options, $cursor, $wpdb->esc_like('_transient_groupentry_staff_') . '%', $wpdb->esc_like('_transient_timeout_groupentry_staff_') . '%')); if ($wpdb->last_error) { wp_die(esc_html__('GroupEntry uninstall could not remove staff sessions. Retry after checking database availability.', 'groupentry')); } foreach ($options as $option) { $cursor = (int)$option->option_id; if (preg_match('/^_transient_(?:timeout_)?(groupentry_staff_[a-f0-9]{64})$/D', $option->option_name, $match)) { delete_transient($match[1]); } } } while (count($options) === 100); $tables = []; foreach (['participants', 'audit', 'rates', 'registrations', 'slots', 'control'] as $name) { $tables[] = $wpdb->prefix . 'groupentry_' . $name; } // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange -- Native uninstall must remove the opted-in plugin data and permissions from storage. if ($wpdb->query($wpdb->prepare('DROP TABLE IF EXISTS ' . implode(',',array_fill(0,count($tables),'%i')),$tables)) === false) { wp_die(esc_html__('GroupEntry uninstall could not remove its database tables. Retry after checking database availability.', 'groupentry')); } delete_option('groupentry_staff_access'); delete_option('groupentry_schema_version'); })();