Easy Digital Downloads Currency Switcher – EDD 2.5 orders fix and support for dynamic caching

Easy Digital Downloads Currency Switcher – What’s new

Currency Switcher for Easy Digital Downloads has been updated to version 1.3.8.160115. This update brings the following improvements and fixes:

  • Fixed bug in tracking of order amounts in Easy Digital Downloads 2.5. The bug was caused by a radical change in EDD 2.5. The new architecture caused EDD to unexpectedly trigger events related to new orders multiple times in a row (version 2.4 and earlier don’t have this issue). As a result, the order amounts were converted multiple times, resulting in incorrect figures.
  • Fixed conflict with new EDD_Payment class. This new class, introduced in EDD 2.5, is a rough equivalent of the Order class that our Currency Switcher introduced in 2014. While it’s a welcome addition to the EDD architecture, it caused conflicts with our plugin. This update addresses such conflicts.
  • Changed storage of selected currency to use cookies. This new system will allow to use dynamic caching, like it’s done with the Currency Switcher for WooCommerce.
  • Fixed display bugs in Admin area with EDD 2.5:
    • Fixed display of currency symbol in Dashboard.
    • Fixed display of order currency in Order Edit page.

How to get latest version

New customers

Simply order the plugin from the product page and you will get the latest version.

Existing customers

You should be able to download the updated file using the link you received with your order. If the link doesn’t work, please contact Support to receive the latest version. Thanks.

news icon

Remember to update your EU VAT rates!

If you didn’t do it already, it’s time to update the VAT rates on your system. From the 1st of January 2016, Romania cut its standard VAT rate from 24% to 20%. This quite good news, as the change will make your products cheaper to your Romanian customers, therefore we would recommend to update your tax settings as soon as possible.

How to update the tax rates

Updating tax rates is a simple operation:

  1. Go to WordPress Admin > WooCommerce > Settings > Tax.
  2. Click on the tax rate you would like to update (e.g. “Standard“), at the top of the page.
  3. Change the rate in the row with the country code “RO” to “20”.
  4. Save the changes.

If you are using our popular EU VAT Assistant, you can also refresh all EU tax rates with a single click. Simply select the rate type at the bottom of the page and click on Update EU VAT Rates.

WooCommerce Tax Rates Settings - Screenshot

With our EU VAT Assistant you can update all VAT rates with a single click

All tax rates will be updated automatically to their most recent value. No risk to forgetting any of them behind!

Now all that’s left is double checking that all tax rates are correct. Our plugin updates the rates related to EU countries, therefore you will have to review the rates that refer to countries outside the European Union. If you don’t have any, then you’re done. WooCommerce will now use the new rates for orders placed from now on, and our plugin will collect the tax data automatically.

It couldn’t be easier! 🙂

The Aelia Team

Easy Digital Downloads Currency Switcher – EDD 2.5 compatibility fix

Easy Digital Downloads Currency Switcher – What’s new

Currency Switcher for Easy Digital Downloads has been updated to version 1.3.5.160108. This update brings the following improvements and fixes:

  • Fixed error at checkout. The error, which was thrown when the checkout process completed, was due to the fact that EDD 2.5 triggers multiple calls to the functions that process the order metadata. Many of those calls lack the information expected by the Currency Switcher, which was unable to complete the order processing. Triggering multiple calls could be considered a bug in EDD, therefore we added checks to make sure that our plugin processes the order metadata only when all the necessary data is available.

How to get latest version

New customers

Simply order the plugin from the product page and you will get the latest version.

Existing customers

You should be able to download the updated file using the link you received with your order. If the link doesn’t work, please contact Support to receive the latest version. Thanks.

WooCommerce PayPal Standard Multi-Account – Code cleanup

PayPal Multi-Account for WooCommerce – What’s new

Our PayPal Standard Multi-Account Gateway for WooCommerce has been updated to version 1.2.6.151208. This update brings the following improvements and fixes:

  • Removed call to an obsolete function. In the last version of the the PayPal Multi-account plugin we inadvertently left a call to an internal function that we had removed. This doesn’t always cause issues, but it might throw an error if the Subscriptions plugin is installed. This update removes the obsolete call.

How to get latest version

New customers

Simply place your order and you will get the latest version.

Existing customers

You should be able to download the updated file using the link you received with your order. If the link doesn’t work, please contact Support to receive the latest version. Thanks.

news icon

WooCommerce Tips & Tricks – Only allow specific product combinations in cart

