array( 'afridirect_form', 'afridirect_payment', 'afridirect_request' ), 'post_status' => array( 'publish', 'draft', 'auto-draft', 'pending', 'private', 'future', 'trash' ), 'posts_per_page' => -1, 'fields' => 'ids', 'no_found_rows' => true, ) ); foreach ( $afridirect_post_ids as $afridirect_post_id ) { wp_delete_post( $afridirect_post_id, true ); } // Remove the pages the plugin created, but only if they still contain nothing except its shortcode. $afridirect_pages = array( 'afridirect_pending_page_id' => '[afridirect_payment_pending]', 'afridirect_receipt_page_id' => '[afridirect_payment_receipt]', 'afridirect_request_page_id' => '[afridirect_payment_request]', ); foreach ( $afridirect_pages as $afridirect_option => $afridirect_shortcode ) { $afridirect_page_id = (int) get_option( $afridirect_option, 0 ); $afridirect_page = $afridirect_page_id ? get_post( $afridirect_page_id ) : null; if ( $afridirect_page && 'page' === $afridirect_page->post_type && trim( $afridirect_page->post_content ) === $afridirect_shortcode ) { wp_delete_post( $afridirect_page_id, true ); } } // Delete plugin options. delete_option( 'woocommerce_afridirect_payment_settings' ); delete_option( 'afridirect_payment_methods' ); delete_option( 'afridirect_payment_forms' ); delete_option( 'afridirect_receipt_counters' ); delete_option( 'afridirect_delete_data_on_uninstall' ); delete_option( 'afridirect_notify_admin' ); delete_option( 'afridirect_notify_started' ); delete_option( 'afridirect_notify_email' ); delete_option( 'afridirect_pending_page_id' ); delete_option( 'afridirect_receipt_page_id' ); delete_option( 'afridirect_request_page_id' ); // Clear scheduled events. wp_clear_scheduled_hook( 'afridirect_payment_check_expired_orders' ); // Delete order meta keys if enabled. if ( class_exists( 'WooCommerce' ) ) { global $wpdb; // Get all orders with AfriDirect Proof meta. // Direct DB query required: WP meta APIs do not support wildcard key deletion. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $order_ids = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT post_id FROM {$wpdb->postmeta} WHERE meta_key LIKE %s", $wpdb->esc_like( '_afridirect_' ) . '%' ) ); // Check if HPOS is enabled. $hpos_enabled = class_exists( '\Automattic\WooCommerce\Utilities\OrderUtil' ) && \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled(); if ( $hpos_enabled ) { // HPOS: Delete from orders meta table. // Direct DB query required: HPOS uses custom table and WP meta APIs do not support wildcard key deletion. // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}wc_orders_meta WHERE meta_key LIKE %s", $wpdb->esc_like( '_afridirect_' ) . '%' ) ); } else { // Traditional: Delete from postmeta. foreach ( $order_ids as $order_id ) { $order = wc_get_order( $order_id ); if ( $order ) { // Delete all _afridirect_ meta keys. $meta_keys = array( '_afridirect_form_id', '_afridirect_method_id', '_afridirect_timer_minutes', '_afridirect_expires_at', '_afridirect_proof_url', '_afridirect_proof_attachment_id', '_afridirect_proof_uploaded_at', '_afridirect_admin_note', '_afridirect_receipt_no', ); foreach ( $meta_keys as $meta_key ) { $order->delete_meta_data( $meta_key ); } $order->save(); } } } } // Note: We do NOT delete uploaded proof files as they are user data. // Files remain in wp-content/uploads/ for manual cleanup if needed. } // Run the uninstall function. afridirect_uninstall();