Entries tagged “php.”

Try Indexy for an even better drag-and-drop file sharing service

Yesterday, Lifehacker published a neat article on How to Roll Your Own Awesome Drag-and-Drop File Sharing Service. The instructions therein are great, but consider replacing Step 4 (their ZIP file of PHP scripts) with Indexy.

I made Indexy so I could have easily themeable, PHP-based file listings (demo here). Some of its features include:

  • Automatic subdirectory scanning (no file duplication or cron jobs necessary).
  • A default theme optimized for smartphone and tablet viewing.
  • The ability to create new themes using Mustache (a dead-simple templating language) and any combination of HTML, CSS and JavaScript you’d like.
  • A built-in Markdown viewer.
  • Source that’s open and easy to fork on Github.

Indexy was created for my own personal use, so I’m sure there are a ton of ways to improve it. I encourage folks to give it a whirl, make tweaks and contribute back to the source.

View or download Indexy on Github

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!