Extend Product “Add to Wishlist” Functionality in BigCommerce for WordPress

BigCommerce for WordPress includes out of the box the ability for customers to have multiple wishlists and an “Add to Wishlist” button on product detail pages. But what if you want to add a heart icon or other button that is present wherever products are displayed?? Many designs include this functionality on category pages, listing pages, homepages and more! This will require some custom development to achieve. So buckle up!

Default BC4WP Functionality

The built in product favoriting functionality in BigCommerce for WordPress includes an “Add to Wishlist” button on the product page. Users can have more than one wishlist, and from the Add to Wishlist button, they can select an existing wishlist OR create a new wishlist.

Purpose of Tutorial

For the purposes of this tutorial, I have extended this functionality so that products can be added to wishlists from other areas of the site, from a category listing page for example, or from a featured module on the homepage. I have not, however, extended the “create a wishlist” feature. The wishlist button when clicked will allow a user to add the product to an existing wishlist. If no wishlist exists, it will direct them to their Account page where they can create a wishlist.

The default Add to Wishlist button on the Product Detail page is simply a link with parameters appended. BigCommerce for WordPress will check this link and add the product to the correct wishlist if the link is correctly formatted. So all we need to do is to create the link with the correct parameters.

We will need two code files to achieve this, the template for the button, and the function to create the link.

Button Template Part 1

First, let’s create a function that will return the button template. This is just a simple button. Notice that the $product_id is a parameter. This will need to be passed to the template and will be used later.

<?php

function product_wishlist_button_template ($product_id) {
    $template =
        '<div class="bc-pdp-wish-list-wrapper" data-js="add-to-wish-list">
<button aria-label="Add to Wishlist" aria-controls="wishlist-add" class="wishlist-button" data-js="bc-wish-list-toggle" aria-expanded="false"></button>'

return $template;
}

Notice the JS attributes. These will be used for toggling open a div that includes the possible wishlists. That is, however, outside the scope of this tutorial. Just know that clicking the button will open a modal box that shows all of the possible wishlists. These wishlist links are what will be clicked to actually add the product to a wishlist. So let’s add the toggle-able div to the template.

<?php
/**
 * Create product wishlist button template
 *
 * @product_id WordPress id of product to be added to wishlists
 */
function product_wishlist_button_template ($product_id) {
    $template =
        '<div class="bc-pdp-wish-list-wrapper" data-js="add-to-wish-list"><button aria-label="Add to Wishlist" aria-controls="wishlist-add" class="wishlist-button" data-js="bc-wish-list-toggle" aria-expanded="false">
             Add to Wishlist</button>
<div class="bc-pdp-wish-lists bc-pdp-wish-lists__product" data-js="bc-pdp-wish-lists">';
      
$template = $template . '<p>Choose a Wishlist List</p><ul>';
   $customer_id = get_current_user_id();
   $links = get_wishlist_links($customer_id, $product_id);
   $template = $template . $links . '</ul>';
   $template = $template . '</div> </div>';
     return $template;
}

In the above code sample, you can see a button, a div with the possible wishlists listed (these are a string represented by the variable $links), and closing tags. These items are concatenated and returned.

The above snippet calls get_current_user_id() which is a standard WordPress function. It also calls get_wishlist_links(). This is a custom function you will need to add.

Get Wishlist Links – Custom Function: Get Wishlists via API

To add a product to a user ID using the BigCommerce for WordPress functions, you will need several parameters. You will need the product id, the customer id, and the wishlist id.

The product id has been passed to the template and will now be passed to the custom get_wishlist_links() function.

The customer ID was just retrieved with the standard WordPress function get_current_user_id() and passed to the custom get_wishlist_links() function.

To get the wishlist id’s for that user, we will need to do an API call to the BigCommerce store that our WordPress site is connected to. The BigCommerce store is where wishlist data specific to customers is stored. Luckily, the BigCommerce for WordPress plugin includes and uses a PHP API Library for BigCommerce. (This library is not well documented, but can be accessed and used outside the plugin for other projects – on Github here.)

First, we will use functions from the BigCommerce for WordPress plugin to access the store API credentials. We will need the $store_url, $client_id, and $access_token.

function get_wishlist_links($customer, $product_id)
{
    $store_url = substr(get_option( Api_Credentials::OPTION_STORE_URL, '' ), 0, -1);
    $client_id = get_option( Api_Credentials::OPTION_CLIENT_ID, '' );
    $access_token = get_option( Api_Credentials::OPTION_ACCESS_TOKEN, '' );
}

