How to Debug WordPress WP-Cron Jobs?

Debugging php code that’s run by WordPress Cron is difficult because:

1) If you don’t know how to force the wp-cron job to run, you have to wait for it to be called on schedule. WP-Cron jobs are often run on an interval like hourly, daily, etc.

2) You can’t see any error messages on the website, even if you have WP-DEBUG set to TRUE.

Today I’ve had a lot of success in debugging wp-cron jobs. This is what I now know how to do, and I’m saving it here for my own future reference, and perhaps it will help you too!

Force WP-Cron Job to Run

This worked for me in WordPress 4.2.2
1. Install the plugin Core Control.
2. In WordPress Admin, go to Tools->Core Control.
3. Check off “Cron Module” and click save.
4. Click the link “Cron Tasks”
5. Click on “Run Now” next to the cron job you are debugging.
6. If an error occurs, it will say “Error occurred” at the top of the page.

Wordpress Core Control Plugin Cron Tasks Module
WordPress Core Control Plugin Cron Tasks Module

View PHP Error Messages

There are two ways I was able to view the error message today.  There should be a better way, and perhaps there is, but this is what I figured out.

View PHP Error Log

It turns out that my development server, which is a WAMP setup, is already recording all php errors in this file:

E:\wamp\logs\php_error.log

If you are running a local server, you may discover that error messages are already being recorded.  If not, here are instructions on how to set up the PHP error log for WordPress.

Because the log file had been recording errors (and notices) for what seems like a century, the file was huge.  To simplify debugging, I deleted the log file contents and saved it as a blank file.  Then I ran my cron job and checked the file again.  Ta-da!  My error was prominently displayed.

View PHP Error Message in PHP Storm with XDebug

 

If you can’t log errors or view the PHP error log, you can view the error while debugging… Keep reading to find out how…

Fix Problems that Don’t Cause Error Messages

Sometimes programming errors are errors in logic, or errors where you use the wrong variable (maybe a typo) and it doesn’t throw an exception but rather the program just doesn’t work correctly.

That’s when a debugger is really helpful!  If you don’t understand debugging, I suggest this Lynda.com course:  Debugging the Web: Javascript.  Yes, it’s about javascript, but it explains concepts that you can use in any programming language with any debugger. I watched it recently and the knowledge gained definitely applies to debugging WordPress.

These are the 3 pieces of software I use to debug WordPress and PHP:

  1. Xdebug
  2. PHP Storm
  3. XDebug Helper Chrome Extension

These are the tutorials I used to set up debugging:

How I debugged the WordPress Cron Job

  1. Set a breakpoint on the first line of the function called by wp-cron.
  2. Click “Play”
  3. When it stops at my breakpoint, click “Step Into” repeatedly until I see my error.

In my case, the error message was displayed in the debugger, next to the error_handler function (see the line above the blue line).  The text is gray, but it shows the contents of the $message variable:

Debugging WordPress with PHP Storm

 

And there you go, one more way to view your PHP error.  Hope this has helped you.  If you have any questions, I will try to answer them.

More About WP-Cron

WP-Cron can cause WordPress problems and might make your site run slow.  But, cron jobs often do very important tasks and disabling them will cause problems.  Here is how to fix this issue:

Properly Setting Up WordPress Cron Jobs

 

Sanitizing & Validating User Input for Amazon Product Advertising API

Summary:  Remove apostrophes to prevent Amazon from returning “No Results”

As a security-conscious web programmer, I always sanitize user input. It’s something you have to do to prevent attacks like SQL Injection and Cross-Site Scripting.  Basically it means that you never trust user input to be safe, and you always filter or sanitize it to remove potentially dangerous input.   PHP has lots of filters for sanitization, so that part is easy.  For Amazon item search, my PHP code filters the user input like this:


if(isset($_POST['title']) && !empty($_POST['title'])) {
     $search_values['Title']= filter_var($_POST['title'], FILTER_SANITIZE_STRING);
}

But there’s a second step.   In addition to sanitizing data, you also want to validate it to make sure that it’s in the expected format.  But, in order to validate correctly, you have to understand the rules about what’s expected. Sometimes the rules are obvious, but other times you’re working with a bit of a black box.

Third party APIs are like black boxes.  You can’t read the code.   You only have the documentation to rely upon.   Giving the wrong input will get you errors or no results, and you might not know what you’re doing wrong.  So, you need to experiment and see if you can figure out what’s allowed and what’s not.

