Half Assed Cron With WP Cron

Posted in Code, Programming on February 8th, 2010 by Eric LambBe the first to comment

I was working on a project recently that was using WordPress as the base platform and had a need for a scheduled task function. Ordinarily, this would be the type of functionality that I would just setup a cron job for; but since Wordpress has a pseudo cron system in place I decided to investigate that as an option. Long story short; fuck that man.

Working With WP Cron

Working With WP Cron

As mentioned, Wordpress has a pseudo cron mechanism available to Wordpress developers for scheduling tasks called WP Cron. WP Cron works using series of functions available for plugin developers to create their own cron style tasks. In theory Wordpress makes this easy(ish) using the built in cron API but the reality is that it’s not only confusing and awkward to implement but once you’re complete you have to allow for a bit of latitude on the scheduling.

Take a look at scheduling a task in Wordpress. Basically, it works by adding a function to your activation hook, within a plugin, that like the below:

<?php 
register_activation_hook(__FILE__, 'my_activation');
add_action('my_hourly_event', 'do_this_hourly');
 
function my_activation() {
	wp_schedule_event(time(), 'hourly', 'my_hourly_event');
}
 
function do_this_hourly() {
	// do something every hour
}
?>

Pretty simple implementation really though not very “cron” like in syntax. The important part is the call to “wp_schedule_event()” which takes 4 paramaters (start date, recurrence, hook and arguments). According to the API manual the function:

Schedules a hook which will be executed by the WordPress actions core on a specific interval, specified by you. The action will trigger when someone visits your WordPress site, if the scheduled time has passed. See the Plugin API for a list of hooks.

The problem I had was that this function only allows for 3 options on recurrence; hourly, twicedaily and daily. I needed my function to run at a specific time. (It was EXTREMELY important that it ran during a specific interval.)

This isn’t to say that it’s not possible to schedule a task for a specific time; it’s just a pain in the ass. You have to write all the logic to determine when to add a new task and removing expired tasks. Ughh. To me the question becomes “Should I write a couple hundred lines of code or just add a single line to my crontab?”.

Crontab baby.

Bookmark and Share

Introducing WP-hResume

Posted in Code on January 25th, 2010 by Eric LambBe the first to comment

Recently I had a problem; the plugin I was using to display my resume on my site mysteriously started causing WordPress to throw a weird error. Not to get too technical about it but the issue was a little more complicated than I was willing to deal with personally and I was prepared to resign myself to not having an online resume for a while. Sigh…

Fast forward about a month and the hoped for “fix” for the plugin never came. This left me with no alternative than to write my own. Yay!!

Looking at the plugin I was using, LinkedIn hResume, and noticing some of the flaws (like the plugin ONLY working with LinkedIn) I realized I could one-up the plugin and make something a lot more useful to more people by writing a new, custom resume plugin.

And that’s what we have here; WP-hResume. WP-hResume is a wordpress plugin that takes any hresume encoded webpage and allows you to place the content on your site. It’s been tested using both LinkedIn and Stack Overflow Careers as well as quite a few stand alone hresume pages. It works wonderfully.

Please take a look and let me know if you like :)

Bookmark and Share

Parse Apache Log Files With PHP

Posted in IT, Programming on January 9th, 2010 by Eric Lamb1 Comment

Parsing the log files generated by Apache is one of those random tasks with a random occurrence in my world. This is a task that, until recently, hadn’t come up enough to warrant any sort of a ready solution (and it was just fun enough to be ok to write a custom solution). So every time this came up I would always fire up Google and go on a scavenger hunt for a starter script written in php.

Parse Apache Log Files With PHP

Parse Apache Log Files With PHP

This always felt like a good idea at the time the need came up. These days, for some ungodly reason, parsing Apache logs seems to come up a little too frequently to keep this up. In the spirit of making my life a hell of a lot easier for tomorrow I’ve taken a shot at writing an Apache log parser written in PHP.

One thing I decided to implement is a filtering system so you can filter out based on a provided regex. Might not be too useful to everyone but it should be trivial to remove the functionality.

Anyway, I hope someone finds this useful (even to learn from and, of course, use)

Here’s the main class:

