Dougal Campbell's geek ramblings

WordPress, web development, and world domination.

An Air Miles Experiment

Several years ago I went on a work-related trip on American Airlines (side note: holy cow! they have RSS feeds!). I don’t travel much, but on a whim, I signed up for their AAdvantage program. I got some quantity of bonus miles for signing up. Enough to keep me interested, but not enough to really do anything with. Then I signed up for some partnership deal that they had with MCI where I earned miles based on my long-distance usage. That got me a chunk of bonus miles, plus a trickle of miles over time (until MCI imploded). Since then, I’ve added miles here and there by supplying my membership ID when I stayed at a hotel, or bought my wife flowers through FTD. All this has added up to not-quite-enough miles to get two round trip tickets to somewhere (continental US, mainly).

So, I’ve got these miles sitting around that I’m not likely to use unless I can add enough more to get a second ticket, so that maybe Susan and I can take our long-overdue honeymoon. And thus is born my Air Miles Experiment. I figure there must be lots of other people out there who travel at least occassionally, but who don’t actively participate in some sort of air miles program. Or people who purchase various things on the net from time to time. If you are one of those people, I’d like to enlist you.

What do you have to do? Just use my AAdvantage number (391H8E0) if you have an opportunity. Staying at a hotel for the weekend? Ask at the front desk if they participate in the American Airlines AAdvantage program. Other participating businesses include Barnes & Noble, Best Buy, Circuit City, Sharper Image, iTunes, Shutterfly, LEGO Shop at Home, Target, Land’s End, and Old Navy (among many others). There’s a full list at the AAdvantage eShopping Mall.

What do you get out of this? Well, nothing — except the joy of giving. Maybe this could be a cheap (free!) way for you to reward me for some software I’ve written, or knowledge that you found on this blog. Maybe it’s just a way for you to “stick it to the man” by getting an airline to give up something for nothing. Maybe you need to atone for that time that you snuck forbidden liquids onto a flight. Maybe you’re just sick and tired of all those mofo snakes on that mofo plane!

So there it is: my plea for something free. The next time you’re getting ready to buy something online, maybe you’ll remember to check the list of merchants. And if you’re buying from a participating vendor, punch in AAdvantage number 391H8E0.

And can I ask one more favor? Even if you aren’t going to do this yourself, if you think this experiment is interesting, spread the word with a link back to this post. If I start to see any significant participation, I’ll update here with some details.

Using the WordPress Object Cache

I’ve been planning to write up a plugin to serve as an example of using the WordPress Object Cache, but haven’t had time to finish it up. However, this topic came up on the wp-hackers mailing list recently, so I thought that I would go ahead and give a brief rundown on how to use the cache from within your own plugins.

The goal of the WordPress Object Cache is to provide a way to persistently store results from expensive queries in an external cache file. This lets us avoid re-querying the database or re-fetching information from an external web service if we think that the data hasn’t changed. It should be noted, however, that some server environments have trouble using the cache. It is up to you to monitor your server to determine whether use of the cache will benefit your sites,

Using the object cache is actually quite simple. You write data to the cache using wp_cache_set(), and you read cached data with wp_cache_get().

Before I get to the sample code, there are some other things you’ll need to check. The object cache is disabled by default. In order to enable it, you’ll need to edit your wp-config.php file. Add the following lines, after the setting for WP_LANG:


// Enable the WordPress Object Cache:
define(ENABLE_CACHE, true);

Also, make sure that there is not a define for a DISABLE_CACHE constant. In addition, you will need to make sure that you have a wp-content/cache subdirectory on your host, and that it is writable by your web server process. I assume that if you are planning to write code to use the object cache, that you know how to handle this on your host server.

That said, let’s take a look at how you use the wp_cache_get() and wp_cache_set() functions in your own code. First, we’ll examine how we put data into the cache. Think of the cache as a set of containers, each of which can store several data packets. You can name the containers and the packets within, so that you know how to retrieve them later. In these examples, I am naming the container mycache, and we’ll call the data packet mysettings. It would probably be a good convention to name your own container based on the name of your plugin, and name the packets based on what kind of information you are storing (e.g. userdata or popularpostinfo).

Here’s how we write data to the cache:


  // Whenever we need to rewrite the cache data:
  // This could be calling a database, webservice, etc.
  $mydata = my_complicated_data_query(); 
  $myexpire = 60 * 60 * 24; // Cache data for one day (86400 seconds)
  wp_cache_set('mysettings', $mydata, 'mycache', $myexpire);

You’ll have to determine the best point in your code to do this depending on what kind of data you’re caching. For example, if you are caching user profile data, you might want to update the cache anytime a user’s profile changes by hooking into the profile_update() API hook.

