/** * 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);