<?php
/**
 * Apache Log Parser
 * Parses an Apache log file and runs the strings through filters to find what you're looking for.
 * @author Eric Lamb
 *
 */
class apache_log_parser
{
	/**
	 * The path to the log file
	 * @var string
	 */
	private $file = FALSE;
 
	/**
	 * What filters to apply. Should be in the format of array('KEY_TO_SEARCH' => array('regex' => 'YOUR_REGEX'))
	 * @var array
	 */
	public $filters = FALSE;
 
	/**
	 * Duh.
	 * @param string $file
	 * @return void
	 */
	public function __construct($file)
	{
		if(!is_readable($file))
		{
			return 	FALSE;
		}
 
		$this->file = $file;
	}
 
	/**
	 * Executes the supplied filter to the string
	 * @param $filer
	 * @param $status
	 * @return string
	 */
	private function applyFilters($str)
	{
		if(!$this->filters || !is_array($this->filters))
		{
			return $str;
		}
 
		foreach($this->filters AS $area => $filter)
		{
			if(preg_match($filter['regex'], $str[$area], $matches, PREG_OFFSET_CAPTURE))
			{
				return $str;
			}
		}
	}
 
	/**
	 * Returns an array of all the filtered lines 
	 * @param $limit
	 * @return array
	 */
	public function getData($limit = FALSE)
	{
		$handle = fopen($this->file, 'rb');
		if ($handle) {
			$count = 1;
			$lines = array();
		    while (!feof($handle)) {
		        $buffer = fgets($handle);
		        $data = $this->applyFilters($this->format_line($buffer));
		        if($data)
		        {
		        	$lines[] = $data;
		        }
 
		        if($limit && $count == $limit)
		        {
		        	break;
		        }
		        $count++;
		    }
		    fclose($handle);
		    return $lines;
		}		
	}
 
	/**
	 * Regex to parse the log file line
	 * @param string $line
	 * @return array
	 */
	function format_log_line($line)
	{
		preg_match("/^(\S+) (\S+) (\S+) \[([^:]+):(\d+:\d+:\d+) ([^\]]+)\] \"(\S+) (.*?) (\S+)\" (\S+) (\S+) (\".*?\") (\".*?\")$/", $line, $matches); // pattern to format the line
		return $matches;
	}
 
	/**
	 * Takes the format_log_line array and makes it usable to us stupid humans
	 * @param $line
	 * @return array
	 */
	function format_line($line)
	{
		$logs = $this->format_log_line($line); // format the line
 
		if (isset($logs[0])) // check that it formated OK
		{
			$formated_log = array(); // make an array to store the lin info in
			$formated_log['ip'] = $logs[1];
			$formated_log['identity'] = $logs[2];
			$formated_log['user'] = $logs[2];
			$formated_log['date'] = $logs[4];
			$formated_log['time'] = $logs[5];
			$formated_log['timezone'] = $logs[6];
			$formated_log['method'] = $logs[7];
			$formated_log['path'] = $logs[8];
			$formated_log['protocal'] = $logs[9];
			$formated_log['status'] = $logs[10];
			$formated_log['bytes'] = $logs[11];
			$formated_log['referer'] = $logs[12];
			$formated_log['agent'] = $logs[13];
			return $formated_log; // return the array of info
		}
		else
		{
			$this->badRows++; // if the row is not in the right format add it to the bad rows
			return false;
		}
	}
}
?>

And here’s an example of how to use it:

<?php
$data = new apache_log_parser($d->path.'/'.$entry); // Create an apache log parser
$data->filters = array(
	'path' => array('regex' => '/^.*\.(FLV|flv)$/') //pull only flv files
);
 
$data = $data->getData();
?>

A couple things to note about this script though:

1. The regex and parsing was pretty stolen from the Apache Log Parser on PHPClasses.org.
2. Without filters the script is pretty memory intensive. My needs don’t require anything client facing but heed my adivice; Don’t use this on a public web server.

Bookmark and Share

Get Rid of HTML Templates With HAML

Posted in Code, Programming on January 4th, 2010 by Eric Lamb3 Comments

