Automatically Create WooCommerce Product for PDF Download

A challenging WordPress project that I recently worked on required that a WooCommerce no-cost virtual, downloadable product be created each time a PDF was uploaded into a certain section on the screen of certain custom post types.

  • A history of the downloads of a PDF product was to be kept for years.
  • Only PDFs uploaded in the PDF Product Group section (a section created as part of the solution for this business requirement) were to be converted into WooCommerce PDF products. (PDFs could be uploaded and linked to inside the regular WordPress post content area. Those PDFs were to be handled by WordPress as it normally does, and were NOT to be added as WooCommerce products.)
    Custom Field Group for PDF Product

    Custom field group for PDF product shown on this client’s custom post type for Case Studies

  • The client had multiple custom post types. Some allowed PDF product uploads and others did not.
  • On the custom post types that allowed PDF product uploads, a PDF was not required to be uploaded.
  • Only one PDF product could be associated with a post at any given time.
  • The reason the PDFs were added to WooCommerce as products was so that the client could track which people downloaded which PDF products. (I was not asked for a recommendation on how I would implement this; I was asked to make it happen using WooCommerce as the manager.)

What I did was:

  1. Make a list of the minimum fields that WooCommerce creates when a virtual, downloadable product is created
  2. Confirm how WooCommerce handles no-cost products
  3. Create a custom field group, the PDF Product Group, that contains the Title of the PDF to be used for the Product title, an upload file field (for uploading the PDF), a small description field to be used as the PDF product’s description.
  4. Added an ‘action’ function in functions.php that runs on ‘save_post’. The function checks whether the post is one of the custom post types that can have a PDF. Then it checks whether a PDF has been successfully uploaded, followed by verifying that a title and a description have been added.
  5. Once all of those validations have been passed, a WooCommerce virtual, downloadable product is created using those fields and others (defined in the first step above) that are set to default values (like the product category which changes according to the custom post type). In all, 29 postmeta records are added.
  6. Finally, the one-to-one relationship between this post and the PDF product that was just created is recorded by adding another postmeta record. This effectively defines the post as the ‘parent’ of the product.

Adding the product for the first time (processing above) was the easy part. Deleting the product was the second easiest.

Remember that the PDF product is related to the ‘original‘ post. That original post has a unique identifier, the post ID. When a WordPress post is edited, a new post is created with its own unique ID (the revision) and the original post’s ID is added to the ‘post_parent’ field in the revision’s record, so, I had to be careful about which post ID I was referencing in the PHP programming: the revision’s post ID, the parent’s post ID, the PDF product’s post ID, or one of the postmeta record’s post ID.

Automatically deleting the WooCommerce PDF product

Since this client was tracking who downloaded which PDFs, the PDF products were not deleted. Instead, they were marked as inactive so that the PDF free products would not display as active downloads on any of the pages – and – the download history was preserved for reporting purposes.

The delete process works like this:

  • Check to see if one of those postmeta ‘parent-child’ records exists for the ‘parent’ post. (By business requirement, there can be only one…if there is any.)
  • Check whether there is a value in the PDF product custom file upload field of the current post.
  • If there is no product in the PDF product custom field of the revision post, use the WooCommerce product post ID in the parent-child record of the revision’s parent to retrieve the product information and mark it as inactive.
  • If there is a product in the PDF Product custom field of the current post, then maybe the records needed to be updated. (see next section)

Updating the WooCommerce PDF product

The toughest part was trying to decipher whether the PDF had been modified and re-uploaded, and, if so, was it uploaded with the same name or a different one? When updating WooCommerce downloadable products directly, WooCommerce keeps track and knows which version to serve for download. WooCommerce can even send a notice to users who downloaded the previous version that there is a new version available. Updating a WooCommerce downloadable product from outside WooCommerce upped the level of complexity.

One thought was to check the most recent PDF name against the name of the PDF originally uploaded. While this final piece was being coded and unit tested, the program manager decided to change course.  The WooCommerce-as-the-manager approach was abandoned. Before that happened, all the other code was unit and system tested, and working – as was the ability to track who downloaded what.

