SearchWP Results In WooCommerce Product & Variation REST API Search

There’s a super nifty extension out there to give SearchWP it’s own REST API endpoint and it’s super useful! It’s made by my good friends at Caldera Forms and it may just solve your needs.  But it wasn’t helping me solve a problem I had.  On a project I have a very customized hooked into and filtered situation going on with the WooCommerce products endpoint on the API.  I didn’t want to refactor to work with that plugin so I needed to get results going into the primary products endpoint we are already using.

?search=keyword

To use the default WordPress search functionality in an API endpoint you tack on ?search=keyword.  This is cool and all but we are implementing SearchWP.  SearchWP works by intercepting WP_Query when it’s got the ‘is_search’ set.  It then does it’s own thing and returns the results.

The issue is, it doesn’t intercept when doing a search through the REST API.  Why? I forgot, I dug through code for hours and figured it out but I can’t remember or sum up the reason so I’m just going to give my solution.

Pass Along IDs From SWP_Query

First thing you will want to do is hook into pre_get_posts and inject SWP_Query search results into the query’s ‘post__in’ parameter.  You need to also tell the query it’s not a search and be sure you are even in the right place to be doing this.  Here’s a quick gist

https://gist.github.com/ChrisFlannagan/7c0ae5510482a9cea9fb488c7f088fca

Order By Post__In

We can’t just let this go and it will work.  The query may still try to order by something other than the result of IDs we got from SearchWP.  So we need to hook into rest_{post_type}_query.  Here’s the gist of that.

https://gist.github.com/ChrisFlannagan/42488c578c3a9167ee2a7290f937d358

Remove Catalog Visibility Hidden Products In WooCommerce From Search & WP REST API Results

Woo doesn’t filter out products with hidden catalog visibility outside of main shop loop. This is important to remember when using the REST API for front end display or general search results. This code snippet will keep them from showing outside of the admin.

https://gist.github.com/ChrisFlannagan/f79ab49491c2b85b0925c66a7fe971fd

Turn Off Localization Temporarily in WooCommerce

I’m working on a site that’s in Japanese.  It’s a huge WooCommerce shop and they have a lot of custom meta fields we built for the English version of things.  Customers have their first and last name in my account and also fields we made for English First Name and English Last Name.

On the Addresses endpoint of WooCommerce’s “My Account” section we wanted to display the names/addresses in both Japanese and English.  This seemed easy except the Japanese state name that’s generated by Woo was being translated in the ‘woocommerce’ text domain.  The work-around was to unload the text domain, reload the countries/states instance with the data, get our state then reload the text domain.  This snippet did the trick:

https://gist.github.com/ChrisFlannagan/423cb29c9ffe9a55baa2e955add81ba6

WooCommerce: Add Fee To Order During Checkout If Cash On Delivery Or Any Other Reason/Gateway

Recently I was tasked with adding a field to the cash on delivery gateway in WooCommerce.  They wanted a field they could put in a dollar amount that would be tacked on as a fee to orders using that gateway.  Seemed simple enough with some googling but took a bit longer to tweak and get functioning correctly.

Add Field to Cash On Delivery Gateway

Adding fields in WooCommerce to its forms is pretty straight forward.  You hook into the WC Settings API and adjust them using this hook:

add_filter( 'woocommerce_settings_api_form_fields_<id>', function( $form_fields ) { return $form_fields; } );

Replace <id> with the id of the form.  In this case it’s “cod” for the Cash on Delivery form. In your hooked function you can manipulate the form fields array as needed.  For my case I just needed to add a field at the end for a fee so I do this:

https://gist.github.com/ChrisFlannagan/bcfe4ea1cbfdcd629db7f292c22cc40c

Add Fee To The Order

Now that we have a fee set we need to hook into the checkout process.  For this I use the action “woocommerce_checkout_create_order” to manipulate the order right before it’s saved.  In WooCommerce 3.0 and over you no longer use the add_fee() function but instead create a line item fee object and add that to the order.  Here’s how I did what I needed:

https://gist.github.com/ChrisFlannagan/ae68a43ec4b60ac741c95715e58dd001

SUPER IMPORTANT

Notice the add_item( $item ) call to place it in the order.  If that’s all you do then you will see the fee on the order but the order total won’t include it.  You need to make sure you run the order’s calculate_totals() function after adding the item.

SNIPPET: Add an “Upgrade” Button To Item on Checkout in WooCommerce – Select Upgrade Product Per Product

This is JUST a proof of concept.  The code here is no where near ok for production.  I share as a snippet, use if/how you can.

https://gist.github.com/ChrisFlannagan/d7559c3682bc3db588cd9c6b70c01dec

Add Variation To Cart in WooCommerce: Don’t Forget The Attributes!

