businessdad icon

Currency Switcher - WooCommerce Blocks Checkout Integration

businessdad | PRO | 05/29/20 05:14:21 PM UTC | 0 ⭐ | 2422 👁️ | Never ⏰ | []
PHP |

4.3 KB

|

None

|

0 👍

/

0 👎

/**
 * Aelia Currency Switcher, Prices by Country, Tax Display by Country
 * --
 * Integration with the "cart" and "checkout" blocks provided by WooCommerce Blocks.
 * 
 * THIS CODE IS PROVIDED AS A PROOF OF CONCEPT. Please make sure to read all the documentation,
 * below, before using it. 
 * 
 * GPL DISCLAIMER
 * THE USE OF THIS CODE IS AS YOUR OWN RISK. 
 * This code is provided free of charge and comes without any warranty, implied or explicit, to the extent permitted 
 * by applicable law. Except when otherwise stated in writing the copyright holders and/or other parties provide the 
 * program "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied
 * warranties of merchantability and fitness for a particular purpose. The entire risk as to the quality and performance 
 * of the program is with you. Should the program prove defective, you assume the cost of all necessary servicing, repair 
 * or correction.
 *
 * Need a consultation, or assistance to customise this code? Find us on Codeable: https://aelia.co/hire_us
 * 
 * BACKGROUND
 * On a "plain" WooCommerce setup, changing fields like billing and shipping country on the 
 * cart and checkout page triggers a call to the site to refresh the cart contents. The Aelia
 * plugins intercept this call, check which country was selected and set customer's country and 
 * currency accordingly. 
 * 
 * For some reason, the WooCommerce Blocks plugin follows a different approach. Rather than the
 * standard call used by WooCommerce, that plugin uses a custom REST API to update the shipping 
 * details. The Aelia plugins are not aware of that call, therefore they can't "see" that the
 * address changed. 
 * 
 * Unfortunately, the WooCommerce Blocks plugin is still quite rigid and doesn't offer events
 * that can be intercepted to detect the change. Due to that, a more "rustic" approach is needed,
 * to listen for the specific REST calls it makes.
 * 
 * CAVEATS
 * - This code listens for the "shipping country" change. When this code was written (29 May 2020), 
 *   the WooCommerce Blocks plugin didn't seem to trigger any event when the BILLING country.
 * - This code doesn't check if the Aelia plugins are supposed to use the shipping country or the
 *   billing country. Since the WooCommerce Blocks plugin only triggers a call on "shipping address change",
 *   this code takes such country and uses it to set customer's country.
 * 
 * IMPLEMENTATION
 * For this code snippet to work, you will probably have to wrap it into a mini-plugin. You can
 * do that as follows:
 * 
 * 1. Create a file called your-plugin-name file in the new subfolder.
 * 2. Add a plugin header to the file: https://developer.wordpress.org/plugins/plugin-basics/header-requirements/. 
 *    You can just set it to "Plugin Name: YOUR PLUGIN NAME".
 * 3. Add your custom code below the plugin header.
 * 4. Save the file.
 * 5. Create a folder called wp-content/plugins/your-plugin-name on your site (e.g. via FTP).
 * 6. Enter the new folder.
 * 7. Upload the file you just created.
 * 8. Go to WordPress > Plugins to enable the custom plugin.
 * 
 * By doing this, the custom code will be loaded together with the other plugin. That will be much earlier than
 * file "functions.php", and it will ensure that the custom code will be loaded soon enough.
 */
 
add_filter('woocommerce_rest_is_request_to_rest_api', function($is_request_to_rest_api) {
  if($is_request_to_rest_api) {
        // Extract the path to the REST API
    $rest_api_path = parse_url(esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])), PHP_URL_PATH);
 
        // Check if the path matches the "update shipping" call made by the WooCommerce Blocks plugin
    if(substr_compare($rest_api_path, '/wc/store/cart/update-shipping', -strlen('/wc/store/cart/update-shipping')) === 0) {
            // Extract and decode the posted data
            // @see WC_API_Server::get_raw_data()
      $raw_body = file_get_contents('php://input');
      $body = json_decode($raw_body, true);
 
            // If a country was posted, simulate a "country selection". This will allow
            // the Aelia plugins to pick it up automatically
      if(!empty($body['country'])) {
        $_POST['aelia_customer_country'] = $body['country'];
      }
    }
  }
 
  return $is_request_to_rest_api;
}, 1, 3);

Comments