Entries tagged “php.”

Get all paths in a directory using PHP

I hate recursion. Writing the code equivalent of an M. C. Escher woodcut gives me a headache.

One activity that typically demands recursion is scraping a directory and its subdirectories for file paths. Luckily, I found this example on php.net and managed to improve it a bit for my own needs.

The first (and only required) argument is the server path you’d like to scan. The second argument defaults to true and determines whether directories will be included in the result. The third argument allows you to specify a file extension to filter results against. For example, if you only want to return paths to JavaScript files, the value would be 'js'.

function dir_tree( $dir, $include_dirs=true, $only_ext=null ) {
    $paths = array();
    $stack[] = $dir;
    while ( count( $stack ) ) {
        $this_dir = array_pop( $stack );
        foreach( scandir( $this_dir ) as $file ) {
            if ( $file !== '.' && $file !== '..' ) {
                $path = $this_dir . '/' . $file;
                if ( is_file( $path ) ) {
                    if ( $only_ext && substr( strrchr( $file, '.' ), 1 ) !== $only_ext ) {
                        continue;
                    }
                    $paths[] = $path;
                } elseif ( is_dir( $path ) ) {
                    if ( $include_dirs ) { 
                        $paths[] = $path;
                    }
                    $stack[] = $path;
                }
            }
        }
    }
    return $paths;
}

This function returns an array like this:

array(
    '/my/server/path',
    '/my/server/path/file.txt',
    '/my/server/path/image.jpg',
    '/my/server/path/subdir',
    '/my/server/path/subdir/style.css'
)

If I set $include_dirs to false:

array(
    '/my/server/path/file.txt',
    '/my/server/path/image.jpg',
    '/my/server/path/subdir/style.css'
)

If I set $only_ext to 'css':

array(
    '/my/server/path/subdir/style.css'
)

This is the first deep directory scanning function I’ve found comprehensible, but I’m sure there’s room for improvement. Let me know if you find some useful tweaks.

Generating Flickr Short URLs with JavaScript

As of this past Saturday, users who click a “tweet this” link on an individual photo in Portwiture may notice a few extra characters available. By popular request, the app now takes advantage of Flickr’s URL shortening.

What’s unique about flic.kr URLs is that they are not directly tied to a database or fetch-able via the API, but derived from a photo’s unique ID using a variation of base58 compression. This is actually pretty neat, as it sidesteps the need for an additional database query, resulting in a faster experience for the end user.

The only problem is that you, the developer, have to do the work to generate the darn thing. If you need to create it on the fly using JavaScript (as Portwiture does), you may be disappointed by the relative lack of JS code snippets in the official base58 flic.kr dev discussion.

Fear not! Using their PHP example, translating this functionality to JavaScript is a straightforward process.

The only function used therein with no direct JavaScript equivalent is intval. Luckily, the amazing php.js project has us covered with a translation. Grab that function and include it in your source.

Now we simply rewrite the base_encode function, swapping out strlen for .length, [] for .charAt(), and so on.

function base_encode(num, alphabet) {
    // http://tylersticka.com/
    // Based on the Flickr PHP snippet:
    // http://www.flickr.com/groups/api/discuss/72157616713786392/
    alphabet = alphabet || '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';
    var base_count = alphabet.length;
    var encoded = '';
    while (num >= base_count) {
        var div = num/base_count;
        var mod = (num-(base_count*intval(div)));
        encoded = alphabet.charAt(mod) + encoded;
        num = intval(div);
    }
    if (num) encoded = alphabet.charAt(num) + encoded;
    return encoded;
}

Note that the default alphabet differs slightly from honest-to-goodness base58 encoding, omitting certain characters that are confusing in URLs (0 and O, I and l, etc.).

Assuming you’ve already fetched a Flickr photo ID, generating a short URL is now as simple as this:

var shortURL = 'http://flic.kr/p/' + base_encode(4379822687);
alert(shortURL);
// Should alert 'http://flic.kr/p/7F2JGg'

That’s all there is to it. Reversing the process is a bit trickier (you need to fetch the author’s name), but this Flickr discussion should get you started.

Want a JavaScript file with intval, baseencode, basedecode and a few helper functions ready and raring to go? You’re one lucky son of a gun:

Download flickr-shorturl.js 1.0