This post was written in December 2015. Based on our tests, the code works with with WooCommerce 2.5 and 2.6. Please keep in mind that the code example are provided “as is”, without explicit or implicit warranties. You might have to adjust the code to make it work with your specific configuration.

Update – 01 March 2018

You can find a link to the code for WooCommerce 3.x at the bottom of the article. 

A member of the Advanced WooCommerce group on Facebook presented an interesting challenge. She needed to allow customers to purchase any products freely, except in one case. She had a specific product (let’s calls it Product X) that had to be purchased “alone”, without any other product being present in the cart. In short:

  • If Product X is in the cart, that must be the only product in the cart.
  • If Product X is not in the cart, any other product can be added to it and purchased at the same time.

Our friend Rodolfo, from BusinessBloomer, posted a solution that he adapted from his solution to allow only one product to the cart. It works, but in our opinion, that approach presented a few limitations:

  1. It works by emptying the cart when Product X is added after the other products. If a customer adds Product X to the cart, then he can add other products, and they will stay there.
  2. It doesn’t allow to have combinations of products (e.g. Product X and Product Y allowed together).
  3. It doesn’t make clear to the customer that other products cannot be purchased together with Product X (all products retain their “Add to cart” button, even if they should not).
  4. It empties the cart explicitly. We try to avoid this type of calls whenever possible, and rely on WooCommerce’s internal logic to decide what items should be removed, and when.

Our approach

Taking advantage of the experience gained with the development of our Prices by Country plugin, we prepared a different solution, which, in our opinion, is more flexible and user friendly. It brings the following advantages:

  • It covers the requirement described above, where a specific product (e.g. Product X) must be the only one in the cart.
  • It also allows to have more than one product allowed in the cart (e.g. Product X and Product Y), while excluding all others.
  • It clearly informs the customers that some products can’t be purchased anymore.

You can find it below, described step by step. The code can be added to the theme’s functions.php, or packaged in a plugin, if needed. It has been tested with WooCommerce up to version 2.5.

Step 1 – Keep track of what’s in the cart

The first thing to do is to determine what is in the cart. The content of the cart will dictate what else can be added to it. We do this operation only once per page load, for better performance.

/**
 * Retrieves the cart contents. We can't just call WC_Cart::get_cart(), because
 * such method runs multiple actions and filters, which we don't want to trigger
 * at this stage.
 *
 * @author Aelia <support@aelia.co>
 */
function aelia_get_cart_contents() {
  $cart_contents = array();
  /**
   * Load the cart object. This defaults to the persistant cart if null.
   */
  $cart = WC()->session->get( 'cart', null );

  if ( is_null( $cart ) && ( $saved_cart = get_user_meta( get_current_user_id(), '_woocommerce_persistent_cart', true ) ) ) {
    $cart = $saved_cart['cart'];
  } elseif ( is_null( $cart ) ) {
    $cart = array();
  }

  if ( is_array( $cart ) ) {
    foreach ( $cart as $key => $values ) {
      $_product = wc_get_product( $values['variation_id'] ? $values['variation_id'] : $values['product_id'] );

      if ( ! empty( $_product ) && $_product->exists() && $values['quantity'] > 0 ) {
        if ( $_product->is_purchasable() ) {
          // Put session data into array. Run through filter so other plugins can load their own session data
          $session_data = array_merge( $values, array( 'data' => $_product ) );
          $cart_contents[ $key ] = apply_filters( 'woocommerce_get_cart_item_from_session', $session_data, $values, $key );
        }
      }
    }
  }
  return $cart_contents;
}

// Step 1 - Keep track of cart contents
add_action('wp_loaded', function() {
  // If there is no session, then we don't have a cart and we should not take
  // any action
  if(!is_object(WC()->session)) {
    return;
  }

  // This variable must be global, we will need it later. If this code were
  // packaged as a plugin, a property could be used instead
  global $allowed_cart_items;
  // We decided that products with ID 737 and 832 can go together. If any of them
  // is in the cart, all other products cannot be added to it
  global $restricted_cart_items;
  $restricted_cart_items = array(
    737,
    832,
  );

  // "Snoop" into the cart contents, without actually loading the whole cart
  foreach(aelia_get_cart_contents() as $item) {
    if(in_array($item['data']->id, $restricted_cart_items)) {
      $allowed_cart_items[] = $item['data']->id;

      // If you need to allow MULTIPLE restricted items in the cart, comment
      // the line below
      break;
    }
  }
});

Step 2 – Prevent disallowed product combinations