The point of this post is to help others that are having a problem dynamically adding a variation of a product (or subscription product in my case) to cart.  I get to that at the bottom of this post if you want to skip the story.

The Problem

I have a pretty high up there client in the box subscription world.  I’ve been brought in to do some WooCommerce functionality with WooSubscriptions and everything else involved.

The checkout process is pretty customized.  We have a page that displays all the attributes available for the subscription variable product.  There’s a bunch of fancy selection boxes and lists and gift inputs and so on.  It’s front end heavy but communicates with a custom endpoint through the REST API that I wrote to add the item to cart.  Problem is, the sub form doesn’t give me a variation id, only the variable subscription product id and all the selected attribute values.

Finding the Variation

The first step is to find which variation they’ve selected.  Someone long before me went through the rigorous process of creating some 50-60 variations of this variable subscription product to match all the different options a user could select.

So I use a WP_Query search the for any post id that has all the meta_key/meta_value matches and select it.  It was a bit of a pain to figure out the best process here but this works.

Adding the Variation to Cart

Took me a few to find the right parameters for adding a variation to cart.  Now that I had the post id of that variation it looked pretty simple from what I found online:

$added = WC()->cart->add_to_cart( $query->post->post_parent, 1, $data['variation_id'] );

This did the trick.  Since I used a WP_Query to get the post I could select the parent (which is the main subscription variable product) needed for first parameter.  Then the quantity, then the variation id.  Which was $query->post->ID but I assigned it to some data my API was returning.

The user checked out and the variation was in the order.  A day after pushing this code the site owner asked where the order details went.  Turns out it original showed the selected attributes in the admin order panel.  I spent a couple hours figuring this out, which I feel dumb now, but going in blind what can you expect.

You have a fourth parameter you can for $variation_data.  This gives it the attribute love it wants and adds it to the order.  Why woo doesn’t just do this automatically if a variation is added? Beats me.  But here’s how you do it using a nice woo provided function for variations.

$added = WC()->cart->add_to_cart( $query->post->post_parent, 1, $data['variation_id'], wc_get_product_variation_attributes( $data['variation_id'] ) );

WooCommerce Buy One Get One Half Off (50% Off) Hook/Plugin – IN PROGRESS

We have a deal coming up for all of November at my work.  Buy one, get one half off.  There’s no way to do this in vanilla WooCommerce.  I looked at Dynamic Pricing and it didn’t seem to offer this ability and if it did it was crazy complicated.  I looked at some other plugins out there and found one that may work but it was pro version only and I didn’t want to pay to find out.

I figured this is pretty straight forward need so why not write up a function real fast.  Here’s my train of thought followed by a code example.  This is only a proof of concept and I still need to add – price limits (items must be over a certain price for this to work), category limits and the ability to apply this more than once to an order.  But as of now it will take the second highest priced item and give it a 50% discount.  If you have two of the same item as the highest price it will discount the amount to make it the same as taking 50% off just one of the items.

First we need to hook into woocommerce_before_calculate_totals.  This way we can change the price on the cart and on the checkout.