Limited Checkout Fields for Free PDF Downloads

Since the client wanted to know who downloaded which PDF, it was necessary for the person downloading to be logged in.

  • If the person downloading did not already have an account at the website, an account needed to be created.
  • If they were downloading only the FREE PDFs, it was not necessary to fill in the multiple checkout screens that WooCommerce normally presents. The WooCommerce Checkout for Digital Goods plugin was used to capture minimal contact information and create a WooCommerce account for them.
  • If there were pay-for products also in the cart, the purchaser would experience the normal, multi-screen WooCommerce checkout process (if they did not already have an account).

So, what seemed like a simple requirement “use WooCommerce to track who downloads the FREE PDFs” became quite challenging when adding and maintaining WooCommerce records outside of the WooCommerce Products module.


Giving Thanks in a Fun Way

Last Thursday, Nov. 17th 2016, we had loads of fun at my BNI meeting while contributing to a great local cause!

Karen Callahan's BNI group

BNI Marlborough, November 17, 2016 (about 1/2 the group)

BNI is a business networking group that meets weekly. Every week, each member gives a 45-second presentation that helps the other members understand what a good referral for their business looks like.

On this Thursday, in the spirit of giving thanks and the gift gifting holidays, each member brought a non-perishable food item to donate to the Marlborough Community Cupboard. Then, during their 45-seconds, they told the story of how the food item ‘represented’ their business or their target audience.

Good fun was had by all as we were reminded how creative everyone can be. Some members even surprised themselves! And, we were all reminded how good ‘giving’ feels and how giving in a group setting multiplies the good will!

Happy Thanksgiving to you and yours. May you be blessed with little traffic, warm hugs, and a full belly!

WordCamp Rhode Island 2016

So, it looks like I have disappeared for a couple of months.  Not really, just wonderfully busy.  To catch you up, these weeks have been a flurry of activities; learning, developing, updating, and hopping from one conference to another. Before too much time gets away from me, I want to acknowledge the triumph of WordCamp RI 2016!

2016 WordCamp Rhode Island logo

This was the fifth year WordCamp was held in Rhode Island. Initially, it was held under the name of WordCamp Providence. Later the named was changed to include all of Rhode island, which more clearly represents the attendees of the WordCamp. The 2016 WordCamp RI was held September 30 & October 1, 2016 at the fabulous New England Institute of Technology in East Greenwich, RI.

So what made this year so special?

I had the lucky job of greeting scores of attendees as I was one of the registration/checkin-in people. It was a terrific gig. I got to meet many WordPress enthusiasts. They spanned all skill levels, all ages, all employment situations. Some had projects planned. Some were in the middle of projects and came to get their questions answered, and some came to find out what the heck WordPress is.

It was my second year as co-organizer and I had a vested interest in it success – but – I have to tell you that it was even more of a success than I had imagined. Not only were there more attendees and more presenters than ever, but, on each day, attendees freely offered their opinions about the venue, the event structure, individual presentations, and even the food.  All gave SUPER positive feedback. It is so gratifying to hear accolades…especially when you have a behind-the-curtain view and understand the hours of thought, discussion, and actions that a whole team participated in in order to make the WordCamp event happen.  Kudos to Aaron Ware and his team at Linchpin of Pawtucket, RI who have spearheaded the event for several years. They, along with a handful of devoted WordPress enthusiasts like myself, were able to put it all together, and hundreds were able to enjoy it!

I had the good fortune of attending the Saturday keynote and a couple of presentations. Here’s photos from those.

John Maeda delivering keynote at 2016 WordCamp Rhode Island

John Maeda delivering keynote


Michelle Schulp presenting DIY Design

nate berger presenting at 2016 WordCamp Rhode Island

Nate Berger presenting “Avoiding Catastrophic Plug-In Failure: Best Practices are Born During Fire”

Planning has already begun for the 2017 RI WordCamp!

If you are a WordPress enthusiast and want to get involved and meet other enthusiasts, both the WordPress Rhode Island (also spearheaded by Linchpin) and the Boston WordPress meetup groups meet once per month. You connect with them here: WordPress RI Meetup, Boston WordPress Meetup

