Enable compatibility mode in WooCommerce

If you have setup a WooCommerce shop recently, or have enabled their HPOS1 you will want to enable compatibility mode as soon as you use any extension.

I’m running into issues with WooCommerce Memberships not able to create memberships for users, because it cannot find the users related to an order:

/**
 * Returns users IDs from orders that contain products that could grant access to a given plan.
 *
 * TODO When WooCommerce starts using alternate data stores for products (perhaps from WC 3.5+) this method may require an update as it performs a direct SQL query assuming a standard WPDB data organization {FN 2018-07-23}
 *
 * @since 1.10.6
 *
 * @param int[] $access_product_ids array of product IDs that grant access to a plan upon purchase
 * @return int[] array of user IDs
 */
private function get_users_for_retroactive_access( array $access_product_ids ) {
	global $wpdb;

	if ( ! empty( $access_product_ids ) ) {

		// get orders that contain an access granting product (or variation) to the given plan
		$product_ids  = Strings_Helper::esc_sql_in_ids( $access_product_ids );
		$orders_table = Framework\SV_WC_Order_Compatibility::get_orders_table();
		$order_id_col = Framework\SV_WC_Plugin_Compatibility::is_hpos_enabled() ? 'id' : 'ID';
		$order_ids    = $wpdb->get_col(  "
			SELECT DISTINCT orders.{$order_id_col}
			FROM {$wpdb->prefix}woocommerce_order_itemmeta AS order_item_meta,
			     {$wpdb->prefix}woocommerce_order_items AS order_items,
			     $orders_table AS orders
			WHERE order_items.order_item_id = order_item_meta.order_item_id
			AND order_items.order_id = orders.{$order_id_col}
			AND ( ( order_item_meta.meta_key LIKE '_product_id'   AND order_item_meta.meta_value IN ({$product_ids}) )
			 OR   ( order_item_meta.meta_key LIKE '_variation_id' AND order_item_meta.meta_value IN ({$product_ids}) ) )
		" );

		if ( ! empty( $order_ids ) ) {

			// get user IDs for the found orders
			$order_ids = Strings_Helper::esc_sql_in_ids( $order_ids );
			$user_ids  = $wpdb->get_col( "
				SELECT posts_meta.meta_value
				FROM {$wpdb->prefix}postmeta AS posts_meta
				WHERE posts_meta.post_id IN ({$order_ids})
				AND posts_meta.meta_key = '_customer_user'
			" );
		}
	}

	return ! empty( $user_ids ) ? array_unique( array_map( 'absint', array_values( $user_ids ) ) ) : [];
}

With HPOS, the customer id is saved in the wp_wc_orders table instead.

  1. High-performance order storage ↩︎

Comments

Leave a Reply