Now, when you want to avoid that complicated database query, check the cache first. If your information is not already in the cache, or if it has expired, wp_cache_get() will return false. In that case, you’ll need to re-query the database for the information. Otherwise, it will return whatever data structure that you previously stored.


  // First of all, before you try to access the user data, check
  // the cache.
  $mydata = wp_cache_get('mysettings', 'mycache');

  if (false === $mydata) {
    // The cache data doesn't exist or it's expired. 
    // Do whatever we need to populate $mydata from the
    // database normally... 
    
    $mydata = my_complicated_data_query();

    // Since we know that the cache isn't up to date, we should
    // write this fresh information to it now, so that we can avoid
    // the query next time.
    $myexpire = 60 * 60 * 24; // Cache data for one day (86400 seconds)
    wp_cache_set('mysettings', $mydata, 'mycache', $myexpire);
  }

It’s up to you to decide an appropriate amount of time to cache your data and to determine which API action hooks should trigger cache updates. A whole day will be too long for some types of information. But with this basic information in hand, it should be relatively easy for plugin authors to take advantage of the object cache.

ViaList

A couple of years ago, when we moved to the Atlanta area, I was working as a contractor doing some web programming on a project that I couldn’t say much about, because I had signed an NDA. But now I can talk, because the product is officially released (actually, I suppose I could have talked about it back when it was in beta). That product is ViaList.

ViaList is software that helps your club, group, committee, or family stay organized and up-to-date. It lets you share any kind of list — things to do, contact information, agendas, ideas, whatever you need — as easily as sending an e-mail.

A program that helps you make and share lists may not sound like a big deal, but when you actually use the software and see how intuitive it is, you could very well end up adding it to your list of favorite tools. I often see new utilities come onto the scene for the Mac and think, “I wish there was something like that for Windows.” This is one of those rare programs that turns the tables, and could have Mac users wishing they had ViaList (there are plans to make a Mac client, eventually).

A lot of what I worked on was on the system administration side, configuring the server for email, setting up the bug tracker, creating a “single sign-on” system, etc. But I also worked on a very early proof-of-concept for the web-based list interface. Oh, and with me being a WordPress dev, the site ended up using WP for its blog.

Susan and I have used it to maintain lists of projects around the house, shopping lists, and planning tasks for web sites that we’ve worked on together. This kind of asynchronous planning is very convenient. Anyhow, if you have a need to keep various kinds of lists (to-do, dated events, priorities, shopping, etc.), and especially if you need to coordinate the lists with other people, you should take a look at ViaList.

Knock, knock…

I know, I know… I haven’t been very active on the blogging front lately. Once again I’ve been sucked into a swirling vortex of job and home projects, with little-to-no time for participating in blogdom. I’ve managed to keep up with most of the latest memes, and I’ve added a few new del.icio.us bookmarks, but there’s been no opportunity to develop any nifty code or write about the subject of the day.

I’ve got eight draft posts in my queue, and three of those are no longer timely, and so I’ll probably end up deleting them. Of the remaining five, one is about how to use the WordPress object cache in plugins, another is about separation of presentation from business logic in HTML::Mason (a mod_perl web framework), one is an explanation of what blog ping services are, and the last two are non-technical. The ping service post is the only one that I’ve actually written any content for, and I started writing that one nearly a year ago. The others are basically nothing more than links to articles I was going to comment on, or placeholders to remind me that I wanted to write something about the subject.

Most of my time lately has been tied up with my day job. We’ve had some big projects on tight deadlines, and we developers had to really push to get things done on schedule. I’ve had to work late at the the office several times in the past few weeks, and that throws off our schedule for getting home projects done.

At home, we’ve been trying to finish building the rest of our bedroom funiture (we’ve almost finished the final piece, a wardrobe). And we still need to finish stripping and repainting the dressers for the girls’ room. We’re also trying to get things cleaned up in general, in preparation for out-of-town family visitors for Independence Day weekend. We’re going to have a very crowded house, with lots of kids to wrangle. If you don’t hear from me again after July 4th, it might mean that we didn’t survive.

And I’m not the only one who’s busy. Susan has her hands full keeping up with Jamie’s summer program, therapies, and doctor visits, Mary’s activities, and taking care of baby Claire, along with everything else. And when she can grab a spare minute on her computer, she’s been working on the website for her 20th class reunion.

So, for the three of you who were just about to delete me from your list of sites to visit, don’t abandon me yet! I should be posting more articles soon-ish. In the meantime, why don’t you take a break and enjoy the sounds of summer?