I was working with a new client the last couple weeks where I met a python developer who introduced me to something I hadn’t head of before: HAML. HAML stands for XHTML Abstraction Markup Language and is a markup “language” modeled after, what appears to me to be, YAML. (The syntax and structure is very similar to YAML but I couldn’t find any reference to this being intentional so I could be wrong.)

Get Rid of Templates With HAML

Get Rid of Templates With HAML

Anywho, it looks like HAML was originally created for Ruby on Rails but has been adopted by a few other programming languages and environments like PHP. According to the official site:

Haml is a markup language that’s used to cleanly and simply describe the HTML of any web document without the use of inline code. Haml functions as a replacement for inline page templating systems such as PHP, ASP, and ERB, the templating language used in most Ruby on Rails applications. However, Haml avoids the need for explicitly coding HTML into the template, because it itself is a description of the HTML, with some code to generate dynamic content.

So in a nutshell HAML allows for the replacement of the normal, everyday, HTML markup with something a little more “elegant”. The HAML Wikipedia page has a really good example of the differences between HTML and HAML (which I’ve stolen and placed below):

HAML

!!!
%html{ :xmlns => "http://www.w3.org/1999/xhtml", :lang => "en", "xml:lang" => "en"}
  %head
    %title BoBlog
    %meta{"http-equiv" => "Content-Type", :content => "text/html; charset=utf-8"}
    = stylesheet_link_tag 'main'
  %body
    #header
      %h1 BoBlog
      %h2 Bob's Blog
    #content
      - @entries.each do |entry|
        .entry
          %h3.title= entry.title
          %p.date= entry.posted.strftime("%A, %B %d, %Y")
          %p.body= entry.body
    #footer
      %p
        All content copyright © Bob

HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
  <head>
    <title>BoBlog</title>
    <meta content='text/html; charset=utf-8' http-equiv='Content-Type' />
    <link href="/stylesheets/main.css" media="screen" rel="Stylesheet" type="text/css" />
  </head>
  <body>
    <div id='header'>
      <h1>BoBlog</h1>
      <h2>Bob's Blog</h2>
    </div>
    <div id='content'>
      <div class='entry'>
        <h3 class='title'>Halloween</h3>
        <p class='date'>Tuesday, October 31, 2006</p>
        <p class='body'>
          Happy Halloween, glorious readers! I'm going to a party this evening... I'm very excited.
        </p>
      </div>
      <div class='entry'>
        <h3 class='title'>New Rails Templating Engine</h3>
        <p class='date'>Friday, August 11, 2006</p>
        <p class='body'>
          There's a very cool new Templating Engine out for Ruby on Rails. It's called Haml.
        </p>
      </div>
    </div>
    <div id='footer'>
      <p>
        All content copyright © Bob
      </p>
    </div>
  </body>
</html>

After comparing the two examples above it should be pretty obvious how HAML is structured compared to good old HTML. There’s nothing too crazy going on in the syntax but that doesn’t matter nearly as much as there’s another syntax to learn. Still, if you can get past that HAML is pretty intriguing and worth it to look at.

Now, if you’re a PHP developer you may be saying, “That’s great and all but what the fuck do I care about a Ruby on Rails tool?”. Well, that’s one of the cool parts; there’s a PHP implementation of HAML a PHP class called phpHaml. phpHaml is a PHP class to compile HAML code into static HTML templates, which is useful if you want to jump right in and build a template system.

At it’s most basic a phpHaml script looks like the below:

<?php
require_once './includes/haml/HamlParser.class.php';
$parser = new HamlParser('./tpl', './tmp/haml');
echo $parser->setFile('example2.haml');
?>

Simple. Simple. Simple. Obviously, there are other, more advanced options for working with phpHaml but 3 lines is really all it takes for the learning portion.

My interest in HAML is a little greater than my time allows so I haven’t been able to play too deeply with phpHaml. From my limited time with it though I do feel that the the compiler works as expected on the limited HTML I threw at it and it’s probably worth a deeper look. Oh, yeah, as an added bonus phpHaml also includes a SASS parser (but that’s a whole other post) to play with.

Bookmark and Share

WP-Click-Track 0.7 Released (Umm Last Week)

Posted in Brain Dump on December 29th, 2009 by Eric Lamb1 Comment