With this information, we can set up necessary configs and add import classes for necessary functions. For this use case, we will want to use the Wishlist API. There are multiple API’s – you can see examples in the Github repo – although the documentation is sparse.

use BigCommerce\Accounts\Wishlists\Wishlist;
use BigCommerce\Api\v3\Model\Wishlist as APIWishlist;
use BigCommerce\Post_Types\Product\Product;
use BigCommerce\Settings\Sections\Api_Credentials;

/**
 * Get appropriate links for adding to wishlists
 *
 * @customer current logged in customer id
 * @product_id WordPress id of product to be added to wishlists
 */
function get_wishlist_links($customer, $product_id)
{
    $store_url = substr(get_option( Api_Credentials::OPTION_STORE_URL, '' ), 0, -1);
    $client_id = get_option( Api_Credentials::OPTION_CLIENT_ID, '' );
    $access_token = get_option( Api_Credentials::OPTION_ACCESS_TOKEN, '' );

    $config = new \BigCommerce\Api\v3\Configuration();
    $config->setHost($store_url);
    $config->setClientId($client_id);
    $config->setAccessToken($access_token);
    $client = new \BigCommerce\Api\v3\ApiClient($config);
    $wishlistAPI = new \BigCommerce\Api\v3\Api\WishlistsApi($client);
}

We will now make a call to the API to get the wishlists associated with the customer id.

<?php

use BigCommerce\Accounts\Wishlists\Wishlist;
use BigCommerce\Api\v3\Model\Wishlist as APIWishlist;
use BigCommerce\Post_Types\Product\Product;
use BigCommerce\Settings\Sections\Api_Credentials;

/**
 * Get appropriate links for adding to wishlists
 *
 * @customer current logged in customer id
 * @product_id WordPress id of product to be added to wishlists
 */
function get_wishlist_links($customer, $product_id)
{
    $store_url = substr(get_option( Api_Credentials::OPTION_STORE_URL, '' ), 0, -1);
    $client_id = get_option( Api_Credentials::OPTION_CLIENT_ID, '' );
    $access_token = get_option( Api_Credentials::OPTION_ACCESS_TOKEN, '' );

    $config = new \BigCommerce\Api\v3\Configuration();
    $config->setHost($store_url);
    $config->setClientId($client_id);
    $config->setAccessToken($access_token);
    $client = new \BigCommerce\Api\v3\ApiClient($config);
    $wishlistAPI = new \BigCommerce\Api\v3\Api\WishlistsApi($client);

    try {
        /*
         * List of request parameters and response properties available at
         * https://developer.bigcommerce.com/api-reference/catalog/catalog-api/products/getproducts
         */
        $wishlists = $wishlistAPI->listWishlists([
            'customer_id' => $customer
        ]);

    } catch (\BigCommerce\Api\v3\ApiException $e) {
        $error_message = $e->getMessage();
        $error_body = $e->getResponseBody();
        $error_headers = $e->getResponseHeaders();
        // do something with the error
        return;
    }
}

We should now have the appropriate wishlists captured by the $wishlist variable.

Get Wishlist Links – Custom Function: Get BigCommerce Product ID

We now need to retrieve the BigCommerce product ID from the WordPress product ID we have as a function parameter. Unfortunately these ID’s are not the same. BigCommerce for WordPress is written in using Object Oriented Programming. Oftentimes the parameters needed to use BC4WP functions need to be BC4WP formatted objects. To retrieve the BigCommerce product ID, we first need to get the product object. Here’s how we do this:

$product = new BigCommerce\Post_Types\Product\Product($product_id);
$bigcommerce_id = $product->bc_id();

Get Wishlist Links – Custom Function: Create Links

Now we finally have the parameters needed to create the link – customer ID, BigCommerce product ID, and wishlist ID. We will loop through the wishlists and for each wishlist we will call the BCW4WP Wishlist methods add_item_url() and name(). These will be concatenated to a template that is a formatted list of wishlists as list items.

$template = '';

    foreach ($wishlists->getData() as $wishlist_data) {
        $wishlist = new Wishlist($wishlist_data);
        $link = $wishlist->add_item_url($bigcommerce_id);
        $name = $wishlist->name();
        $list_item = "<li class='bc-wish-lists-item'><a href='" . $link . "' class='bc-wish-list-item-anchor'>Add to " . $name . "</a></li>";
        $template = $template . $list_item;
    }
    return $template;

