query( $wpdb->prepare( 'DELETE FROM %i WHERE meta_key = %s', $wpdb->termmeta, '_oc_agent_phone' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching // Delete post meta from products and orders, but NOT from oc_agent posts (those belong to PRO). $oc_meta_pattern = $wpdb->esc_like( '_oc_' ) . '%'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->query( $wpdb->prepare( "DELETE pm FROM {$wpdb->postmeta} pm INNER JOIN {$wpdb->posts} p ON pm.post_id = p.ID WHERE pm.meta_key LIKE %s AND p.post_type != %s", $oc_meta_pattern, 'oc_agent' ) ); // Delete order meta (HPOS) - check if table exists first. if ( class_exists( 'Automattic\WooCommerce\Utilities\OrderUtil' ) ) { $hpos_table = $wpdb->prefix . 'wc_orders_meta'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $hpos_table ) ); if ( $table_exists ) { $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE meta_key LIKE %s', $hpos_table, $oc_meta_pattern ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching } } // Drop events table. $wpdb->query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $wpdb->prefix . 'oc_events' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching // Clear scheduled events. wp_clear_scheduled_hook( 'ordercourier_cleanup_events' ); // Clear transients (escape LIKE patterns). $oc_transient_pattern = $wpdb->esc_like( '_transient_oc_' ) . '%'; $oc_timeout_pattern = $wpdb->esc_like( '_transient_timeout_oc_' ) . '%'; $wpdb->query( $wpdb->prepare( 'DELETE FROM %i WHERE option_name LIKE %s OR option_name LIKE %s', $wpdb->options, $oc_transient_pattern, $oc_timeout_pattern ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching } ordercourier_uninstall();