WordPress 2.0.3 Tuneup Plugin

A couple of buglets snuck by in the WordPress 2.0.3 release. There should be a version 2.0.4 release relatively soon. But in the meantime, check out the WordPress 2.0.3 Tuneup Plugin, by Mark Jaquith. It fixes a few of the more obvious/annoying problems (mainly errant “Are You Sure?” dialogs when performing certain admin actions).

More advanced users can also use SVN to track the 2.0 branch like so: svn co http://svn.automattic.com/wordpress/branches/2.0/

WordPress 2.0.3 Released

The wee hours of the morning saw the release of WordPress 2.0.3. This release fixes a few bugs that have been identified in the past three months, and it also adds some security enhancements.

If you would like a smaller upgrade package, Mark Jaquith has a zip file that contains just the changed files. It’s unofficial, but I’d trust Mark.

Also, if you don’t regularly check your WordPress Dashboard to see when new releases are available, you can also check the project status on Freshmeat.net. Freshmeat lets you subscribe to email notifications on projects, rate projects, etc.

A Software Development Analogy

Alice takes her car to a repair shop on Monday. She walks inside and talks to Bob, the customer service representative behind the counter. “My car seems to work pretty well, but occassionally it makes an odd noise. When can you have it fixed, and how much will it cost?”

Bob smiles and replies, “we can have your car ready by noon on Friday, and it will cost $200.” Alice says that this is acceptable, and leaves her car to be worked on.

On Wednesday afternoon, Bob talks to Charlie, the mechanic. “How are you progressing on Miss Alice’s repairs?” Charlie gives Bob a blank look.

“I gave it a quick look yesterday, but I haven’t even started working on her car. I’m still finishing up the work on Mr. Durham’s truck.”

“Haven’t started? We have to get her car working by Friday at noon!” Bob exclaims.

Charlie narrows his eyes and shrugs. “That’s not going to happen. I had to order some parts, and they won’t even be here until tomorrow.”

Bob gives Charlie a pained look and sputters, “surely you realize that Miss Alice is an important customer? She works for a company that has a fleet of leased cars, and they get all their servicing from us. If we don’t have her car ready on time, we could lose that contract!”

Charlie looks back and Bob and replies, “Maybe you should have thought of that earlier. And maybe you should have asked me what my repair schedule looked like before you gave her an ETA on her repairs. Better yet, you probably should have asked Dave, since he’s the shop manager. But, no — you ignored our normal workflow, and now I’m going to have to work overtime because of your mistake. And when this lady gets her car back, if everything works fine, she’ll send you a nice thank you note, and the shop owner will congratulate you. But if I make a mistake in my hurry to meet your unreasonable deadline, you’ll blame me, and the shop owner might fire me. Is that basically right?”

“Yup.”

“I guess I’d better get to work, then.”

The prodigal son returns

On Friday afternoon, I called home as I was leaving the office, as usual. Before I had a chance to say much more than “hello,” Susan said, “guess what?” Not knowing whether it was something good or bad, I asked, “what?” She replied, “the prodigal son has returned.”

A neighbor down the street from us had found our dog! This nice young lady had first spotted Spirit wandering around on Thursday, and thought that he didn’t look like he should be wandering around on his own. Friday afternoon, she spotted him again, and called to him. When he came to her, she got hold of his collar and called the phone number on it. Susan met her halfway and retrieved our wayward pooch. This young lady doesn’t know it yet, but we’re going to be giving her a gift certificate in thanks.

We helped the kids bathe him later that night, and he seems happy to be home. Of course he’s lost his winging-it privileges — no more trips outdoors without a leash!

Not a good day

Today, so far, has not been a good day.

Maybe it was an omen when our dog ran away this morning… I opened our front door to let him go out for his “morning consititutional”, but he spotted a rabbit in the yard across the street, and he bolted after it. I chased after him, and came close to getting him to come back, but then he ran off again. We haven’t seen him since. All we can do right now is hope that he either gets hungry and finds his way back home, or that someone friendly will call the phone number on his collar and dog tags.

At work, we were preparing to preview a new web design and process flow for a big customer of ours. I’ve been working on this project for several weeks, including some weekends and evenings. The whole thing has been plagued from the beginning with vague/incomplete project specifications and on-the-fly last-minute changes. But we had managed to get the major features implemented as desired to the point that we were going to dog-and-pony the new site this morning, to be followed by production deployment. Unfortunately, a miscommunication about the timeline for a critical piece of the deployment has caused a snafu in their current production site, which we are still trying to repair.

Bad things often seem to happen in threes. So I’m now wondering what the third bad thing will be.

Is it Friday yet?