Back to The Gym

I went to the gym today.

About a year ago, I was doing weights (almost exclusively); but when I went today, I might have pushed myself a little too hard. I dropped my initial weights to about 60% from where I left off (60lbs now vs. 100lbs a year ago), but it still got me dizzy to the point I needed to sit in the changeroom for 30 minutes to let the dizziness and nausea subside.

But is that gonna stop me? Heck no.

Once all that stuff went away, I felt much better. After eating I felt even better.

For the record, this is my session:

  • Deadlift, 2 sets of 10 reps, 70lbs
  • Squats, 2 sets of 10 reps, 80lbs
  • Bench Press, 3 sets of 10 reps, 70lbs
  • Leg Lifts, 3 sets of 5, bodyweight only
  • Stationary Bike, 4 mins.

So you can tell that I’m really out of shape when you look and say “That doesn’t look too hard!” I know. I’m fully aware. Again, I’m not going to let that stop me. I’m going back on Wednesday.

Maybe this time, I’ll do some light cardio to get my heart back to where I can handle weights again. And I will handle weights again.

The Auto Industry is a Fraud

Click bait, n’est pas?

So as many of my Facebook friends know, I’ve been trying to sell my Buick Encore for a little over 3 months now. I have it on LeaseBusters (which in my opinion is a giant rip off, more on that later) and So far, I’ve gotten a total of 6 bites and only one serious.

What many people don’t know (unless you’ve looked at my CarProof report) is that about a year ago, the front bumper of the Encore decided that it really wanted to get to know a cement wall in a parking garage. All in all, no internal damage, just the bumper; which in a ’14 Encore is no less than 3 separate parts. Almost $4000 later, the car is probably better than brand new; if not, it is as goods as new. I’ve been told by no less than 3 dealers that the car is “in amazing shape” but because 3 pieces that have nothing to do with the performance of the vehicle had to be replaced and it crossed some magical ____ing number of $3000,”there is nothing they can do” that it affects the resale value by anywhere from $4000-7000 (depending on who you ask and where you look).

So, what you’re saying is, is that despite nothing being wrong with the vehicle, everything that has been wrong with the vehicle has been fixed, and nothing that was broken was anything that can affect the performance, operability or longevity of the car; because it cost more than a certain amount to fix, it loses a significant amount of its value.

If your house had a flood in the unfinished basement and was limited to one corner; nowhere near your furnace or water heater, and you fixed the section of concrete (or whatever) and sold your house, would you:

  1. Have to tell new buyers about it?
  2. Tell your real estate agent about it?
  3. Lose 25% of the value of your home because of it?

No. None of those things. If it happened recently, you might mention it, but since you had it taken care of professionally it wouldn’t be a big deal. It certainly wouldn’t hit your bottom line on the value of your home.

I don’t see this as any different. 

I’ve used a few options at my disposal to try and sell it. AutoTrader, for what it’s worth, is pretty good. It’s free to use as a private seller, and there are some inexpensive add-ons that can make your listing stand out. That being said, you’re competing against dealerships who have some sort of paid accounts and get all the features for every vehicle.

LeaseBusters is a full on rip-off. For the privilege of listing your vehicle with them, it costs you $249; and you have no access to change anything on the profile other than mileage and bonus cash. I’m a web guy, so I know how the Google works. So if I want my listing to stand out, among other things I can change certain keywords so that the Google can index my listing page and see those words. Nope. You’re stuck with either the wording they give you, which is some of the most horrible copywriting I’ve seen this side of a Cheerios box (or this blog); or contacting someone who could care less about your $20k vehicle because they’re busy selling some jackass’s BMW that worth 3-5 times as much.

The state of vehicle sales, at least in North America, is broken. What makes me most angry, is that we’ve all fallen into this trap of ultimate consumerism: if it’s not new, it’s of no value. Frankly, if we were hit by some kind of cosmic radiation that made all combustion engines cease to function, we would all be better for it.

Food is Fuel

I hate it. I hate having to eat healthy. There. I said it.

But I’ve lost almost 15 lbs in 2 weeks because I am eating healthy. Anyone who knows me probably knows that I’ve struggled with my weight all my life. It’s gotten to the point that in my 30s I’m on two blood pressure medications, medication to stop gout (which started in my teens), and an asthma inhaler (which started in my 20s). It’s gotten to the point that I’m more sick of those ailments than I am about hating eating healthy.

I jumped a big hurdle today. I was so tempted to get pizza, which is only 2 doors down from my office; but I didn’t. You know why? Because I’d rather live longer and miss out on one thing I enjoy to be there for many other things I enjoy. Like my wife. My kids. My business. Maybe even finding new things I could enjoy that I couldn’t before: like riding my bike to work everyday. Or skateboarding. Or skiing. Who knows, but when you have stamina, the sky’s the limit.