New WordPress website for local Rotary club in the works

I’m proud to announce that I have been chosen to work with the Marlborough Chapter of Rotary International on defining, designing, and developing a new website for the Chapter.

The existing website launched in 2010.

Marlborough Rotary website 2010At that time, the committee had wanted to establish a web presence for the local chapter. It wanted a simple, clean design with user-friendly navigation that could be used as a tool to communicate with the local community as well as with its members.

The 2016 Marketing committee has created a website sub-committee to work on defining a new, more-modern looking website. Sub-Committee members are Elaine McDonald, Peggie Thorsen, Emily Greenwood, and myself. The sub-committee wants a website that includes functionality that meets the business requirements of today’s Marlborough Rotary club, and, more importantly, reflects how the Marlborough Rotary club has evolved as a modern, community-focused organization, with its 2016 message as well as its 2016 attitude!

As an Honorary Rotarian since September 2013, it is a particular pleasure to work on revamping the Marlborough Rotary’s web presence.

Stay tuned…More will be posted when the new website is launched.


Go-To Plugins for Transferring a WordPress Website

When I transfer WordPress websites from one hosting company to another or even one server to another, I tend to install and use a limited set of WordPress plugins to assist in the transfer. Which plugins are used depends on the website’s set up, but, here’s a list of the plugins that help developers like myself transfer WordPress websites.

WordPress website transfer data migration

The existing website hosting area is the ‘source‘, and, the hosting area to which the website is being transferred is the ‘destination‘.

  • UpdraftPlus
    • Before doing anything else, backup the source website to remote storage. I have used this plugin for WordPress websites as large as 2.5 GB – with no problems. (Yes, gigabyte.)
    • Duplicator is an alternative for smaller websites. Remember to download the Duplicator package to your local drive and delete it from the source area before copying the website over to the destination area.
  • Broken Link Checker
    • Check the broken links on the source website, record them, and save them to your local or remote storage.
    • Use again to check the broken links in the destination website (after the transfer) in order to ensure that they match the broken links on the source website
    • Report broken links to the client
  • WP Migrate DB Pro with WP Migrate DB Pro Media Files
    WP Migrate DB Pro Media Files is an add-on plugin available with WP Migrate DB Pro.

    • Create a migration ‘definition’ that:
      • Backs up the source database. (I don’t worry about backing up the destination database as I use a clean install. See the Before Transferring a WordPress Website section.)
      • Maps the source addresses to the destination addresses (inside the database)
      • Copies the source database into the destination location.
        NOTE: Depending on how you prepare the destination hosting area, you may not want to copy the usermeta nor user tables to the destination. See the comments below about how I prep the destination hosting area.
      • Copies the images and other media from the source into the same folder locations in the destination hosting area.
  • Search and Replace
    • When I forget to map one or more addresses, or need to make mass changes to content in the destination database, I install Search and Replace. Search and Replace is a WordPress tool that makes mass changes to the database – and – the best feature is that it handles serialized data. WordPress data is stored in serialized format. This format is special and needs special handling. Search and Replace does the job well.

These are the WordPress plugins that I typically use. These plugins provide functionality for WordPress website developers. I delete them as soon as the website transfer is complete as they add no value to the public-facing website, and, we know that having extra files hanging out in your WordPress hosting account is an invitation for hackers.

Actually, Broken Links Checker does add value, but, has been reported as a source for burning up server resources. I have not experienced the burn, but prefer to err on the side of caution. So, periodically, I install it on websites, run it, record the broken links, inactivate and delete the plugin, then report the broken links to the client.

Before transferring a WordPress website

  1. Update WordPress to its latest security release on the source website
  2. Update all the plugins to their latest releases on the source website
  3. Install a clean version of WordPress in the destination hosting area
  4. Copy the .htaccess (if exists) and the wp-config files of the destination hosting area onto your local drive for safe keeping.
  5. Copy the wp-custom folder from the source over the destination folder of the same name

What plugins do you use when you transfer WordPress websites?