This post is specific to the Amazon Product Advertising API, which is an Amazon service that allows you to look up product information, like availability, pricing, keyword search, etc.

I use the Amazon Product Advertising API for several different projects, and for one of them, my application uses the ItemSearch operation. Specifically, I often search the Books category by Title.

Amazon’s API behaves differently than the search function on their site.  On their site, if you put in an apostrophe, the site just ignores it.  When using the API, you get no results.

So, the solution is to always strip the user input of all apostrophes. Or, if you’re a fellow programmer, you might call them single quotes. If you leave the apostrophe in, you’ll get no results. If you remove it, you hopefully get lots of results!

In my program, I am sending the user input via an HTML Form using Ajax.  My browser actually encodes the user input before sending it to the server.  It encodes the apostrophe character as its html entity which is '.

So, in my back end PHP code, I remove the apostrophe with this:


str_replace("'", "", $my_search_string);

Problem solved!   In actuality, I have combined that function with my code for sanitization, and the whole thing looks like:

 


if(isset($_POST['title']) && !empty($_POST['title'])) {
     $search_values['Title'] = str_replace("'", "", filter_var($_POST['title'], FILTER_SANITIZE_STRING));
}

How to embed C3.js Javascript Charts in WordPress Posts

I’ve been working with C3.js graphs for an admin website and thought it would be fun to use it on this WordPress blog.  You can use most Javascript libraries in WordPress, but it takes a little more work.  If you know how to write Javascript, then you’ll find that C3.js offers a relatively easy way to create custom pie charts, timeseries charts, line and bar graphs, etc.   Here’s an example of a graph created with C3.js.  I used real historical weather data to compare the record high July 2015 temperatures to average temperatures.

Tacoma, WA: Record High July 2015 Temperatures

Here’s how I created the above graph.

First, I downloaded the c3 and d3 libraries (you can get the zip file on github). I unzipped the file and put the c3.css, c3.min.js, d3.min.js files into the root directory of my wordpress theme.

Side note: I am using a child theme, as you should too, to prevent problems if your theme gets automatically updated.  If you are not familiar with child themes, check out this WordPress tutorial.

Next, I added the following code to my functions.php file:

functions.php


add_action( 'wp_enqueue_scripts', 'add_c3_scripts' );

function add_c3_scripts() {
	$d3_url =  get_stylesheet_directory_uri() . '/d3.min.js';
	$c3_url =  get_stylesheet_directory_uri() . '/c3.min.js';
	$c3_css =  get_stylesheet_directory_uri() . '/c3.css';
	$my_graphs_url =  get_stylesheet_directory_uri() . '/my_graphs.js';
	wp_enqueue_script( 'd3', $d3_url );
	wp_enqueue_script( 'c3', $c3_url, 'd3' );
	wp_enqueue_script( 'my_graphs', $my_graphs_url, 'c3' );
	wp_enqueue_style( 'c3', $c3_css );
}

Next, I create the my_graphs.js file in the root directory of my theme.  For better organization, you could put this in a scripts folder and change the above url accordingly.

In the my_graphs.js file, I write a Javascript function which creates a C3 chart.  It looks like this:

my_graphs.js


function july_2015_graph() {
    var chart = c3.generate({
        bindto: '#july_2015_graph',
        color: {
            pattern: ['#396ab1', '#cc2529']
        },
        data: {
            x: 'x',
            columns: [
                ['x', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ,16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31],
                ['Average', 69, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 72, 72, 73, 73, 74, 74, 75, 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, 75, 75, 75]
            ],
            type: 'spline'
        },
        axis: {
            x: {
                label: 'Date'
            },
            y: {
                label: 'Temperature (F)',
                min: 65,
                max: 95
            }
        },
        transition: {
            duration: 100
        }
    });

    setTimeout(function () {
        chart.load({
            columns: [
                ['2015', 89, 92, 92, 91, 91, 84, 83, 87, 81, 71, 72, 78, 79, 81, 80, 79, 80, 91, 94, 80, 75, 74, 77, 75, 71, 71, 75, 81, 88, 92, 95]
            ]
        });
    }, 1000);

}

The “bindto:” line at the top of that code segment tells the c3.js Javascript Library where to put the graph.

To display the graph in this post, I edit the post in “text” mode (select the text tab at the top of the wordpress post editor) and add this code:


<div id="july_2015_graph"></div>
<script type="text/javascript">
july_2015_graph();
</script>

 

For more information about how to use Javascript with WordPress, check out this page: Using Javascript in WordPress