How WordPress 3.0 will rock your portfolio

I couldn’t be happier that my WordCamp Portland 2009 presentation, WordPress-Powered Portfolios, will likely have the shortest shelf life of any presentation I’ve given. It’s a testament to the WordPress team (and open source projects in general) that the “hacks” I proposed only months ago have already blossomed into honest-to-goodness features.

In December, WordPress 2.9 introduced support for post thumbnails, eliminating the need for my custom meta hack. WordPress 3.0 (which should be released around May) will solve the problem of secluding portfolio content from your blog with the introduction of custom post types.

Instead of corralling your portfolio content with tools like “category excluders” or relying solely on nested pages (as I suggested), you’ll soon be able to create a custom “portfolio” post type in a supported and predictable fashion.

As Frank Bültge details on the WP Engineer blog, adding a whole new section to your WordPress sidebar will be a straightforward and extremely flexible process you can bake right into your theme. No crazy plugins or hackery required!

This change is exciting not only for the impact it will have on  sites like my own, but because it increases WordPress’ prospects as a hardy CMS solution.

All that’s left to render my presentation completely obsolete is a more robust and customizable gallery solution. I’ll be crossing my fingers.

Ring in the new year with a little PHP

I think this has happened to every web developer at one point or another: You complete and launch a site, revel in it’s glory, January 1st passes you by and suddenly, embarrassingly, the site proudly proclaims the previous year in the footer!

Ack! How’d you miss that? So unprofessional.

Many of you have probably used the following solution to combat this troublesome oversight:

<?php echo date('Y'); ?>

In PHP, this displays the current year. But what if you want to intelligently display a span of time, regardless if your project launched this year or five years ago?

Here’s a fun little function my good friend (and ace developer) Peter Wooley showed me some time ago:

function copyrightYear($start,$between='-',$echo=true) {
    $current = date('Y');
    $result = $current > $start ? $start.$between.$current : $start;
    if ($echo) echo $result;
    return $result;
}

The first attribute ($start) is the launch date of your site, the first year of the date span. $between is what goes between the start and end year (when applicable). If you set $echo to false, the value will be returned instead of echoed.

So if your site debuted in 2009, you would use the following:

<?php copyrightYear(2009); ?>

If the year is 2009, it will echo ’2009′. In 2010, it will echo ’2009-2010′.

Now sit back and rest easy next New Year’s Day knowing your footers shan’t go out of date again!

Implement 2.9′s thumbnail feature in your WordPress-Powered Portfolio

WordPress 2.9 was unleashed upon the world last evening with a pile of killer features (image editing, anyone?).  Perhaps my favorite new feature is built-in support for thumbnails associated with a page or post.

When I discussed building WordPress-Powered Portfolios earlier this year at WordCamp Portland, you may recall my rather obtuse solution for supporting thumbnails. Basically, you were required to upload an image, copy its filename, close the media browser, create a new custom field called “tn,” and paste the filename into it.

No longer!

With support in your theme for 2.9′s post thumbnails, simply upload an image and assign it as the thumbnail with a single click (or through the handy new “Page Image” box in the lower-right corner). No custom fields to mess with, no copying and pasting filenames.

Implementing this feature in a portfolio already using my WordCamp functions is a three-step process.

  1. Tell WordPress that the feature is supported by adding addthemesupport('post-thumbnails'); somewhere in your theme’s functions.php file.
  2. Log in to WordPress and assign each of your portfolio items an image. If you’ve already used the “Upload/Insert” tool to add them prior to 2.9, just click the “Add an Image” button, then “Gallery,” “Show” the image you want to use and click the “Use as thumbnail” link toward the bottom.
  3. Adjust your functions to support the new feature. Refer to my updated list_work function snippet as an example.
Your mileage may vary depending on the volume of portfolio items you’ll need to switch over, but it took me roughly an hour to support the feature on this very site.

I recommend reading Justin Tadlock’s excellent blog post on the subject, which details the post thumbnails in much greater detail than WordPress’ documentation and was of great help to me in supporting them.

I do have one bit of extra theme development knowledge to bestow on other developers which I was unable to find elsewhere online. To echo only the URL of the thumbnail image file, use the following:

<?php echo get_post(get_post_thumbnail_id())->guid; ?>