I hadn’t really had much time to announce this (what with the holidays and stuff) but last week WP-Click-Track 0.7 was released. This release includes a few bug fixes and a couple new features. I’d planned to release this a while ago but testing took a little longer than anticipated but it’s finally done.

WP-Click-Track 0.7 Released (Umm Last Week)

WP-Click-Track 0.7 Released (Umm Last Week)

There were a couple minor, edge, bugs that I don’t want to go into detail about but there were 2 in particular that deserve a mention.

First, there was a bug fix for SSL enabled admins. This one I hadn’t really anticipated; I’d never thought someone would use ssl for the admin panel. The problem was that if you went to the admin through ssl the graphs wouldn’t render properly. My bad.

Then there was an issue in the graphs. If the charted number was over 1,000 the chart would basically throw up. Rookie move on my part but some escaping fixed that right up. If you ran into this bug I’m really sorry.

0.7 also includes an improved cookie model. I admit, I’ve been completely lazy about cookie management for years now. Yes, sessions are nice but when you’re building for a multi-server environment sessions can get a little tricky. Problem is that there are some pretty specific rules for cookies and just setting a cookie willy nilly, without any thought to the implications, can screw things up. Now it’s much, much, better.

Among the additions there’s a new configuration value to disable tracking of internal links. This should help with all the clicks in peoples galleries I’ve been hearing so much about :)

Speaking of configuration the entire configuration section has been rewritten to be more user friendly. Instead of the HUGE and confusing single page everything is organized into tabs and should, hopefully, make for a better experience when you do have to configure something.

Anyway, you can install it within the WordPress plugin manager or if you want to take a  look at the code here you go.

Bookmark and Share

Blackberry Secret Codes

Posted in IT on December 23rd, 2009 by Eric Lamb1 Comment

After my little foray into unlocking my old Blackberry Curve I started to think that there were probably other special codes to play around with. I’ve done a little bit of research and it turns out, yup, there are quite a few special codes to do some random things.

Decibel meter

Normally, the signal strength meter is a series of bars like the below image. Hold “Alt” and press “N”, “M”, “L”, “L”. To undo just redo :)

Normal Signal Strength Indicator

Normal Signal Strength Indicator

Decibal Meter

Decibal Meter

View Source Code

This one every web developer should know. In the Browser, hold “Alt” and press “R”, “B”, “V”, “S”

View Source Code

View Source Code

Help Me! menu

If you ever call up for support chances are you’ve been told to enter this one. It shows a bunch of info in one place but most of it will be greek to most people.  Hold “Alt” and (left) “shift”, then press “H”.

Help Me! Menu

Help Me! Menu

Display IMEI Code

As far as I know this is really only useful for unlocking a device. Type “*”, “#”, “0″, “6″, “#” on the Home screen.

Display IMEI Code

Display IMEI Code

Event Log

The Event Log is probably only going to be useful if you’re a developer or similar. It displays all the last Java goodies that have happened since starting the device. Hold “Alt” and press “L”, “G”, “L”, “G”.

Event Log

Event Log

Show SIM Information

This code will display the details about a SIM card. You have to enter this code from the SIM Options page and press “M”, “E”, “P”, “D”

Show SIM Information

Show SIM Information

View Refld and ServiceUserId

From inside a message hold “Alt” and press “V”, “I”, “E”, “W”

View Refld and ServiceUserId

View Refld and ServiceUserId

View Data Usage & Voice Usage

This one is really only good if you have a new, unused, Blackberry. It maxes out at the below but if you buy a “new” Blackberry enter this code and verify it. From Status Options page press “B”, “U”, “Y”, “R”

View Data Usage & Voice Usage

View Data Usage & Voice Usage

Hard Reset

Doing a Hard Reset is like taking the battery out and inserting it again. Handy if you’re not in the mood to fuddle with the case. Hold ALT + Right Shift + Del

Validate Contact List

I’m honestly not really sure what these last two do but I’m listing them anyway for completeness. Hold “Alt” and press “V”, “A”, “L”, “D” in address book list

Rebuild Contact List

Hold “Alt” and press “V”, “A”, “L”, “D” in address book list.

