Phillip Pearson - web + electronics notes

tech notes and web hackery from a new zealander who was vaguely useful on the web back in 2002 (see: python community server, the blogging ecosystem, the new zealand coffee review, the internet topic exchange).

2008-12-9

Strictly matching URLs with regular expressions in preload FQL, and migration tricks for PHP Facebook apps

Preload FQL is a nice little Facebook app feature that lets you specify a bunch of regular expressions and FQL queries to Facebook, and have it send you the results of those queries each time it makes an HTTP POST request to your site to fetch an FBML page.

For example, if you've got a page, http://apps.new.facebook.com/myapp/something, that always needs to know the names and IDs of all the current user's friends, you could specify preload FQL like this:

  {
    'names_and_ids': {
      "pattern": "\/something$",
      "query": "SELECT uid, name FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1={*user*})"
    }
  }

If you're using PHP, the results of the query will then be accessible with json_decode($facebook->fb_params['names_and_ids']) (where $facebook is your Facebook object, from the PHP platform library).

One interesting thing (and the whole point of this post) is how the pattern parameters are interpreted. It looks like they're going to PHP's preg_match like this:

  preg_match("/$pattern/", $full_url)

This means you have to escape all slashes or they'll prematurely terminate the pattern. Also, the pattern matches the whole URL, including http://apps.new.facebook.com/appname/, so if you want to be strict with your regexes and ensure they don't accidentally match pages with the same suffix, you want to do something like this:

  $root = "http\:\/\/[^\/]+\/[^\/]+"; // regex to match "http://apps.whatever.facebook.com/app_name"

... then specify patterns like "^$root\/mypage$".

Unrelated but probably useful if you're using preload FQL is a trick for feeding the data to Facebook in your migration script. Set up your preload FQL like this and find the MD5 hash of it in serialized form:

  $preload_fql = array(
    "first_fql" => array("pattern" => ..., "query" => ...),
    ...);
    $current_hash = md5(serialize($preload_fql));

After setting your preload FQL with Admin.setAppProperties, save the hash somewhere, then the next time you run your migration script, compare the computed with the stored hash, and if they differ, you know you need to update the FQL on Facebook.

You can do a very similar trick with template bundles: hash each one and map the hashes with Facebook IDs in your database, then in the migration script, register template bundles whose hashes aren't in the database and delete template bundles which are in the database but are no longer known to the migration script.

... more like this: []