Now that we know what’s in the cart, we can prevent some products from being added to it if any of the “restricted” products are present. Emptying the cart would not work, as we would risk to throw away one of the allowed products. Instead, we simply make the disallowed products unavailable. This will have several effects:

  • If any of the disallowed products is already in the cart, WooCommerce will remove it.
  • The Add to Cart button will be replaced by a Read More button on the disallowed products. Customers won’t be able to add the products back, and will instead get a note explaining that they cannot be purchased.
// Step 2 - Make disallowed products "not purchasable"
add_filter('woocommerce_is_purchasable', function($is_purchasable, $product) {
  global $restricted_cart_items;
  global $allowed_cart_items;

  // If any of the restricted products is in the cart, any other must be made
  // "not purchasable"
  if(!empty($allowed_cart_items)) {
    // To allow MULTIPLE products from the restricted ones, use the line below
    //$is_purchasable = in_array($product->id, $allowed_cart_items) || in_array($product->id, $restricted_cart_items);

    // To allow a SINGLE  products from the restricted ones, use the line below
    $is_purchasable = in_array($product->id, $allowed_cart_items);
  }
  return $is_purchasable;
}, 10, 2);

At this stage, we have the code that fulfils the original requirements. However, we need one extra step to make it more elegant.

Step 3 – Explain customers why some products cannot be purchased anymore

As we have seen, the code in step 2 prevents some products from being added to the cart if Product X and/or Product Y are already present, but it doesn’t explain customers why. We just need to show them a message with some information about the restrictions, to make things clearer.

// Step 3 - Explain customers why they can't add some products to the cart
add_filter('woocommerce_get_price_html', function($price_html, $product) {
  if(!$product->is_purchasable() && is_product()) {
    $price_html .= '<p>' . __('This product cannot be purchased together with "Product X" or "Product Y". If you wish to buy this product, please remove the other products from the cart.', 'woocommerce') . '</p>';
  }
  return $price_html;
}, 10, 2);

Step 4 – Combining the code

For the snippets above to work together, we must combine them in the correct order. More specifically, the code from step 2 should go inside the code from step 1. Here’s the complete code, ready to be pasted in the functions.php file: http://pastebin.com/BRU1BP2E.

Update – 01 March 2018

We prepared an example of how the code can be adapted for WooCommerce 3.x. You can find the code here: https://pastebin.com/tRbJKt37.

Step 5, 6, 7, etc – Improvements

The above solution is fully functional, but it would be possible to make it more elegant and flexible. Further improvements to the code could include the following:

  • Packaging the code as a plugin. This will help avoiding global variables and could make the code tidier and easier to read.
  • Adding support for groups of restricted products (e.g. Product X and Y or Product A and B, etc).
  • Adding a dynamically generated message, showing exactly which restricted products are in the cart, instead of relying on static text.
  • Adding formatting to the message displayed to the customers.

Should you need assistance adapting the solution to your needs, or implementing any of the above optimisations, please feel free to contact us. We will review your specifications and provide you with a quote for your customisation.

The Aelia Team

news icon

WooCommerce Meetup, Secrets of a Plugin Developer – Here are the slides!

Dublin WooCommerce Meetup - Banner

Great news, WooCommerce friends! The slides for the November WooCommerce Meetup are finally online: Aelia – Secrets of a WordPress Plugin Developer. We would like to apologise for the delay in publishing the material. November has been an intense month, with multiple parallel projects, and we were so busy that we forgot about the slides. 🙂

What’s inside

The presentation contains a summary of the topics that our founder, Diego Zanella, discussed during the Dublin WooCommerce Meetup on the 11th November. The topic of the meetup was “Secrets of a WordPress Plugin Developer”, and the document describes key concepts that will help you becoming a top notch plugin developer.

Inside, you will find information about:

  • Plugins’ fundamentals
    How plugins differ from standalone applications. Advantages and disadvantages of plugins’ architecture.
  • How to get ideas for plugins
    Some easy ways to find ideas for your first plugin.
  • How to develop, test and support your product.
    Technical information to get you started.
  • What challenges you can expect by becoming a plugin developer
    A short list of the most common “bumps” you will find on your way to success, and how to overcome them.

And more!

Should you have any questions about the content of the document, please feel free to get in touch. Our founder will be happy to answer you, personally. If you would like to meet him, the next WooCommerce Dublin Meetup is scheduled for Wednesday, 9th December 2015, at the Realex headquarters. We will have a Christmas party with our WooCommerce friends and collaborators.

Yes, there will be free food and free beer again, so see you there! 🙂

The Aelia Team