Move Your Damn WordPress Debug Log so It’s Not Accessible via HTTP


Every time I need to view a WordPress debug log, I get a little belly-side security loophole cringe. It completely depends on what information you stuff into it that would cause a security issue, but it’s so easy to mitigate this risk entirely—by storing (and writing to) the file outside of your document root. It drives me bat-shit crazy that anyone with a browser can simply navigate to the blatantly accessible file and view its contents.

In writing this post I searched a few high profile WordPress sites and found a few debug logs in the mix. Most of them returned with 404s, but I did find a few. No juicy debug information though, but I only spent like five minutes looking.

Anyways, I digress.

So, for some time now I’ve been implementing on any of my client websites the following solution to move the debug log to a safer, inaccessible location.

In your wp-config.php add the following:

define('WP_DEBUG', true);
if ( WP_DEBUG ) {

	// turn off wordpress debug (otherwise it will override)
	define( 'WP_DEBUG_LOG', false );

	// specify new safe path
	$path = realpath( $_SERVER["DOCUMENT_ROOT"] . '/..' ) . '/wp-logs/debug.log';
	// enable php error log
	@ini_set( 'log_errors', 'On' ); // enable or disable php error logging (use 'On' or 'Off')
	@ini_set( 'error_log', $path );


A few notes:

  • All of this code assumes you have access to your servers root filesystem. Check with your host if you’re unsure.
  • The code in it’s current form assumes that the folder and file already exist.
  • If nothing is being written to the file after these changes, you may need to adjust the permissions of the folder and file once created.

And for a bonus I use the following awesome function to write to said log file. Compliments of Stu Miller.

if (!function_exists('write_log')) {
    function write_log ( $log )  {
        if ( true === WP_DEBUG ) {
			if( is_array( $log ) || is_object( $log ) ) {
				error_log( print_r( $log, true ) );
			} else {
				error_log( $log );
Bookmark and Share
Posted in: Code Samples, Development  |  Tagged with: , ,  |  Leave a comment

Convert A Massive CSV To Many CSVs Using PHP

One CSV Many CSVs
I’m in the process of working in a CSV file with roughly 26000+ rows and 20 some odd columns. Each row represents an historical purchase order, including information such as date, time, name, address, product name, product sku, etc. My end goal is to import all these transactions into an existing e-commerce system. The trouble is, is that my import tool can only process 1500 rows in one go, or I get connection reset errors from the server.

The solution here is to break up the master CSV file into discreet 1500 row chucks and save in separate files. So rather than hack my way through Excel, copying and pasting 1500 row chunks into new workbooks (ug…) I decided to write me a little PHP script to do the job. It took about 30 minutes. Not only is this a faster way to breakup these transactions, it is completely error free. There’s a high likelihood I would have missed or duplicated some rows having had done this manually.

Current code assumes your master file is in the same directory as the script. Adjust as necessary.


@ini_set( 'display_errors', 1 );


echo 'start <br/>';

$file_name_base = 'masterfile';
$master_file = "{$file_name_base}.csv";

$fh = fopen( $master_file, "r" );
if( $fh ) { // valid file?

	$i = 0;
	$records_per_file = 1500;
	$header_row = null;

	// loop through csv rows
	while ( ( $row = fgetcsv( $fh, 0, ',' ) ) !== false ) {
		if( $i == 0 ) { // first row?
			// save column names row
			$header_row = $row;

		if( $i % $records_per_file == 0 ) { // time to create a new file?

			// some vars, duh
			$curr_file_name = "{$file_name_base}_{$i}.csv";
			$curr_fh = fopen( $curr_file_name ,"w" );
			if( isset( $header_row ) && !empty( $header_row ) && $i > 0 ) { // we cool?
				// yes, add header row
				fputcsv( $curr_fh, $header_row );
			echo "{$i} - create new file: {$curr_file_name}. <br />";
		fputcsv( $curr_fh, $row );
	echo $i . '<br/>';


Bookmark and Share
Posted in: Code Samples, Development  |  Tagged with: , ,  |  Leave a comment

Launched: Valhalla DSP

Valhalla / Grand Canyon

Gosh, it has been far too long since I posted anything. And for that I’m only apologizing to myself, which is effectively moot because I’m also, at the same time, forgiving myself. I’m sorry, Jibran. You’re forgiven, Jibran. Phew, dodged that emotional bullet.

I have considered a new years resolution to post more stuff about things and stuff that I like, but that will just stress me out. The best I can do is promise to post more often than every three months. That’s a goal I can get behind. I work in the moment. And if the idea in that moment gets old and I don’t write it down semi-humorously then I lose interest and …

(Oh look another episode of Battlestar Galactica is on.)

And from that introduction, this post, is a big one. It’s a combination of eight months of blood, sweat, stress and code that kept me from posting and alas in the end all is certainly well: we have just launched my clients new website, An incredibly simple, easy to use e-commerce site. Well, easy to use from the front-end. Quantum computer complicated, from the back-end. Well that might be an overstatement, but it’s all relative and I think it’s funny.

Who is Valhalla DSP?

Anyways, Valhalla DSP (where DSP stands for digital signal processing) is a Seattle-based company that writes incredibly popular audio plugins for home and professional recording studios all over the world. (And from Norse mythology, Valhalla is an enormous hall in some place called Asgard where the dead go to hangout with more dead people. And the image above is my interpretation, if you didn’t pick up on that.) So go forth and check out the site if you like.

I’m tired now and losing inter …

Bookmark and Share
Posted in: Portfolio, Technology  |   |  Leave a comment

Run Your Own Damn Code after PayPal Calls WooCommerce Back

PalPal Calls WooCommerce Back
This isn’t rocket science, but the WooCoommerce documentation (as robust and complete as it is) isn’t clear about how to hook into a PayPal IPN successful charge webhook call back thingy—yes, that’s its technical name. In fact “isn’t clear” insinuates some level of recognition from them that something like this can be done. But no, not one word about it. Geez. Anyways, like usual, I digress.

But, if you’re like me, you ASSUME everything can be done. I know this can be done. I just have to dig. Where is my shovel? But I’m also curious. Is this a hush hush thing? Like maybe, if they don’t ask, we won’t have to tell that it’s as easy as writing a function. Thank the dogs for StackOverflow—check out this post.

From information garnered from that post and some elbow grease, here is the function I wrote that allows you to run your own damn code after PayPal calls WooCommerce back, which is apparently super top secret. It’s also posted here.

add_action( 'valid-paypal-standard-ipn-request', 'handle_paypal_ipn_response', 10, 1 );

function handle_paypal_ipn_response( $formdata ) {
    if ( !empty( $formdata['invoice'] ) && !empty( $formdata['custom'] ) ) {
		if( $formdata['payment_status'] == 'Completed' ) {

			// unserialize data
			$order_data = unserialize( str_replace('\"', '"', $formdata['custom'] ) );

			// get order
			$order_id = $order_data[0];
			$order = new WC_Order( $order_id );
			// got something to work with?
			if ( $order ) {
				// get user id
				$user_id = get_post_meta( $order_id, '_customer_user', true );
				// get user data
				$user = get_userdata( $user_id );
				// get order items
				$items = $order->get_items();
				// loop thru each item
				foreach( $items as $order_item_id => $item ) {
					$product = new WC_Product( $item['product_id'] );
					// do extra work...


Bookmark and Share
Posted in: Code Samples, Development  |  Tagged with: , , ,  |  Leave a comment

Most recent work

  • Valhalla DSP A one man Seattle based company, writing pretty sick professional audio plugins. Check ‘em out!
  • Trivial Beersuit A site that provides professional pub trivia to bars and restaurants.

Need hosting?

  • Media Temple My go to hosting provider. You get rockstar hosting and I make a little cash. No pressure, just clean honest fun.

Past work