These are all the “secret codes” I could find but that doesn’t mean there aren’t any more. Also, these codes were only verified on the Blackberry Bold 9000 so they may not work with all devices. If anyone has any new ones please leave a comment and I’ll update a list.

Bookmark and Share

How To Unlock AT&T Blackberry

Posted in Brain Dump, IT on December 21st, 2009 by Eric LambBe the first to comment

My business partner recently had her phone literally break apart in her hands. Since communication between us is pretty crucial I decided to give her a backup Blackberry Curve I had as a replacement for my Blackberry Bold. Problem was that the Curve was bought through AT&T and she uses T-mobile. The phone would have to be unlocked.

How To Unlock AT&T Blackberry

How To Unlock AT&T Blackberry

Initially, I was a little nervous about the process of  unlocking the Blackberry. I’d never personally tried anything like this and my direct experience with the process was that a 3rd party company would have to be brought into the mix. I didn’t relish the idea of paying someone to handle what seemed to be a simple exercise when I’m capable of pushing buttons on a freaking phone.

Turns out it’s actually extremely easy to handle this yourself though it does require a phone call to AT&T support. Simply call them up and they’ll ask you for your IMEI code; it’s under the battery on the serial number label. They’ll send you an email, like the below, that’ll walk you through the process.

Your device unlock request was received and processed, see below for details:

IMEI: YOUR_IMEI_NUMBER

Unlock Code: YOUR_UNLOCK_CODE

Caution: If this process is unsuccessful ten times in a row, the phone will be permanently locked to the at&t network. Do not attempt to enter the code more than one (1) time total.  Instructions below will assist you in unlocking your device, if these steps are unsuccessful please contact us at 1-800-331-0500 or (916) 843-4685 from overseas.

Blackberry 8310

Follow these steps to unlock device:

1. Turn off the radio! VERY IMPORTANT

2. Go to “Options”

3. Scroll to and select “Advanced Options”

4. Click on “SIM Card”

5. Type “MEPD” (You will not see on display what is being typed. To obtain a “P” double tap “OP” key)

6. Type “MEP2” (To obtain a “P” double tap “OP” key. Press “ALT “key to obtain a “2″)

7. Enter the unlock code

8. Press enter

9. Reboot device. Device is now unlocked.

Note: To verify the IMEI, dial *#06# on device’s keypad, 15 digit # IMEI will display on the screen.  If this sequence does not work, pull the back/battery off the phone and the IMEI will be listed on the back of the phone.

All told the total time invested was only about 5 minutes. Seriously, 5 minutes. So why would I want to pay someone for this again?

Bookmark and Share

Tablekit: HTML Table Enhancements

Posted in Code, Programming on December 18th, 2009 by Eric LambBe the first to comment

I’ve been using Jquery a lot lately and have absolutely fallen in love with it; so much so that I’ve pretty much walked away from Prototype and Scriptaculous entirely. Not to take anything away from Prototype but Jquery is just a lot more… well, it’s just more fun to work with. That being said, I wanted to give a shout out to one of the cooler toys Prototype has: TableKit.

TableKit

TableKit

TableKit is a table enhancement JavaScript library written using Prototype provided by Millstream Software. In a nutshell TableKit allows you to easily create sortable, resizable and editable tables. Implementation is extremely simple and, according to Robert Speer, designers don’t have an issue working with it (I haven’t had the pleasure of having a designer work with it yet):

Many times using scripts I find on the Internet turns into kind of a hassle. They are usually unfinished side projects, or are kind of bloated and slow.

TableKit is not one of those scripts, it’s fast & easy to implement. Development time was low, and the designers didn’t complain too much about working with it.

Robert’s right; TableKit is extremely easy to work with. TableKit works by using css class overloading to tell the system how to handle a table. For example:

<table class="sortable resizable editable">

indicates that the table should, obviously, be sortable, resizable and editable. There are all sorts of other options available, which you can read about in the documentation. If you have to use Prototype for a project and you need some jazz TableKit is a good fit.

Bookmark and Share

Why Not Upgrade Perl I Thought

Posted in IT on December 16th, 2009 by Eric LambBe the first to comment