I’m writing this to myself as much as anyone else who may read this. I need to convince myself that missing out on the foods (gummies) that I like (steak) will have lasting benefits (bread) than the short term pleasure (chips) that bad food gives.

So I’ve lost 15 lbs. I’ve got 80 more to go, give or take 15. What’s another year of this?

I’m (loosely) following the Daniel Plan. I’m giving it a read through with a bunch of people before going full force into following it. Give it a look. If the God side of things isn’t… ummm… your thing, take a look at the 10 Day Detox Diet, which admittedly is not the best title for those who don’t believe in “cleanses,” but it gives you a rundown of food and what it does to your body.

Creating a plugin for WooCommerce

I was looking around wanting to find info on creating a plugin that leverages WooCommerce, and found their guide on their docs site. However, it didn’t go according to plan because their docs are a bit outdated, probably due to the fact they aren’t accepting submission to their own repo anymore. So without further adieu, my edited version of that tutorial.

Want to create a plugin to extend WooCommerce? WooCommerce Plugins are essentially the same as regular WordPress plugins, just with a little more finesse. Sometimes you need a little finesse, sometimes you need a lot. If you don’t know how to write a plugin, you can get started here.

Check if WooCommerce is active

Most WooCommerce plugins do not need to run unless WooCommerce is already active. You can check within your plugin to see if WooCommerce is installed:

 * Check if WooCommerce is active
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
if(is_plugin_active( 'woocommerce/woocommerce.php')) return;

// Put your plugin code here

If you are looking to create a WooCommerce plugin for a multisite, (which, why wouldn’t you?) it might look something like this:

 * Check if WooCommerce is active
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
if( !is_plugin_active( 'woocommerce/woocommerce.php' ) || !is_plugin_active_for_network( 'woocommerce/woocommerce.php' ) ) return;

// Put your plugin code here

Main file naming

The main plugin file should adopt the name of the plugin, e.g., A plugin with the directory name of plugin-name would have its main file named plugin-name.php.

Text domains

Follow guidelines for Internationalization for WordPress Developers, the text domain should match your plugin directory name, e.g., A plugin with a directory name of plugin-name would have the text domain plugin-name. No underscores.


All text strings within the plugin code should be in English. This is the WordPress default locale, and English should always be the first language. If your plugin is intended for a specific market (e.g., Spain or Italy), appropriate translation files for those languages should be included within your plugin package. More at: Using Makepot to translate your plugin.

Follow WordPress PHP Guidelines

WordPress has a set of guidelines to keep all WordPress code consistent and easier to read. This includes quotes, indentation, brace style, shorthand php tags, yoda conditions, naming conventions, and more. Please review the guidelines.

Don’t get me wrong. Guidelines are great. I’m a fan of keeping things consistent. But if you use tabs and not spaces, snuggle your braces or not… it’s not going to break your code.

Code conventions help stop basic mistakes; but in my experience, don’t prevent them completely. Understand what you are doing before you do it, and don’t just cut n paste random code.

Custom Database Tables & Data Storage

Creating custom database tables should be avoided. Whenever possible, you should always use WordPress post types, taxonomies, and options.

Consider the permanence of your data. Here’s a quick primer:

  • If the data may not always be present (i.e., it expires), use a transient.
  • If the data is persistent but not always present, consider using the WP Cache.
  • If the data is persistent and always present, consider the wp_options table.
  • If the data type is an entity with n units, consider a post type.
  • If the data is a means or sorting/categorizing an entity, consider a taxonomy.
  • Logs should be written to a file using the WC_Logger class.

Prevent Data Leaks

Try to prevent direct access data leaks. Add this line of code after the opening PHP tag in each PHP file:

if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly


WooCommerce Plugins seem to all have a “standard” WordPress readme. I’ve only ever noticed this since diving into WooCommerce Plugins. You should add two extra headers to the top of the readme file:

  • WC requires at least
  • WC tested up to

Your readme might look something like this:

=== Plugin Name ===
Contributors: (this should be a list of userid's)
Tags: comments, spam
Requires at least: 4.0.1
Tested up to: 4.3
Stable tag: 4.3
License: GPLv3 or later License
WC requires at least: 2.2
WC tested up to: 2.3

Plugin Author Name

Consistency is important to us and our customers. Products offered through should provide a consistent experience for all aspects of the product, including who the customer contacts if they have queries.

It should also be obvious for the customer to differentiate a product purchased at from a product purchased elsewhere, when looking through their plugin list in WordPress.

Thus, the following plugin headers should be in place:

The Plugin Author is WooCommerce
The Developer header is YourName/YourCompany, with the Developer URI field listed as
Copyright information is “WooCommerce”

Since you aren’t going to be selling on WooCommerce directly, the previous information is pointless. That being said, your plugin won’t work if you don’t have this at the beginning of your main plugin PHP file (because you read the primer on plugins, right?):

 * Plugin Name: WooCommerce Extension
 * Plugin URI:
 * Description: Your extension's description text.
 * Version: 123.234.55656
 * Author: Sammy McSammerson
 * Author URI:
 * Text Domain: woocommerce-extension

In the WooCommerce Helper plugin — required for customers to receive product updates — developer information is included as part of the plugin info to ensure developers are given the credit they deserve. Nope.

Plugin URI

Ensure that the Plugin URI line of the above plugin header is provided. This line should contain the URL of the plugin’s product/sale page on (if sold by WooCommerce) or to a dedicated page for the plugin on your website. Again, not needed.

Use WordPress/WooCommerce UI

It’s important to keep a consistent UI across plugins. I can’t stress this enough. Having a custom designed interface, unless it’s super user friendly, can be jarring to the user. All plugins should be hooked into the WordPress/WooCommerce UI. Application data should be loaded via API instead of an iframe. Because, why would you use an iframe? Are you from 10 years ago?

Admin Menu Screens

Both WordPress and WooCommerce provide an extendable administration menu system, allowing for menu items to be added anywhere from the top level of the navigation to an integration sub-menu in the WooCommerce “Integrations” tab. It is important to understand the reasons for each of the various navigation systems, and in which circumstances we expect each to be employed.

tl;dr – which to use when, and why

  • If your plugin integrates with a third party service (e.g., to receive tax rates or connect to a Help Desk), you should use the integration class.
  • If your plugin adds a settings screen to set up the plugin, settings should be under an appropriate tab on the WooCommerce > Settings screen.
  • If your plugin has settings that don’t fit under existing tabs, and creating a sub-tab isn’t appropriate, create a top-level settings tab.
  • If your plugin adds administration screens that don’t involve settings (e.g., Checkout Add-Ons has a screen for managing checkout add-on fields), use a sub-menu under the WooCommerce admin menu item.

WooCommerce Integrations Sub-Menu

WooCommerce provides a facility for registering product integrations. If integrations are registered, an Integrations tab is made available under the WooCommerce > Settings screen.

If your plugin interfaces with a third-party service other than a payment gateway or shipping method that have their own structures, your settings screen should be placed in the Integrations tab.
If you’re integrating a plugin with WooCommerce, we strongly recommend that you use the WC_Integration class.

WordPress Settings Sub-Menu

The top-level Settings menu in WordPress is reserved for screens that are only accessible by full administrators. If your plugin has a single settings screen and is a standalone product, your settings screen should go here.

As WooCommerce extensions are not standalone products, your settings screen would look out of place under the main WordPress Settings menu.
Look how lost and out of place I look, being so far away from the other WooCommerce admin screens.
How a plugin would look if located under WordPress Settings, far away from the the WooCommerce admin.

WooCommerce Sub-Menu

If your plugin adds administration screens that don’t involve setting up your plugin, these screens can sit under the WooCommerce Sub-Menu. For example, Coupon Campaigns adds a WooCommerce sub-menu item to create, edit and delete coupon campaigns; Checkout Add-Ons adds a screen for managing checkout screen add-on fields.

Another reason is that not all admin screens belong in the WooCommerce sub-menu. If everyone placed their settings screen here, there would be a lengthy administration menu. This is inconvenient for the WooCommerce store owner or manager.

Settings used to set up your plugin do not belong in a WooCommerce sub-menu item.

WooCommerce Settings Tab

WooCommerce Settings tabs are intended for top-level, broad topics around setting up WooCommerce.

If your plugin requires settings that don’t fit any of the provided settings tabs, and does not interface with a third-party service, use a new WooCommerce Settings tab.

We make this distinction to avoid lengthy settings tab bars, which do not provide a pleasant UX for a store owner or manager.

If your settings require a page but fall under one of the top level tabs like Products, add them in a section to keep it organized and user friendly.

More info at Adding a Section to a Settings Tab — all it takes is a few lines of code.

Make it Extensible

Developers should use WordPress actions and filters to allow for modification/customization without users having to touch the plugin’s core code base. Don’t ever touch core. Unless you become a core contributor, but in that case, you’re probably way too advanced to have read this far.

And if your plugin creates a front-end output, it’s recommended to have a templating engine in place so users can create custom template files in their theme’s WooCommerce folder that overwrites the plugin’s template files. Now, we use the term templating engine loosely here, don’t go grabbing twig or smarty or anything. It doesn’t need to be that complicated.

For more information, check out Pippin’s post on Writing Extensible Plugins with Actions and Filters.

Remove Unused Code

With version control, there’s no reason to leave in commented out code that can be annoying to scroll through and read. Remove it and add it back later if needed. So do yourself a favour and use Git or Subversion.


If you have a function, what does the function do? There should be comments for most if not every function in your code. Someone/You may want to modify, and comments are helpful for that. I recommend using PHP Doc Blocks.

Avoid God Objects

God Objects are objects that know or do too much. I had a colleague of mine explain something called “Thor” to me. To this day, I still am not completely sure what it did, but it did way too much. The point of object-oriented programming is taking a large problem and breaking it into smaller parts; for example, a train would have both an Engine object and multiple Car objects; the Car object could contain multiple Person objects, etc.  By having functions do too much, it’s hard to follow that logic and a bug will be harder to fix. Instead of having massive functions, break them down into smaller pieces.

Test Your Code with WP_DEBUG

Always develop with WP_DEBUG mode on, so you can see all PHP warnings sent to the screen. It’s usually things like making sure a variable is set before checking the value.

Separate Business Logic & Presentation Logic

It’s a good practice to separate business logic (i.e., how the plugin works) from presentation logic (i.e., how it looks). Two separate pieces of logic are more easily maintained and swapped if necessary. An example is to have two different classes — one for displaying the end results, and one for the admin settings page. And there’s no reason you can’t keep your presentation logic in separate files.Putting presentation logic in functions/methods is just messy and lazy.

Use Transients to Store Off Site Information

If you provide a service via an API, it’s best to store that information so future queries can be done faster, and the load on your service is lessened. WordPress transients can be used to store data for a certain amount of time.

Logging Data

You may want to log data that can be useful for debugging purposes. This is great with two conditions:

  1. Allow any logging as an ‘opt in’.
  2. Use the WC_Logger class. A user can then view logs on their system status page.

If adding logging to your extension, here’s a snippet for presenting a link to the logs, in a way the extension user can easily make use of:

$label = __( 'Enable Logging', 'your-textdomain-here' );
$description = __( 'Enable the logging of errors.', 'your-textdomain-here' );

if ( defined( 'WC_LOG_DIR' ) ) {
  $log_url = add_query_arg( 'tab', 'logs', add_query_arg( 'page', 'wc-status', admin_url( 'admin.php' ) ) );
  $log_key = 'your-plugin-slug-here-' . sanitize_file_name( wp_hash( 'your-plugin-slug-here' ) ) . '-log';
  $log_url = add_query_arg( 'log_file', $log_key, $log_url );

  $label .= ' | ' . sprintf( __( '%1$sView Log%2$s', 'your-textdomain-here' ), '<a href="' . esc_url( $log_url ) . '">', '</a>' );

$form_fields['wc_yourpluginslug_debug'] = array(
  'title' => __( 'Debug Log', 'your-textdomain-here' ),
  'label' => $label,
  'description' => $description,
  'type' => 'checkbox',
  'default' => 'no'

UI for service integration plugins

If your plugin relies on connecting to an external service (for example, your service is a payment gateway, shipping method, or other service integration), it’s important to inform your users that a connection is required in order to use the plugin.

To do this, we recommend an admin notice, linking to the specific service integration screen within WooCommerce.

The following code was taken directly out of an integration we WooCommerce developed with Mailchimp, and forms part of a larger PHP class. The code has been preserved, rather than modified to be an example, for your reference in the context of a PHP class.

// Display an admin notice, if setup is required.
add_action( 'admin_notices', array( $this, 'maybe_display_admin_notices' ) );

 * Display an admin notice, if not on the integration screen and if the account isn't yet connected.
 * @access public
 * @since 1.0.0
 * @return void
public function maybe_display_admin_notices () {
  if ( isset( $_GET['page'] ) && 'wc-settings' == $_GET['page'] && isset( $_GET['section'] ) && 'mailchimp' == $_GET['section'] ) return; // Don't show these notices on our admin screen.

  // Find a different method of retrieving this value.
  $api_key = WC()->integrations->integrations['mailchimp']->get_option( 'wc_mailchimp_api_key' );

  if ( '' == $api_key ) {
    $url = $this->get_settings_url();
    echo '<div class="updated fade"><p>' . sprintf( __( '%sWooCommerce MailChimp is almost ready.%s To get started, %sconnect your MailChimp account%s.', 'woocommerce-mailchimp-integration' ), '<strong>', '</strong>', '<a href="' . esc_url( $url ) . '">', '</a>' ) . '</p></div>' . "\n";
} // End maybe_display_admin_notices()

 * Generate a URL to our specific settings screen.
 * @access public
 * @since 1.0.0
 * @return string Generated URL.
public function get_settings_url () {
  $url = admin_url( 'admin.php' );
  $url = add_query_arg( 'page', 'wc-settings', $url );
  $url = add_query_arg( 'tab', 'integration', $url );
  $url = add_query_arg( 'section', 'mailchimp', $url );

  return $url;

Lovingly stolen & modified from WooCommerce Docs