Author Archives: Paul Kehrer - Page 9

WordPress 2.9 Upgrade

WP 2.9 is out. The upgrade went quite smoothly here, but be sure you upgrade your plugins before running the core upgrade! Fidgetr and CDN Tools are both 2.9 compatible already, so if you have the latest versions you’re set.

Comcast Chicago Clear QAM Cable Channels

For those who may wonder, as of the date of this posting here are the digital channel mappings for the various high definition channels Comcast (Chicago, north side) offers over clear QAM. These channels will be available if you directly connect a coaxial cable to an HDTV with a clear QAM tuner. Most TVs with ATSC (aka over the air/antenna tuners) also support clear QAM.

Channel Name Reported As
2.1 CBS CBS2
5.1 NBC NBC5-DT
7.1 ABC WLS-HD
9.1 WGN WGN-DT
11.3 PBS WTTW-HD
20.1 Wise TV WYCC-HD
26.1 The U WCIU-HD
32.1 Fox WFLD-DT
38.1 ION ION
50.1 my50 (MyNetworkTV) WPWR-DT
93.36 Hallmark Movies Nothing

There are many, many more SD digital channels available as well, but this list is intended to index only HD stations. Let me know if I’ve missed any or if the logical mappings change.

Writing Compatible PHP For WordPress

One of the big problems I’ve run into as a WordPress plugin developer is the diversity of PHP installations. Simply stating you only support PHP5 and greater is insufficient to ensure compatibility. Things you may take for granted in your development environment may be missing or worse, partially functional. I’ve decided to document a few of the bigger “gotchas” I’ve run into so future WordPress hackers will have a starting point for investigating problems.

Minimum PHP Version

One easy way to reduce compatibility confusion is specifying a minimum version of PHP for your WordPress plugin or widget. To do so you can use PHP’s version_compare function:

if(version_compare(PHP_VERSION, '5.0.0','<')) {
	die(sprintf('You are currently running PHP version %s and you must have at least PHP 5.0.x', PHP_VERSION));
}

Take a look at the version_compare documentation for more information.

PHP Modules

The biggest single thing to remember is that any module for PHP is optional. If you want to require something like curl, that’s great, but be aware that some non-trivial percentage of your potential users may not have it. Still want to use that module? Test for its presence during the instantiation of your plugin and die if it’s not present. This will prevent users from being able to successfully install your “broken” product if they don’t have the proper requirements.

Sometimes you’ll find yourself using functions you think are core to PHP like “mime_content_type”. This is not the case. In fact, I have frequently run into PHP installations that have no MIME detection facilities at all. Consider writing a fallback for suffix detection1 in addition to coding for mime_content_type and the finfo_* methods.

Safe Mode and Related Problems

Another common issue is safe_mode and open_basedir. These flags enforce certain security restrictions (must have the same group as PHP when writing to a directory, can’t open files beneath the basedir, et cetera). However, they also impact some modules. For instance, using curl you can’t use CURLOPT_FOLLOWLOCATION. This will trigger the error “CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set”.

Network Communication

I’ve already talked a bit about the curl module, but you may also be tempted to use file_get_contents() assuming allow_url_fopen is enabled. This is very frequently untrue in shared hosting environments. Luckily, you don’t need to rely on curl or allow_url_fopen or write your own fsockopen() wrapper class. Instead, WordPress has integrated Snoopy into the core. Invoking it to fetch just the contents of a URL could not be easier!

require_once( ABSPATH . 'wp-includes/class-snoopy.php');
$snoopy = new Snoopy();
$result = $snoopy->fetch($url);
if($result) {
	$response = $snoopy->results;
}

Just hit up Google for the class docs to learn everything Snoopy can do for you.

There are many more where these came from, so drop your problems and solutions in the comments!

  1. This can be a security risk in certain circumstances, so be careful.

Building Services Using Automator Workflows in Snow Leopard (10.6)

In Snow Leopard (Mac OS X 10.6) the Automator tool has been drastically upgraded to support the creation of service workflows. In simple terms, this means you can build automated chains of tasks that can be invoked in a context sensitive manner. Not simple enough? Using this tool, you can automate common actions you perform and the proper service will appear in the menu only when it is capable of being used. You can even assign global hotkeys (via the Keyboard preference pane) to your service. Let’s take a look at a simple service workflow so you can see how it’s done.

Open Automator (it’s located in your /Applications folder). You will be greeted by a sheet requesting a template for your workflow. Choose service.