add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {

Then I set variables for highest price, quantity of that item, a counter so we know if the shopper has more than 1 item in our discount range (for future use with pricing bottoms) and next highest price item.

$highest_price_id = 0;
$highest_price_quantity = 0;
$cnt = 0;
$highest_price = 0;
$next_highest_price_id = 0;
$next_highest_price = 0;

I need to optimize this, there should be no need for looping the cart twice but in a hurry to prove the concept works this morning and get something ready for our promo I did it this way.  I loop through the cart and gather all my data: highest priced item, quantity and so on.  Then we loop the contents again and reduce price where needed.

foreach ( $cart_object->cart_contents as $key => $value ) {
   if( $value['data']->price > $highest_price ) {
      $highest_price = $value['data']->price;
      $highest_price_id = $value['product_id'];
      $highest_price_quantity = $value['quantity'];
      $cnt++;
   }

   if( $value['data']->price < $highest_price && $value['data']->price > $next_highest_price ) {
      $next_highest_price = $value['data']->price;
      $next_highest_price_id = $value['product_id'];
      $cnt++;
   }
}

The final loop we first check if:

  1. Highest priced item is more than 1 quantity and we are on it in the loop
  2. There’s no other item that’s considered the second highest price.  If there is, we want to discount that and not one of the highest priced items.
  3. If any of that fails then we check if this is the next highest priced item and run our discount here
foreach ( $cart_object->cart_contents as $key => $value ) {
   if ( $highest_price_quantity > 1 && $value['product_id'] === $highest_price_id && $next_highest_price === 0 ) {
      $value['data']->price = $value['data']->price - ( $value['data']->price / $value['quantity'] ) * .5;
   } elseif ( $value['product_id'] === $next_highest_price_id && $cnt > 1 ) {
      $value['data']->price = $value['data']->price - ( $value['data']->price / $value['quantity'] ) * .5;
   }
}

The discount is based on quantity.  If someone has two of the same $99 item we don’t want to make them both $48.  We want to discount just the first item but I’m not sure if that’s even doable.  We could generate a coupon or some other more complicated options but I went with the simple approach.  Let’s take the quantity, divide the price by that (so we have two $99 items, 99/2 is $48) then take 50% of that and subtract it from the price.  Each item will have 25% subtracted basically and add up to 50% total discount on 2 items.

I’ve been testing this and it seems to be working.  I JUST put this together though so needs a lot more testing to make sure it’s working correctly.

https://gist.github.com/ChrisFlannagan/0d2010c49f582d5d89fa6f9740bf5703

Tracking Conversions in WooCommerce with Simple Link Codes the Easy Way & More

woocommerce-tracking-code-plugin-simpleI wrote about this as I was building it out.  It’s evolved a bit and is now on the WordPress Plugin Repository.

https://wordpress.org/plugins/quick-tracking-conversions-for-woocommerce/

It’s simple.  You setup codes you want to track for conversions in WooCommerce.  If you have an email blast coming up then just create a code for it and attach that code to the end of all links in the email blast.  This works for affiliates, whatever.

The link looks like this: https://whoischris.com/?qtc_woo_tracking_code=testcode

Of course you can replace “testcode” with anything you want and have as many tracking codes as you’d like.  Then in the admin, you input the code you want to see the results of.  You get a total and # of conversions.  I have every intention of adding more in depth analytics but this is a proof of concept.

Passwords to Conversions Analytics

What I encountered the following week at work presented a new problem.  We are starting a site for retailers and professionals in our industry.  We sell a specialized tool only to licensed professionals and we want them to be able to carry our consumer product on their shelves, so they need to be able to buy at a discounted, bulk price.

Fortunately this site is on its own domain and I can make the functionality global.  So here’s what I needed to happen:

  • All shopping functionality should be hidden behind a password/access code that we hand out.
  • Different rep groups selling to professionals need to have their own code that can be tracked
  • We want to see total conversion for each code used

My thoughts lead to why not use the existing conversions plugin I built?  I’ll just hide all of WooCommerce behind a password wall.  Any password the admin creates can be used to access it, I just drop a cookie.

I also drop a cookie for the Quick Tracking Conversions plugin and voila, our shoppers have access and we can see what password/access code they are using to make their purchase.  The new extension can be found here:

https://github.com/ChrisFlannagan/qtc-passwords

 

Quick Campaign Conversion Tracking in WooCommerce

My company hired a marketing firm that is starting our Constant Contact campaigns amongst other things.  We want to track conversions and at this point we don’t need anything too fancy.  Between that, Facebook ads/posts, Google Analytics and our affiliates, there’s a lot of pixels, JavaScript and php functions that need to be added to our system.  It’s a bit overwhelming and each has its own installation instructions/methods.

Right now, we just want to see conversions.  We want to know what source provide how many purchases and at what value.

I searched for some quick methods and plugins that might help but again, too much complicated setup for simple conversion tracking.  So I built a thing.

Quick Tracking Conversions for WooCommerce

I envisioned a super simple system where you can take on a code to the end of a link and all visits to your site with that code would be tracked and recorded when converted.  I wanted to start with simply recorded full, purchase conversions.

I didn’t want to have to setup a campaign with a code and details in an admin before generating links.  I want to just tell our marketing person put something like ?tracking_code=MyEmailCampaign on the end of all links in a Constant Contact.

So I built a plugin.  It’s light weight, secure and solid.  It does it’s job and it does it right.  You add whatever campaign code you want to links for Facebook, Email blasts, affiliates or anything at all that you want to track conversions from a link.  Here’s an example link that could be in an email:

https://example.com/product/t-shirts?qtc_woo_tracking_code=Oct2016-email-blast

After the email goes out and orders come in I can simply go to the admin page of the plugin, type in Oct2016-email-blast and submit the form.  It will show me number of conversions and total money generated so far.

How It Works

The plugin checks for $_GET[‘qtc_woo_tracking_code’] and sets its value in a cookie.  If the user converts it adds a post_meta to the order for that tracking code.

This allows me to pull all details of every order made.  We can get products purchases, shipping methods, totals, taxes and everything.

Here’s the repo if you want to check it out.  It’s simple right now and has Google Analytics Enhanced Ecommerce option you can enable as well.  There’s room to add all sorts of conversions such as product viewing, add to cart and so on.  This plugin will grow.

https://github.com/ChrisFlannagan/woo-flanny-conversion-tracker