About a month ago I started receiving emails from my server about the installed version of PERL being too old and needing to be upgraded. Since my server uses WHM and cPanel, and thinking that upgrading PERL would have some pretty nasty consequences if something went wrong, I held off until I could familiarize myself with the ins and outs of what this was all about. Now that I’ve done the upgrade I’m not sure it was really so worth the wait and worry.

perl01

The first thing you want to do is backup all your installed CPAN modules. These are basically the library of functionality your system relies on to work. Pretty important stuff in there. It’s a pretty simple command though:

perl -MCPAN -e 'autobundle'

The above will create a “bundle” of all the CPAN modules you have installed to be used after the upgrade. Make a note of the bundle location though; you’ll need it later.

The instructions to do the actual installation were included in the email and is geared specifically towards cPanel servers:

cd /root
wget http://layer1.cpanel.net/perl588installer.tar.gz
tar -zxf perl588installer.tar.gz
cd perl588installer
./install -optimize-memory

This parts pretty simple, but time consuming. The whole process is automated and should take about an hour or three. When you come back you’re going to want to install the autobundle you created earlier. To do that you’ll need this command:

perl -MCPAN -e 'install Bundle::NAME_OF_BUNDLE_YOU_CREATED_EARLER'

This is where things started getting difficult. This process is going to require all sorts of input from you. It’ll, thankfully, give you default options but the install will sit there until you enter something. All told, this process took me about 4 hours; just sitting there watching the process.

Definitely a pain but not upgrading PERL would have been worse. If you have to do it be sure to set aside an afternoon though.

Bookmark and Share

Windows 7 Upgrade Experience

Posted in Brain Dump, IT on December 10th, 2009 by Eric LambBe the first to comment

When I purchased my newest laptop back in July, from Best Buy, it came with a free upgrade to Windows 7 when it came out a few months later. Fast forward to December and I’ve since received the new operating system and have installed it on the laptop. Since a lot of people are going to be going through the same thing I put together some notes about the experience.

Windows 7

Windows 7

Because the promotion was for a version of Windows 7 that was the same flavor as the installed Windows Vista, I was given a 64bit Windows 7 Home Premium copy. Personally, I would have preferred Business or Ultimate but ok, fine Home Premium it is. At least this meant that I wouldn’t have to do a clean install so I could keep all files and programs where they were (still backing up the data of course).

The upgrade package came with 2 discs; the Windows 7 disc and a driver upgrade disc. The instructions said to insert the upgrade disc first and I’ll be prompted to enter disc 2 when required. Doing so started an upgrade program that inspected my system and warned me about deauthorizing my iTunes account which immediately made me feel good about the experience.

All told the install took around 3.5 hours and was like watching water boiling. I did it super late at night but I was still up and every time I would check on it I swear the progress rarely looked like it was making any progress. Still, it is Windows, so I was used to this; just wait and be patient, it’ll finish. And eventually it did.

Upon first booting up there were a couple issues. One was my fault. The others… not so much. Probably the worst offense was that I had no Internet connectivity. I checked both my wired NIC and the wifi and both were working  fine; I could connect to my router through both and I could find my Xbox and PS3 on the network. I just couldn’t get online. I eventually found that this was caused by a conflict between Esets firewall (which I had disabled in Vista) and the native Windows firewall. Uninstalling Eset and reinstalling it solved the issue.

I also had an issue with my local Apache webserver working. After checking the logs it turned out to be a soft link I had created under Vista to link the conf directory (makes editing the files from my working directory that much easier). Creating a new link solved the issue nicely.

The last issue is with the touchpad; and I haven’t really fixed it yet. At first, Windows thought the touchpad was a PS/2 mouse. This wouldn’t be an issue except I like the scrolling functions on the touchpad and the PS/2 drivers don’t support it. This seemed like a cut and dry driver issue except I installed all the latest drivers for my laptop that Gateway offered and it still doesn’t work all that well. Yes, it’s there but not in any real functional way. It’s jerky and hesitant when it works (around 30% of the time). Not enough to get me to downgrade but still a pain.

I’ve never really had an issue with Vista but I was still excited about Windows 7. Even though there were a couple hiccups during the install, and that my touchpad isn’t operating 100%, I’m still really happy with the experience.

Bookmark and Share