choose_your_template

You’ll now be greeted by the main Automator window. On the left you’ll see a Library and actions you can perform. On the right you’ll see an empty pane where you drag actions or files to build your workflow. Third party applications you have installed can expose additional available actions, so the list of available actions will vary for each user’s computer.

main_window

As an example, we’re going to build a service that allows you to select files in the Finder, automatically zip them, and attach them to a new email. To begin, change the drop down in the upper right from “text” to “files or folders” and change “any application” to “Finder”. This means that the service we’re constructing will accept files or folders from the Finder as input. Next we need to add our first action. To accomplish this type “create” in the search field in the upper left of the actions pane. This will live filter the available actions so you can more easily locate the “Create Archive” action. Once you’ve found it, drag and drop it to the right hand side.

After creating the zip archive we want to attach it to a mail message. Search for “new mail message” and drag and drop it below the first action. It will prompt you with a few dialogs (mostly for permissions to access your keychain), but when you’re done you should have the workflow below.

prelim_workflow

To test you can click Run, but you’ll receive a warning that states “This service will not receive input when run inside Automator. To test this service within Automator, add the “Get Specified Finder Items” action to the beginning of your workflow. Remove or disable the action before running the workflow outside of Automator.”. Hit cancel (there’s no point to running our service without input!) and add the “Get Specified Finder Items” action to the very top of your workflow. You’ll also need to add an item or two for testing.

get_specified

To test the entire service, click Run in the upper right! You should see it create a zip file in the same directory as whatever files you specified, then open a new Mail message with your zip file attached.

If everything is working you can remove or disable the “Get Specified Finder Items” action and save your new service. Whatever you name it will be how it appears in your Services menu, so try to give it a descriptive name (something like “Create Zip and Email”). Now head to the Finder, select a file or folder, and click the Finder menu to see the Services submenu.

services_menu

Success!

But what if you don’t want to use that submenu? OS X allows you to assign global shortcuts/hotkeys to any Service using the Keyboard preference pane in System Preferences. Go to Keyboard Shortcuts within it, click the services option on the left, then find your “Create Zip and Email” option on the right. To add a shortcut you’ll need to double click on the righthand side of the Create Zip and Email row. Once the text box appears, press the key combination you want to use to invoke this service. Try to choose one that won’t conflict with anything.

keyboard_assigned

Automator has a great deal of power, so try experimenting with various actions to build your own ideal workflow. For example, I frequently parse SSL certificates in the course of my day, so I built this workflow to do it quickly and display the results in a text document in my editor of choice:

parse_cert

I also wanted a universal key combo to start the screensaver (which requires a password) so I could lock my computer quickly without using the mouse.

start_screensaver

If you’ve got other service ideas or want to show off one of you’ve written drop a comment! It’s always great to discover a better/more efficient way to accomplish a task.

Bypass Hulu Regional Restrictions in Mac OS X

Hulu is a great site to find new shows and catch up on old, but due to various contracts no one outside the US can use it. This irritated some friends of mine from Canada, England, Germany, et cetera. So I decided to write up one (very reliable) way to circumvent the Hulu geolocation checks — using a VPN.1

Accessing Hulu Outside The US

In this case, we’ll be using a small VM and the open source VPN server pptpd. All the server side instructions below are applicable to both OS X and Windows, but the client setup is only specified for Mac OS X.

Server Setup

First, obtain a VM from a reputable (and fast) US vendor. The VM must be located in the US since that’s our required origin. I personally use Slicehost, but there are many others. Once you get your login be sure you change the root password.

Install pptpd. If you’re running on Ubuntu or Debian you can simply run

apt-get install pptpd

Once you have pptpd installed, we’ll need to add a user. The default pptpd configuration is fine, but we’ll need to edit /etc/ppp/chap-secrets. When you edit the file (using vi, nano, emacs, et cetera) you’ll see this:

# Secrets for authentication using CHAP
# client        server  secret                  IP addresses

Client is your username, server is “pptpd”, secret is your password in plaintext, and IP addresses is a range of allowed IPs. If you’re unconcerned about who might attempt to access your VPN, you can simply use a wildcard (*). Once you’ve populated this file with data it will look something like this:

# Secrets for authentication using CHAP
# client	server	secret			IP addresses
testuser	pptpd	mypassword		*