As you can see, once you retrieve the $wishlists you need to call the getData() method on the object to retrieve data for each wishlist. Then you will instantiate a new wishlist object with that data in order to use the wishlist methods. the methods add_item_url() will create the URL that when clicked will add the product to the correct wishlist. Notice it takes the BigCommerce ID as a parameter. The name() method retrieves the name of the wishlist so that it can be echoed to the screen. We’ve then created a list item and appended it to a template.

Here is the full file:

<?php

use BigCommerce\Accounts\Wishlists\Wishlist;
use BigCommerce\Api\v3\Model\Wishlist as APIWishlist;
use BigCommerce\Post_Types\Product\Product;
use BigCommerce\Settings\Sections\Api_Credentials;

/**
 * Get appropriate links for adding to wishlists
 *
 * @customer current logged in customer id
 * @product_id WordPress id of product to be added to wishlists
 */
function get_wishlist_links($customer, $product_id)
{
    $store_url = substr(get_option( Api_Credentials::OPTION_STORE_URL, '' ), 0, -1);
    $client_id = get_option( Api_Credentials::OPTION_CLIENT_ID, '' );
    $access_token = get_option( Api_Credentials::OPTION_ACCESS_TOKEN, '' );

    $config = new \BigCommerce\Api\v3\Configuration();
    $config->setHost($store_url);
    $config->setClientId($client_id);
    $config->setAccessToken($access_token);
    $client = new \BigCommerce\Api\v3\ApiClient($config);
    $wishlistAPI = new \BigCommerce\Api\v3\Api\WishlistsApi($client);

    try {
        /*
         * List of request parameters and response properties available at
         * https://developer.bigcommerce.com/api-reference/catalog/catalog-api/products/getproducts
         */
        $wishlists = $wishlistAPI->listWishlists([
            'customer_id' => $customer
        ]);

    } catch (\BigCommerce\Api\v3\ApiException $e) {
        $error_message = $e->getMessage();
        $error_body = $e->getResponseBody();
        $error_headers = $e->getResponseHeaders();
        // do something with the error
        return;
    }

    $product = new BigCommerce\Post_Types\Product\Product($product_id);
    $bigcommerce_id = $product->bc_id();

    $template = '';

    foreach ($wishlists->getData() as $wish) {
        $wishlist = new Wishlist($wish);
        $link = $wishlist->add_item_url($bigcommerce_id);
        $name = $wishlist->name();
        $list_item = "<li class='bc-wish-lists-item'><a href='" . $link . "' class='bc-wish-list-item-anchor'>Add to " . $name . "</a></li>";
        $template = $template . $list_item;
    }
    return $template;
}

Button Template Part 2

The last step is to return to our template file and add some conditional handling. We will want to check if a customer is logged in – if not, none of these functions would work and we will need to echo a message asking the user to login. We will also need to check if the customers has wishlists at all. If no wishlists exist for the logged in customer, we will echo a message telling them to create a wishlist and linking to their Account page where they can do so. Here is the button template file with those updates:

<?php
/**
 * Create product wishlist button template
 *
 * @product_id WordPress id of product to be added to wishlists
 */
function product_wishlist_button_template ($product_id) {
    $template =
        '<div class="bc-pdp-wish-list-wrapper" data-js="add-to-wish-list">
            <button aria-label="Add to Wishlist" aria-controls="wishlist-add" class="wishlist-button" data-js="bc-wish-list-toggle" aria-expanded="false">
Add to Wishlist</button>
            <div class="bc-pdp-wish-lists bc-pdp-wish-lists__product" data-js="bc-pdp-wish-lists">';
        if( is_user_logged_in() ) {
            $customer_id = get_current_user_id();
            $links = get_wishlist_links($customer_id, $product_id);
            if(!empty($links)) {
                $template = $template . '<p>Choose a Favorites List</p>
                    <ul>';
                $template = $template . $links . '</ul>';
            } else {
                $template = $template . '<p>You do not have any favorites lists.</p><a href="' . get_site_url() . '/wish-lists">Create a favorites list!</a>';
            }
        } else {
        $template = $template . '<p>You are not logged in.</p><a href="' . get_site_url() . '/login">Log in | Create Account</a>';
        }
    $template = $template . '</div> </div>';
     return $template;
}

Hurray! We now have a simple button that will correctly add a product to the selected wishlist.

With any luck I will turn this into a plugin some day! ????