We need to set up IPv4 forwarding, so edit /etc/sysctl.conf and uncomment the line below from the file (remove the #).

#net.ipv4.ip_forward=1

This will enable the behavior after a reboot, but you can enable it right now by running:

echo 1 > /proc/sys/net/ipv4/ip_forward

Now run these commands:

/sbin/iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
/sbin/iptables -A FORWARD -i eth0 -o ppp0 -m state --state RELATED,ESTABLISHED -j ACCEPT
/sbin/iptables -A FORWARD -i ppp0 -o eth0 -j ACCEPT

Once you’ve run these you can save them so they execute every time your VM boots by following these quick instructions. This completes the server side setup.

Client Setup

Now it’s time to configure the Mac to utilize the VPN server. Bear in mind that all traffic to the internet will be routed through your VPN server when this is active, so you’ll only want to connect to your VPN when watching Hulu.2

Open System Preferences and go to Network.  Click the plus sign in the lower left and choose add to add a VPN PPTP interface.  Then set the server address (the IP of your VM) and account name (“testuser” from above).
network_screen

After filling out those fields, click authentication settings and type your password, then click Okay.

advanced

Finally, click advanced, then click DNS and click the plus sign.  Add 4.2.2.1 as a DNS server.3

dns_fix

Save these changes and then you can click connect to test it out. Your traffic should all be routed through the VPN and since the endpoint is located in the US Hulu should work just fine!

  1. There are many other ways, including just proxying Hulu traffic from the browser and Flash plugin, but I’m not going to cover those methods.
  2. This can be alleviated by using a split tunnel if you want to go to the trouble.
  3. Our PPTP server doesn’t announce its own DNS by default.

Fixing GrowlMail for Mail 4.2

Update 3: Fix for 10.6.7 and Mail 4.5
Update 2: Fix for 10.6.5 and Mail 4.4
Update: Fix for 10.6.4 and Mail 4.3

Lately Apple has been revving the version number (and plugin compatibility UUID) of Mail.app with every version of 10.6. This breaks bundles like GrowlMail even when they are still compatible. The easy fix (although not necessarily the best if it turns out an update is required!) is to run a few commands in Terminal to add the new UUIDs1 to the SupportedPluginCompatibilityUUID key in the Info.plist.2

If you have already had your plugins disabled by opening Mail.app you’ll need to look in ~/Library/Mail (or /Library/Mail if you installed globally) and move the files back to the active bundles directory. They’ll typically be in Bundles (Disabled), so quit Mail, find them, and move them back into the proper directory.

Once you’ve gotten the files moved into the proper location use either the local installation or global installation commands below (depending on where you found your bundles). To run them, simply copy/paste them into a Terminal window.3

For GrowlMail (assuming local installation)

defaults write ~/Library/Mail/Bundles/GrowlMail.mailbundle/Contents/Info SupportedPluginCompatibilityUUIDs -array-add "2F0CF6F9-35BA-4812-9CB2-155C0FDB9B0F"
defaults write ~/Library/Mail/Bundles/GrowlMail.mailbundle/Contents/Info SupportedPluginCompatibilityUUIDs -array-add "0CB5F2A0-A173-4809-86E3-9317261F1745"

For GrowlMail (global installation)

defaults write /Library/Mail/Bundles/GrowlMail.mailbundle/Contents/Info SupportedPluginCompatibilityUUIDs -array-add "2F0CF6F9-35BA-4812-9CB2-155C0FDB9B0F"
defaults write /Library/Mail/Bundles/GrowlMail.mailbundle/Contents/Info SupportedPluginCompatibilityUUIDs -array-add "0CB5F2A0-A173-4809-86E3-9317261F1745"

Update: Letterbox has been updated, but the above instructions can be adapted for any future OS update that breaks compatibility.

Update 2: You can download a pre-patched copy if you don’t want to follow the above instructions. Just unzip it and drop it in your bundles directory.

Update 3: GrowlMail 1.2.1 has been released, which fixes 10.6.2 compatibility. This issue will likely occur again with 10.6.3 though!

  1. 2F0CF6F9-35BA-4812-9CB2-155C0FDB9B0F for Mail.app v4.2 and 0CB5F2A0-A173-4809-86E3-9317261F1745 for the Message framework. These were released with OS X 10.6.2.
  2. These UUIDs can be found in /Applications/Mail.app/Contents/Info.plist and /System/Library/Frameworks/Message.framework/Resources/Info.plist for when they inevitably change again.
  3. Terminal is found in /Applications/Utilities if you’ve never used it before. You’ll see a prompt and you can paste the commands in and hit enter.